package TDB_FileX; use common::sense; use Exporter (); use XSLoader (); our @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. our %EXPORT_TAGS = ( flags => [qw( ALLOW_NESTING BIGENDIAN CLEAR_IF_FIRST CONVERT DEFAULT DISALLOW_NESTING INCOMPATIBLE_HASH INTERNAL MUTEX_LOCKING NOLOCK NOMMAP NOSYNC SEQNUM VOLATILE )], insert => [qw( INSERT MODIFY REPLACE )], error => [qw( SUCCESS ERR_CORRUPT ERR_EXISTS ERR_IO ERR_LOCK ERR_LOCK_TIMEOUT ERR_NOEXIST ERR_NOLOCK ERR_OOM ERR_EINVAL ERR_RDONLY )], debug => [qw( DEBUG_FATAL DEBUG_ERROR DEBUG_WARNING DEBUG_TRACE} )], ); our @EXPORT_OK; Exporter::export_ok_tags qw(flags insert error debug); $EXPORT_TAGS{all} = \@EXPORT_OK; our $VERSION = '0.97'; XSLoader::load __PACKAGE__, $VERSION; 1; __END__ =head1 NAME TDB_FileX - Perl access to the trivial database library =head1 SYNOPSIS use TDB_FileX; # tie interface tie %hash, TDB_FileX => $filename, hash_size => 8000, mutex => 1, ; $hash{key} = 'value'; while (my ($k, $v) = each %hash) { print "$k -> $v\n" } # OO interface my $tdb = TDB_FileX->open ($filename, flags => TDB_FileX::CLEAR_IF_FIRST) or die $!; $tdb->store (key => 'value') or die $tdb->errorstr; $tdb->traverse (sub { print "$_[0] -> $_[1]\n" }); =head1 DESCRIPTION TDB is a simple database similar to GDBM, but allows multiple simultaneous writers. It's main drawback is the need to manually configure a hash table size in advance - see the C option for C. TDB_FileX provides a simple C interface, similar to DB_File and friends; and an object-oriented interface, which provides access to all of the functions in the tdb library. =head2 FUNCTIONS =over 4 =item TDB_FileX->open ($path[, key => value...]) TDB_FileX constructor. Opens $path and returns a TDB_FileX object. The same arguments may be passed to the C function. On error, C<$!> is set and C is returned. A number of key-value pairs are accepted, with hopefully sensible defaults for most of these (but you should consider at least setting C if you want to store more than a thousand or so pairs, And C if you want to take advantage of much faster locking. =over =item tdb_flags => $flags (default: C) A set of flags that influence the behaviour and format of the database. See tdb_open(3) for the meanings and possible values (note that the C prefix has to be removed, see the L section for a list. =item open_flags => $flags (default: C) Standard open flags, as used in C. =item mode => $mode (default: C<0666>) Standard file open mode, as use din C. Only used when creating the database file. =item hash_size => $int (default: internal to libtdb, but normally C<131>) The size of the internal hash table - only used when creating the database. The default is usually very low and only good for a few thousand keys. As a rule of thumb, it should be at least one percent of the number of keys you plan to store, e.g. for C<800000> keys you should use around a size of C<8000>. To give you an idea of the performance, I inserted about 600000 records, 3GB of data, into a TDB file: size time 131 160s 256 85s 1024 12s 4096 5s 8192 4s As you can see, the default hash table size for this case caused it to use 40 times the time to insert than a larger hash table, the optimum being around 75 ke4ys per hash entry). =item log_cb => $cb->($level, $msg) Setsb a code reference that is called with a message and a log level (lower means more important, there are C, C, C and C). Unlike the "debug" in the name might indicate, if you want to find out why, for instance, you could not open a database, you need to use a logging callback. =item hash => $hash (default: C) Selects a hash function to use. =over =item C<"default"> or C Use autodetection and use either C<"jenkins"> or the original tdb hash function. =item C<"jenkins"> The jenkins hash function. Relatively fast, and recommended for modern tdb databases that need to be interoperable between implementations. =item C<"fnv1ax"> The FNV1-A hash with 32 bit post-mixing. Pretty good and verxy fast for keys up to 10-20 octets. =item C<"xxh3"> The XXH3 hash. Very good and fast especially for long keys. =item C<1> .. C<4> Specify one of up to four custom hash functions (see L). =back =item mutex => $bool (default: C<0>) TDB can take advantage of fast interprocess mutexes, which can be orders of magnitude faster than the syscall-based locking used by default. Normally, you need to call C and set the C flag if support is indicated. This option, when enabled, enables C if it is supported by the platform - which involves a fork when opening the database. When disabled, it will remove the flag. It is recommended to keep this one, but enabling this changes the format of the database, so might not be an option if interoperability with other programs is required. =back There is no explicit close function. The database is closed implicitly when there are no remaining references. =item $tdb->store ($key, $value[, $flag=REPLACE]) Store $value in the database with key w$key. The $flag defaults to C, but can also be C or C, see tdb_store(3) for details. On failure, a perl false is returned. See Lerror> and Lerrorstr> for the reason. =item $tdb->fetch ($key) Fetch the value associated with $key, or C if it is not found. =item $tdb->delete ($key) Delete the value associated with $key. On failure, a perl false is returned. See Lerror> and Lerrorstr> for the reason. =item $tdb->exists ($key) Return true if the $key is found, false otherwise. =item $tdb->firstkey Return the key of the first value in the database. Returns C on failure or if there are no keys in the database. See tdb_firstkey(3) for details. =item $tdb->nextkey ($lastkey) Return the next key in the database after $lastkey. Returns C on failure or if there are no more keys in the database. See tdb_nextkey(3) for details. =item $tdb->error Returns the current error state of the C<$tdb> object. See the list of error codes given in L. =item $tdb->errorstr Returns a printable string that describes the error state of the database. =item $tdb->reopen Closes and reopens the database. Required after a L, if both processes wish to use the database. B If C fails (returns false), then it is unsafe to call any further methods on C<$tdb>. Thus, the only way to find out I C failed is to use a logging function. =item TDB_FileX::reopen_all Closes and reopens all open databases. See Lreopen>. B If C fails (returns false), there is no indication of I C<$tdb> objects failed or why. If you have to survive failures, you may wish to do your own C loop instead. =item $tdb->traverse ($cb->()) #TODO Call $cb for each entry in the database. The callback is called with the key and value as arguments and should return a true value if you wish to continue traversal. C returns the number of elements traversed or C on error. If SUB is C, then this function simply counts the number of elements. =item $tdb->set_logging_function(SUB) Set the logging function to use when this database object encounters errors. SUB should be a coderef or a string giving the name of a function. SUB is called with the severity level (an integer) and the message (a string). =item $tdb->lockall Lock an entire database, returning false on error. =item $tdb->unlockall Unlock an entire database previously locked with Llockall>. =item $tdb->dump_all Dump the records and freelist to STDOUT in an almost human readable form. =item $tdb->printfreelist Dump the freelist to STDOUT. =back =head2 EXPORTS Nothing constants are exported by default. The tag C<:all> exports allpo of the constants. Individually or with the tag C<:flags>: DEFAULT CLEAR_IF_FIRST INTERNAL NOLOCK NOMMAP CONVERT BIGENDIAN NOSYNC SEQNUM VOLATILE ALLOW_NESTING DISALLOW_NESTING INCOMPATIBLE_HASH MUTEX_LOCKING Individually or with the tag C<:insert>: REPLACE INSERT MODIFY Individually or with the tag C<:error>: SUCCESS ERR_CORRUPT ERR_IO ERR_LOCK ERR_OOM ERR_EXISTS ERR_NOLOCK ERR_LOCK_TIMEOUT ERR_NOEXIST ERR_EINVAL ERR_RDONLY Individually or with the tag C<:debug>: DEBUG_FATAL DEBUG_ERROR DEBUG_WARNING DEBUG_TRACE =head1 BUGS There is no way to survive an error during C. Unfortunately this is a limitation in the TDB C API. Currently the hash functions are set globally. This is due to a limitation in the TDB C API. =head1 SEE ALSO tdb(3), L. =head1 AUTHOR Angus Lees, Egus@inodes.org> Currently maintained by Marc A. Lehmann http://home.schmorp.de/ =cut