Tie-TransactHash
view release on metacpan or search on metacpan
lib/Tie/TransactHash.pm view on Meta::CPAN
package Tie::TransactHash;
$Tie::TransactHash::VERSION = '0.03'; #BETA; not heavily tested.
use strict;
use Carp;
require Tie::IxHash;
require 5.002; #I think older versions don't have proper working tie.
# please note; perl 5.003 to something below 5.003_25 (that's a
# developers version before perl 5.004) has a bug which causes loss of
# data during the destructor calls at the end opf the program
#TransactHash - a perl module to allow editing of hashes in transactions
#maintaining the sequence of the hash through the transaction.
#Copyright (c) 1997 Michael De La Rue
#This is free software and may be distributed under the same terms
#as perl. There is no warantee. See the file COPYING which should
#have been included with the distribution for one set of terms under
#which it may be distributed.
=head1 NAME
Tie::TransactHash - Edit hash in transactions not changing order during trans.
=head1 SYNOPSIS
use Tie::TransactHash;
$::edit_db = tie %::edit_me, TransactHash, \%::db_as_hash, $::db;
while (($key, $value)=each %edit_me)) {
$::edit_me{$key} ++ if $key =~ m/counters/ ;
}
=head1 DESCRIPTION
Tie::TransactHash is a package which provides facilities for editing
any other hash in transactions. A transaction is a group of changes
which go together and are either all applied or none. When working on
a standard perl hash or a hash indexed DBM file, one advantage is that
the original hash remains untouched during the transaction, so its
order (the order the each(), keys() or values functions give out) is
maintained - changes can be made to the transact hash whilst iterating
over it.
=head1 OVERVIEW
Editing a hash causes problems because it rearranges the hash. If the
editing is to be done in sequence then this makes life difficult. The
TransactHash class uses a fixed sequence hash class which overlays the
normal hash and allows editing in place. It stores all of the changes
to the original hash in memory until it is told to apply them.
As a side effect of this design, the class also provides a
commit/rollback system. When a commit is called, the order of the
hidden hash will be changed.
A commit will normally be done as the TransactHash object is being
destroyed. This could be undesirable if your program exits when it
discovers a failure. You can change the.
If you can accept the re-ordering, then you can do partial
edits and commit half way through.
When working on a DBM file, if a crash occurs during the editing and
no commit has been called then the original hash will be left intact.
If however the crash occurs during the commit, bad things could
happen.
use DB_File;
use Tie::TransactHash;
use Fcntl;
$::db = tie %::db_as_hash, DB_File, $::dbname, O_RDWR|O_CREAT, 0640, $db_type
or die $!;
$::edit_db = tie %::edit_me, TransactHash, \%::db_as_hash, $::db;
#the $::db doesn't really do any good right now, but in future it might
my $count = 0;
my ($key,$value)
while(($key,$_)=each %edit_me) {
s/bouncy/bouncy, very very bouncy./;
m/Fred/ && do {
$count++;
$edit_me{ Fred . $count } = $key;
}
}
print "Found Fred in the values $count times\n";
Generally, this package should be used if you want to occasionally do
small numbers of changes across the values of a large hash. If you
are using it overly (often or for large numbers of changes on the
database), then you should probably switch to btree indexed hashes
(Berkley DBM) which give you the same ordering effect but don't use a
large chunk of memory. Alternately you could consider some kind of
multi-pass algorithm (scan through the database putting planned
changes to a file then apply them afterwards all in one go).
=head1 METHODS
=cut
$TransactHash::autostore = 1; #we automatically commit at destructor time.
#$TransactHash::verbose= 0xfff; #
$TransactHash::verbose= 0; #turn this up for debugging messages
sub version { return $Tie::TransactHash::VERSION };
=head2 new( \%hidehash [,$hideobj] )
( run in 0.756 second using v1.01-cache-2.11-cpan-39bf76dae61 )