From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Fri, 27 Apr 2007 14:20:34 +0400 From: Alexey Tourbin To: devel@lists.altlinux.org Message-ID: <20070427102034.GB11839@solemn.turbinal> Mail-Followup-To: devel@lists.altlinux.org References: <200704271505.10158.asy@altlinux.ru> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="7DO5AaGCk89r4vaK" Content-Disposition: inline In-Reply-To: <200704271505.10158.asy@altlinux.ru> Subject: Re: [devel] =?koi8-r?b?18/Q0s/TINDSzyBCREIgySDCzM/LydLP18vJLg==?= X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.9rc1 Precedence: list Reply-To: ALT Devel discussion list List-Id: ALT Devel discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Apr 2007 10:21:39 -0000 Archived-At: List-Archive: List-Post: --7DO5AaGCk89r4vaK Content-Type: multipart/mixed; boundary="bAmEntskrkuBymla" Content-Disposition: inline --bAmEntskrkuBymla Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Apr 27, 2007 at 03:05:09PM +0500, Sergey Y. Afonin wrote: > =E8=CF=DE=C5=D4=D3=D1, =D7 =C4=C1=CE=CE=CF=CA =D3=C9=D4=C1=C3=C9=C9, "=C4= =CF=C2=C9=D4=D8" =D0=D2=CF=C2=CC=C5=CD=D5 =D3 mailfromd. =F7 =C4=CF=CB=D5= =CD=C5=CE=D4=C1=C3=C9=C9 > http://www.oracle.com/technology/documentation/berkeley-db/db/ref/lock/in= tro.html > =D5=D4=D7=C5=D2=D6=C4=C1=C5=D4=D3=D1, =DE=D4=CF The Lock subsystem is cre= ated, initialized, and opened by=20 > calls to DB_ENV->open with the DB_INIT_LOCK or DB_INIT_CDB flags specifie= d. > =F4=CF =C5=D3=D4=D8, =DE=D4=CF =D7=D3=D4=D2=CF=C5=CE=CE=D9=C5 =C2=CC=CF= =CB=C9=D2=CF=D7=CB=C9 =D7 BDB =CE=C1=DE=C9=CE=C1=C0=D4 =D2=C1=C2=CF=D4=C1= =D4=D8 =D4=CF=CC=D8=CB=CF =D7 =D3=CC=D5=DE=C1=C5 > =C9=D3=D0=CF=CC=D8=DA=CF=D7=C1=CE=C9=D1 =C6=CC=C1=C7=CF=D7 DB_INIT_LOCK = =C9=CC=C9 DB_INIT_CDB. =F0=CF =CE=C5=CB=CF=D4=CF=D2=CF=CA =D0=D2=C9=DE=C9= =CE=C5 (=D7=20 DB_INIT_CDB =C4=C1=C5=D4 "=D0=D2=CF=DA=D2=C1=DE=CE=D9=CA" =CC=CF=CB=C9=CE= =C7 =C4=CC=D1 =CB=C1=D6=C4=CF=CA =CF=D0=C5=D2=C1=C3=C9=C9.=20 =F4=CF =C5=D3=D4=CF =CF=D0=C5=D2=C1=C3=C9=D1 =CE=C1=DE=C9=CE=C1=C5=D4=D3=D1= =C2=C5=D2=A3=D4=D3=D1 =C2=CC=CF=CB=C9=D2=CF=D7=CB=C1. =EF=D0=C5=D2=C1=C3= =C9=D1 =DA=C1=CB=C1=CE=DE=C9=D7=C1=C5=D4 =C2=CC=CF=CB=C9=D2=CF=D7=CB=C1 =D3=CE=C9=CD=C1=C5=D4=D3=D1. DB_INIT_LOCK =D0=CF =C9=C4=C5=C5 =D3=D0=C5=C3=C9=C1=CC=D8=CE=CF =D5=CB=C1= =DA=D9=D7=C1=D4=D8 =CE=C5 =CE=C1=C4=CF, =C5=D3=CC=C9 =D5=CB=C1=DA=C1=CE=CF DB_INIT_CDB|DB_INIT_MPOOL. =F4=C1=CD =C5=D3=D4=D8 =C5=DD=A3 =C4=D2=D5=C7=CF=CA =D2=C5=D6=C9=CD =D7=CD= =C5=D3=D4=CF =CC=CF=CB=C9=CE=C7=C1, =CF=CE log =CD=CF=D6=C5=D4 =D0=C9=D3=C1= =D4=D8. > =DC=D4=C9 =D0=CF=C4=D2=CF=C2=CE=CFc=D4=C9 =D1 =CE=C5 =D7=C4=C1=D7=C1=CC= =D3=D1, =D5=D4=D7=C5=D2=D6=C4=C1=C5=D4=D3=D1, =DE=D4=CF =CE=C5 =D7=D3=A3 = =C7=CC=C1=C4=CB=CF) =C1=D7=D4=CF=D2=20 > mailfromd =D2=C5=DB=C9=CC =C4=C5=CC=C1=D4=D8 =C2=CC=CF=CB=C9=D2=CF=D7=CB= =C9 =D3=C1=CD=CF=D3=D4=CF=D1=D4=C5=CC=D8=CE=CF. =F1, =D7=D2=CF=C4=C5 =CB=C1= =CB, =C5=C4=C9=CE=D3=D4=D7=C5=CE=CE=D9=CA=20 > =C9=DA =CE=C1=D2=D7=C1=D7=DB=C9=C8=D3=D1 =CE=C1 =D0=D2=CF=C2=CC=C5=CD=D5 = =D3 =C5=C7=CF =C2=CC=CF=CB=C9=D2=CF=D7=CB=C1=CD=C9. =E9=D3=D0=CF=CC=D8=DA= =D5=D1 =CD=C5=D4=CF=C4 =CE=C1=D5=DE=CE=CF=C7=CF =D4=D9=CB=C1=20 > =C9 =D0=CF =D3=CF=D7=C5=D4=D5 =DE=C5=CC=CF=D7=C5=CB=C1, =CB=CF=D4=CF=D2= =D9=CA =CB=CF=C5-=C7=C4=C5 bdb =D3=C1=CD =C9=D3=D0=CF=CC=D8=DA=CF=D7=C1=CC,= =D1 =D0=D2=CF=D3=D4=CF =D5=C2=D2=C1=CC=20 > =C2=CC=CF=CB=C9=D2=CF=D7=CB=D5 (=D0=D2=CF =D4=CF, =DE=D4=CF =CF=CE=C1 =C1= =CB=D4=C9=D7=C9=D2=D5=C5=D4=D3=D1 =D0=D2=C9 =C9=D3=D0=CF=CC=D8=DA=CF=D7=C1= =CE=C9=C9 DB_INIT_LOCK =C9=CC=C9=20 > DB_INIT_CDB, =D1 =C5=DD=A3 =CE=C5 =C4=CF=DE=C9=D4=C1=CC =CE=C1 =D4=CF=D4 = =CD=CF=CD=C5=CE=D4). =F7=CF=D4 =CB=D5=D3=CF=CB =D0=C5=D2=CC=CF=D7=CF=C7=CF =CB=CF=C4=C1. =F4=D5= =D4 =C5=D3=D4=D8 =C4=D7=C5 =D4=CF=CE=CB=CF=D3=D4=C9: =CF=D4=CB=D2=D9=D7=C1= =D4=D8 env =CE=C1=C4=CF =DE=C5=D2=C5=DA exclusive lock, =C9=CE=C1=DE=C5 =D4=C1=CD =C7=CC=C0=CB=C1= =CC=CF. =F1 =DC=D4=CF =C4=C5=CC=C1=C0 =DE=C5=D2=C5=DA flock =CE=C1 =C4=C5=D3=CB=D2=C9=D0=D4=CF=D2=C5 =CB=C1=D4=C1=CC=CF=C7=C1 (=CB=D2=D5=D4=CF= !). =E9 =C5=DD=A3 =CF=C4=CE=C1 =D4=CF=CE=CB=CF=D3=D4=D8 =DE=D4=CF =CE=D5= =D6=CE=CF =D3=C9=C7=CE=C1=CC=D9 =CF=C2=D1=DA=C1=D4=C5=CC=D8=CE=CF =C2=CC=CF=CB=C9=D2=CF=D7=C1=D4=D8 =CE=C1 = =D7=D2=C5=CD=D1 =D7=DA=D1=D4=C9=D1 =C2=CC=CF=CB=C9=D2=CF=D7=CB=C9. =EB=C1= =D6=C5=D4=D3=D1, =C6=C1=CB=D4 =C2=CC=CF=CB=C9=D2=CF=D7=CB=C9 =C6=C9=CB=D3=C9=D2=D5=C5=D4=D3=D1 =C6=C9=DA= =C9=DE=C5=D3=CB=C9 =D7 =D3=C1=CD=CF=CA =C2=C1=DA=C5. =F0=CF=DC=D4=CF=CD=D5= =C5=D3=CC=C9 =D0=CF =D0=D2=C9=DB=C5=D3=D4=D7=C9=C9 =D3=C9=C7=CE=C1=CC=C1 =C2=CC=CF=CB=C9=D2=CF= =D7=CB=D5 =CE=C5 =D3=CE=D1=D4=D8, =D4=CF =C2=C1=DA=C1 =CF=D3=D4=C1=CE=C5=D4= =D3=D1 =DA=C1=CC=CF=DE=C5=CE=CE=CF=CA "=CE=C1=C4=CF=CC=C7=CF". --bAmEntskrkuBymla Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="cache.pm" package qa::cache; use strict; use BerkeleyDB; our $topdir = "$ENV{HOME}/.qa-cache"; my $topdir_fd; my $dbenv; sub init_dbenv () { use Fcntl qw(:flock O_DIRECTORY); -d $topdir or mkdir $topdir; sysopen $topdir_fd, $topdir, O_DIRECTORY or die "$topdir: $!"; if (flock $topdir_fd, LOCK_EX | LOCK_NB) { $dbenv = BerkeleyDB::Env->new(-Home => $topdir, -Verbose => 1, -ErrFile => *STDERR, -Flags => DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL) or die $BerkeleyDB::Error; # TODO: drop all locks flock $topdir_fd, LOCK_SH; } else { flock $topdir_fd, LOCK_SH; $dbenv = BerkeleyDB::Env->new(-Home => $topdir, -Verbose => 1, -ErrFile => *STDERR, -Flags => DB_JOINENV) or die $BerkeleyDB::Error; } } my %blessed; my $pagesize; sub TIEHASH ($$) { my ($class, $id) = @_; return $blessed{$id} if $blessed{$id}; init_dbenv() unless $dbenv; my $dir = "$topdir/$id"; -d $dir or mkdir $dir; my $db = BerkeleyDB::Hash->new(-Filename => "$id/cache.db", -Env => $dbenv, -Flags => DB_CREATE) or die $BerkeleyDB::Error; $pagesize ||= $db->db_stat->{hash_pagesize}; my $self = bless [ $dir, $db ] => $class; $blessed{$id} = $self; use Scalar::Util qw(weaken); weaken $blessed{$id}; return $self; } use Storable qw(freeze thaw); use Compress::LZO qw(compress decompress); use Digest::SHA1 qw(sha1); use constant { V_STO => 2**1, # STO is Special Theory of Relativity V_LZO => 2**2, # LZO is real-time compressor }; my $today = int($^T / 3600 / 24); sub STORE ($$$) { my ($self, $k, $v) = @_; $k = freeze($k) if ref $k; $k = sha1($k); my $vflags = 0; if (ref $v) { $v = freeze($v); $vflags |= V_STO; } if (length($v) > 768) { $v = compress($v); $vflags |= V_LZO; } my ($dir, $db) = @$self; if (length($v) > $pagesize / 2) { my ($subdir, $file) = unpack "H2H*", $k; $subdir = "$dir/$subdir"; $file = "$subdir/$file"; -d $subdir or mkdir $subdir; open my $fh, ">", "$file.$$" or die $!; syswrite $fh, pack("S", $vflags); syswrite $fh, $v; close $fh; rename "$file.$$", $file; } else { # SSS: mtime, atime, vflags $db->db_put($k, pack("SSS", $today, 0, $vflags) . $v); } } sub FETCH ($$) { my ($self, $k) = @_; $k = freeze($k) if ref $k; $k = sha1($k); my ($dir, $db) = @$self; my ($vflags, $v); if ($db->db_get($k, $v) == 0) { (my $m, my $a, $vflags) = unpack "SSS", $v; substr $v, 0, 6, ""; $db->db_put($k, pack("SSS", $m, $today, $vflags) . $v) if $a != $today; # XXX not atomic } else { my ($subdir, $file) = unpack "H2H*", $k; $subdir = "$dir/$subdir"; $file = "$subdir/$file"; open my $fh, "<", $file or return; local $/; $v = <$fh>; $vflags = unpack "S", $v; substr $v, 0, 2, ""; } $v = decompress($v) if $vflags & V_LZO; $v = thaw($v) if $vflags & V_STO; return $v; } sub EXISTS ($$) { my ($self, $k) = @_; $k = freeze($k) if ref($k); $k = sha1($k); my ($dir, $db) = @$self; return 1 if $db->db_get($k, my $v) == 0; my ($subdir, $file) = unpack "H2H*", $k; $subdir = "$dir/$subdir"; $file = "$subdir/$file"; return -f $file; } sub DELETE ($$) { my ($self, $k) = @_; $k = freeze($k) if ref($k); $k = sha1($k); my ($dir, $db) = @$self; $db->db_del($k); my ($subdir, $file) = unpack "H2H*", $k; $subdir = "$dir/$subdir"; $file = "$subdir/$file"; unlink $file; } # BerkeleyDB cleans up at the END, so do I my $global_destruction; # execute the END when interrupted by a signal -- # it is VERY important to release all locks and shut down gracefully use sigtrap qw(die normal-signals); our $expire = 33; sub DESTROY ($) { return if $global_destruction; my $self = shift; my ($dir, $db) = @$self; my $cur = $db->_db_write_cursor() or return; if ($db->db_get("cleanup", my $cleanup) != 0) { $db->db_put("cleanup", $today); return; } elsif ($cleanup == $today) { return; } while ($cur->c_get(my $k, my $v, DB_NEXT) == 0) { next if $k eq "cleanup"; my ($m, $a, $vflags) = unpack "SSS", $v; next if $a + 33 > $today; next if $m + 33 > $today; $cur->c_del(); } my $wanted = sub { stat or return; -f _ and -M _ > $expire and -A _ > $expire and unlink; -d _ and rmdir; }; require File::Find; File::Find::finddepth($wanted, $dir); } END { undef $dbenv; while (my ($id, $self) = each %blessed) { next unless $self; $self->DESTROY(); undef @$self; } $global_destruction = 1; } 1; --bAmEntskrkuBymla-- --7DO5AaGCk89r4vaK Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFGMc5yfBKgtDjnu0YRApy7AKCrvS3PoxgEqPCtRD+54BLR2UJDtACgojgf 5Gg2HVFIbfWx36DQTGnGC1M= =VEtu -----END PGP SIGNATURE----- --7DO5AaGCk89r4vaK--