1 # DB_File.pm -- Perl 5 interface to Berkeley DB
3 # written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
4 # last modified 28th June 1996
7 package DB_File::HASHINFO ;
12 @DB_File::HASHINFO::ISA = qw(Tie::Hash);
26 bless { 'bsize' => undef,
40 return $self->{$key} if exists $self->{$key} ;
43 croak "${pkg}::FETCH - Unknown element '$key'" ;
53 if ( exists $self->{$key} )
55 $self->{$key} = $value ;
60 croak "${pkg}::STORE - Unknown element '$key'" ;
68 if ( exists $self->{$key} )
70 delete $self->{$key} ;
75 croak "DB_File::HASHINFO::DELETE - Unknown element '$key'" ;
83 exists $self->{$key} ;
91 croak "${pkg} does not define the method ${method}" ;
94 sub DESTROY { undef %{$_[0]} }
95 sub FIRSTKEY { my $self = shift ; $self->NotHere(ref $self, "FIRSTKEY") }
96 sub NEXTKEY { my $self = shift ; $self->NotHere(ref $self, "NEXTKEY") }
97 sub CLEAR { my $self = shift ; $self->NotHere(ref $self, "CLEAR") }
99 package DB_File::RECNOINFO ;
103 @DB_File::RECNOINFO::ISA = qw(DB_File::HASHINFO) ;
109 bless { 'bval' => undef,
110 'cachesize' => undef,
119 package DB_File::BTREEINFO ;
123 @DB_File::BTREEINFO::ISA = qw(DB_File::HASHINFO) ;
129 bless { 'flags' => undef,
130 'cachesize' => undef,
131 'maxkeypage' => undef,
132 'minkeypage' => undef,
144 use vars qw($VERSION @ISA @EXPORT $AUTOLOAD $DB_BTREE $DB_HASH $DB_RECNO) ;
150 #typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
151 #$DB_BTREE = TIEHASH DB_File::BTREEINFO ;
152 #$DB_HASH = TIEHASH DB_File::HASHINFO ;
153 #$DB_RECNO = TIEHASH DB_File::RECNOINFO ;
155 $DB_BTREE = new DB_File::BTREEINFO ;
156 $DB_HASH = new DB_File::HASHINFO ;
157 $DB_RECNO = new DB_File::RECNOINFO ;
163 @ISA = qw(Tie::Hash Exporter DynaLoader);
165 $DB_BTREE $DB_HASH $DB_RECNO
200 ($constname = $AUTOLOAD) =~ s/.*:://;
201 my $val = constant($constname, @_ ? $_[0] : 0);
203 if ($! =~ /Invalid/) {
204 $AutoLoader::AUTOLOAD = $AUTOLOAD;
205 goto &AutoLoader::AUTOLOAD;
208 my($pack,$file,$line) = caller;
209 croak "Your vendor has not defined DB macro $constname, used at $file line $line.
213 eval "sub $AUTOLOAD { $val }";
217 bootstrap DB_File $VERSION;
219 # Preloaded methods go here. Autoload methods go after __END__, and are
220 # processed by the autosplit program.
225 croak "Usage: \$db->get_dup(key [,flag])\n"
226 unless @_ == 2 or @_ == 3 ;
233 my $wantarray = wantarray ;
237 # get the first value associated with the key, $key
238 $db->seq($key, $value, R_CURSOR()) ;
240 if ( $key eq $origkey) {
243 # save the value or count matches
245 { push (@values, $value) ; push(@values, 1) if $flag }
249 # iterate through the database until either EOF
250 # or a different key is encountered.
251 last if $db->seq($key, $value, R_NEXT()) != 0 or $key ne $origkey ;
255 $wantarray ? @values : $counter ;
266 DB_File - Perl5 access to Berkeley DB
273 [$X =] tie %hash, 'DB_File', [$filename, $flags, $mode, $DB_HASH] ;
274 [$X =] tie %hash, 'DB_File', $filename, $flags, $mode, $DB_BTREE ;
275 [$X =] tie @array, 'DB_File', $filename, $flags, $mode, $DB_RECNO ;
277 [$X =] tie %hash, DB_File, $filename [, $flags, $mode, $DB_HASH ] ;
278 [$X =] tie %hash, DB_File, $filename, $flags, $mode, $DB_BTREE ;
279 [$X =] tie @array, DB_File, $filename, $flags, $mode, $DB_RECNO ;
281 $status = $X->del($key [, $flags]) ;
282 $status = $X->put($key, $value [, $flags]) ;
283 $status = $X->get($key, $value [, $flags]) ;
284 $status = $X->seq($key, $value , $flags) ;
285 $status = $X->sync([$flags]) ;
288 $count = $X->get_dup($key) ;
289 @list = $X->get_dup($key) ;
290 %list = $X->get_dup($key, 1) ;
297 B<DB_File> is a module which allows Perl programs to make use of the
298 facilities provided by Berkeley DB. If you intend to use this
299 module you should really have a copy of the Berkeley DB manual page at
300 hand. The interface defined here mirrors the Berkeley DB interface
303 Berkeley DB is a C library which provides a consistent interface to a
304 number of database formats. B<DB_File> provides an interface to all
305 three of the database types currently supported by Berkeley DB.
313 This database type allows arbitrary key/value pairs to be stored in data
314 files. This is equivalent to the functionality provided by other
315 hashing packages like DBM, NDBM, ODBM, GDBM, and SDBM. Remember though,
316 the files created using DB_HASH are not compatible with any of the
317 other packages mentioned.
319 A default hashing algorithm, which will be adequate for most
320 applications, is built into Berkeley DB. If you do need to use your own
321 hashing algorithm it is possible to write your own in Perl and have
322 B<DB_File> use it instead.
324 When opening an existing database, you may omit the final three arguments
325 to C<tie>; they default to O_RDWR, 0644, and $DB_HASH. If you're
326 creating a new file, you need to specify at least the C<$flags>
327 argument, which must include O_CREAT.
331 The btree format allows arbitrary key/value pairs to be stored in a
332 sorted, balanced binary tree.
334 As with the DB_HASH format, it is possible to provide a user defined
335 Perl routine to perform the comparison of keys. By default, though, the
336 keys are stored in lexical order.
340 DB_RECNO allows both fixed-length and variable-length flat text files
341 to be manipulated using the same key/value pair interface as in DB_HASH
342 and DB_BTREE. In this case the key will consist of a record (line)
347 =head2 How does DB_File interface to Berkeley DB?
349 B<DB_File> allows access to Berkeley DB files using the tie() mechanism
350 in Perl 5 (for full details, see L<perlfunc/tie()>). This facility
351 allows B<DB_File> to access Berkeley DB files using either an
352 associative array (for DB_HASH & DB_BTREE file types) or an ordinary
353 array (for the DB_RECNO file type).
355 In addition to the tie() interface, it is also possible to access most
356 of the functions provided in the Berkeley DB API directly.
357 See L<"Using the Berkeley DB API Directly">.
359 =head2 Opening a Berkeley DB Database File
361 Berkeley DB uses the function dbopen() to open or create a database.
362 Below is the C prototype for dbopen().
365 dbopen (const char * file, int flags, int mode,
366 DBTYPE type, const void * openinfo)
368 The parameter C<type> is an enumeration which specifies which of the 3
369 interface methods (DB_HASH, DB_BTREE or DB_RECNO) is to be used.
370 Depending on which of these is actually chosen, the final parameter,
371 I<openinfo> points to a data structure which allows tailoring of the
372 specific interface method.
374 This interface is handled slightly differently in B<DB_File>. Here is
375 an equivalent call using B<DB_File>:
377 tie %array, 'DB_File', $filename, $flags, $mode, $DB_HASH ;
379 The C<filename>, C<flags> and C<mode> parameters are the direct
380 equivalent of their dbopen() counterparts. The final parameter $DB_HASH
381 performs the function of both the C<type> and C<openinfo> parameters in
384 In the example above $DB_HASH is actually a pre-defined reference to a
385 hash object. B<DB_File> has three of these pre-defined references.
386 Apart from $DB_HASH, there is also $DB_BTREE and $DB_RECNO.
388 The keys allowed in each of these pre-defined references is limited to
389 the names used in the equivalent C structure. So, for example, the
390 $DB_HASH reference will only allow keys called C<bsize>, C<cachesize>,
391 C<ffactor>, C<hash>, C<lorder> and C<nelem>.
393 To change one of these elements, just assign to it like this:
395 $DB_HASH->{'cachesize'} = 10000 ;
397 The three predefined variables $DB_HASH, $DB_BTREE and $DB_RECNO are
398 usually adequate for most applications. If you do need to create extra
399 instances of these objects, constructors are available for each file
402 Here are examples of the constructors and the valid options available
403 for DB_HASH, DB_BTREE and DB_RECNO respectively.
405 $a = new DB_File::HASHINFO ;
413 $b = new DB_File::BTREEINFO ;
423 $c = new DB_File::RECNOINFO ;
432 The values stored in the hashes above are mostly the direct equivalent
433 of their C counterpart. Like their C counterparts, all are set to a
434 default set of values - that means you don't have to set I<all> of the
435 values when you only want to change one. Here is an example:
437 $a = new DB_File::HASHINFO ;
438 $a->{'cachesize'} = 12345 ;
439 tie %y, 'DB_File', "filename", $flags, 0777, $a ;
441 A few of the values need extra discussion here. When used, the C
442 equivalent of the keys C<hash>, C<compare> and C<prefix> store pointers
443 to C functions. In B<DB_File> these keys are used to store references
444 to Perl subs. Below are templates for each of the subs:
450 # return the hash value for $data
456 my ($key, $key2) = @_ ;
458 # return 0 if $key1 eq $key2
459 # -1 if $key1 lt $key2
460 # 1 if $key1 gt $key2
461 return (-1 , 0 or 1) ;
466 my ($key, $key2) = @_ ;
468 # return number of bytes of $key2 which are
469 # necessary to determine that it is greater than $key1
473 See L<"Using BTREE"> for an example of using the C<compare>
475 =head2 Default Parameters
477 It is possible to omit some or all of the final 4 parameters in the
478 call to C<tie> and let them take default values. As DB_HASH is the most
479 common file format used, the call:
481 tie %A, "DB_File", "filename" ;
485 tie %A, "DB_File", "filename", O_CREAT|O_RDWR, 0640, $DB_HASH ;
487 It is also possible to omit the filename parameter as well, so the
494 tie %A, "DB_File", undef, O_CREAT|O_RDWR, 0640, $DB_HASH ;
496 See L<"In Memory Databases"> for a discussion on the use of C<undef>
497 in place of a filename.
499 =head2 Handling duplicate keys in BTREE databases
501 The BTREE file type in Berkeley DB optionally allows a single key to be
502 associated with an arbitrary number of values. This option is enabled by
503 setting the flags element of C<$DB_BTREE> to R_DUP when creating the
506 There are some difficulties in using the tied hash interface if you
507 want to manipulate a BTREE database with duplicate keys. Consider this
516 # Enable duplicate records
517 $DB_BTREE->{'flags'} = R_DUP ;
519 tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0640, $DB_BTREE
520 or die "Cannot open $filename: $!\n";
522 # Add some key/value pairs to the file
523 $h{'Wall'} = 'Larry' ;
524 $h{'Wall'} = 'Brick' ; # Note the duplicate key
525 $h{'Smith'} = 'John' ;
526 $h{'mouse'} = 'mickey' ;
528 # iterate through the associative array
529 # and print each key/value pair.
531 { print "$_ -> $h{$_}\n" }
540 As you can see 2 records have been successfully created with key C<Wall>
541 - the only thing is, when they are retrieved from the database they
542 both I<seem> to have the same value, namely C<Larry>. The problem is
543 caused by the way that the associative array interface works.
544 Basically, when the associative array interface is used to fetch the
545 value associated with a given key, it will only ever retrieve the first
548 Although it may not be immediately obvious from the code above, the
549 associative array interface can be used to write values with duplicate
550 keys, but it cannot be used to read them back from the database.
552 The way to get around this problem is to use the Berkeley DB API method
553 called C<seq>. This method allows sequential access to key/value
554 pairs. See L<"Using the Berkeley DB API Directly"> for details of both
555 the C<seq> method and the API in general.
557 Here is the script above rewritten using the C<seq> API method.
565 # Enable duplicate records
566 $DB_BTREE->{'flags'} = R_DUP ;
568 $x = tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0640, $DB_BTREE
569 or die "Cannot open $filename: $!\n";
571 # Add some key/value pairs to the file
572 $h{'Wall'} = 'Larry' ;
573 $h{'Wall'} = 'Brick' ; # Note the duplicate key
574 $h{'Smith'} = 'John' ;
575 $h{'mouse'} = 'mickey' ;
577 # Point to the first record in the btree
578 $x->seq($key, $value, R_FIRST) ;
580 # now iterate through the rest of the btree
581 # and print each key/value pair.
582 print "$key -> $value\n" ;
583 while ( $x->seq($key, $value, R_NEXT) == 0)
584 { print "$key -> $value\n" }
596 This time we have got all the key/value pairs, including both the
597 values associated with the key C<Wall>.
599 C<DB_File> comes with a utility method, called C<get_dup>, to assist in
600 reading duplicate values from BTREE databases. The method can take the
603 $count = $x->get_dup($key) ;
604 @list = $x->get_dup($key) ;
605 %list = $x->get_dup($key, 1) ;
607 In a scalar context the method returns the number of values associated
608 with the key, C<$key>.
610 In list context, it returns all the values which match C<$key>. Note
611 that the values returned will be in an apparently random order.
613 If the second parameter is present and evaluates TRUE, the method
614 returns an associative array whose keys correspond to the the values
615 from the BTREE and whose values are all C<1>.
617 So assuming the database created above, we can use C<get_dups> like
620 $cnt = $x->get_dups("Wall") ;
621 print "Wall occurred $cnt times\n" ;
623 %hash = $x->get_dups("Wall", 1) ;
624 print "Larry is there\n" if $hash{'Larry'} ;
626 @list = $x->get_dups("Wall") ;
627 print "Wall => [@list]\n" ;
629 @list = $x->get_dups("Smith") ;
630 print "Smith => [@list]\n" ;
632 @list = $x->get_dups("Dog") ;
633 print "Dog => [@list]\n" ;
638 Wall occurred 2 times
640 Wall => [Brick Larry]
646 In order to make RECNO more compatible with Perl the array offset for
647 all RECNO arrays begins at 0 rather than 1 as in Berkeley DB.
649 As with normal Perl arrays, a RECNO array can be accessed using
650 negative indexes. The index -1 refers to the last element of the array,
651 -2 the second last, and so on. Attempting to access an element before
652 the start of the array will raise a fatal run-time error.
654 =head2 In Memory Databases
656 Berkeley DB allows the creation of in-memory databases by using NULL
657 (that is, a C<(char *)0> in C) in place of the filename. B<DB_File>
658 uses C<undef> instead of NULL to provide this functionality.
661 =head2 Using the Berkeley DB API Directly
663 As well as accessing Berkeley DB using a tied hash or array, it is also
664 possible to make direct use of most of the API functions defined in the
665 Berkeley DB documentation.
667 To do this you need to store a copy of the object returned from the tie.
669 $db = tie %hash, "DB_File", "filename" ;
671 Once you have done that, you can access the Berkeley DB API functions
672 as B<DB_File> methods directly like this:
674 $db->put($key, $value, R_NOOVERWRITE) ;
676 B<Important:> If you have saved a copy of the object returned from
677 C<tie>, the underlying database file will I<not> be closed until both
678 the tied variable is untied and all copies of the saved object are
682 $db = tie %hash, "DB_File", "filename"
683 or die "Cannot tie filename: $!" ;
688 All the functions defined in L<dbopen> are available except for
689 close() and dbopen() itself. The B<DB_File> method interface to the
690 supported functions have been implemented to mirror the way Berkeley DB
691 works whenever possible. In particular note that:
697 The methods return a status value. All return 0 on success.
698 All return -1 to signify an error and set C<$!> to the exact
699 error code. The return code 1 generally (but not always) means that the
700 key specified did not exist in the database.
702 Other return codes are defined. See below and in the Berkeley DB
703 documentation for details. The Berkeley DB documentation should be used
704 as the definitive source.
708 Whenever a Berkeley DB function returns data via one of its parameters,
709 the equivalent B<DB_File> method does exactly the same.
713 If you are careful, it is possible to mix API calls with the tied
714 hash/array interface in the same piece of code. Although only a few of
715 the methods used to implement the tied interface currently make use of
716 the cursor, you should always assume that the cursor has been changed
717 any time the tied hash/array interface is used. As an example, this
718 code will probably not do what you expect:
720 $X = tie %x, 'DB_File', $filename, O_RDWR|O_CREAT, 0777, $DB_BTREE
721 or die "Cannot tie $filename: $!" ;
723 # Get the first key/value pair and set the cursor
724 $X->seq($key, $value, R_FIRST) ;
726 # this line will modify the cursor
727 $count = scalar keys %x ;
729 # Get the second key/value pair.
730 # oops, it didn't, it got the last key/value pair!
731 $X->seq($key, $value, R_NEXT) ;
733 The code above can be rearranged to get around the problem, like this:
735 $X = tie %x, 'DB_File', $filename, O_RDWR|O_CREAT, 0777, $DB_BTREE
736 or die "Cannot tie $filename: $!" ;
738 # this line will modify the cursor
739 $count = scalar keys %x ;
741 # Get the first key/value pair and set the cursor
742 $X->seq($key, $value, R_FIRST) ;
744 # Get the second key/value pair.
746 $X->seq($key, $value, R_NEXT) ;
750 All the constants defined in L<dbopen> for use in the flags parameters
751 in the methods defined below are also available. Refer to the Berkeley
752 DB documentation for the precise meaning of the flags values.
754 Below is a list of the methods available.
758 =item C<$status = $X-E<gt>get($key, $value [, $flags]) ;>
760 Given a key (C<$key>) this method reads the value associated with it
761 from the database. The value read from the database is returned in the
764 If the key does not exist the method returns 1.
766 No flags are currently defined for this method.
768 =item C<$status = $X-E<gt>put($key, $value [, $flags]) ;>
770 Stores the key/value pair in the database.
772 If you use either the R_IAFTER or R_IBEFORE flags, the C<$key> parameter
773 will have the record number of the inserted key/value pair set.
775 Valid flags are R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE and
778 =item C<$status = $X-E<gt>del($key [, $flags]) ;>
780 Removes all key/value pairs with key C<$key> from the database.
782 A return code of 1 means that the requested key was not in the
785 R_CURSOR is the only valid flag at present.
787 =item C<$status = $X-E<gt>fd ;>
789 Returns the file descriptor for the underlying database.
791 See L<"Locking Databases"> for an example of how to make use of the
792 C<fd> method to lock your database.
794 =item C<$status = $X-E<gt>seq($key, $value, $flags) ;>
796 This interface allows sequential retrieval from the database. See
797 L<dbopen> for full details.
799 Both the C<$key> and C<$value> parameters will be set to the key/value
800 pair read from the database.
802 The flags parameter is mandatory. The valid flag values are R_CURSOR,
803 R_FIRST, R_LAST, R_NEXT and R_PREV.
805 =item C<$status = $X-E<gt>sync([$flags]) ;>
807 Flushes any cached buffers to disk.
809 R_RECNOSYNC is the only valid flag at present.
815 It is always a lot easier to understand something when you see a real
816 example. So here are a few.
823 tie %h, "DB_File", "hashed", O_RDWR|O_CREAT, 0640, $DB_HASH
824 or die "Cannot open file 'hashed': $!\n";
826 # Add a key/value pair to the file
827 $h{"apple"} = "orange" ;
829 # Check for existence of a key
830 print "Exists\n" if $h{"banana"} ;
839 Here is a sample of code which uses BTREE. Just to make life more
840 interesting the default comparison function will not be used. Instead
841 a Perl sub, C<Compare()>, will be used to do a case insensitive
849 my ($key1, $key2) = @_ ;
851 "\L$key1" cmp "\L$key2" ;
854 $DB_BTREE->{'compare'} = 'Compare' ;
856 tie %h, "DB_File", "tree", O_RDWR|O_CREAT, 0640, $DB_BTREE
857 or die "Cannot open file 'tree': $!\n" ;
859 # Add a key/value pair to the file
860 $h{'Wall'} = 'Larry' ;
861 $h{'Smith'} = 'John' ;
862 $h{'mouse'} = 'mickey' ;
863 $h{'duck'} = 'donald' ;
868 # Cycle through the keys printing them in order.
869 # Note it is not necessary to sort the keys as
870 # the btree will have kept them in order automatically.
876 Here is the output from the code above.
885 Here is a simple example that uses RECNO.
890 $DB_RECNO->{'psize'} = 3000 ;
892 tie @h, "DB_File", "text", O_RDWR|O_CREAT, 0640, $DB_RECNO
893 or die "Cannot open file 'text': $!\n" ;
895 # Add a key/value pair to the file
898 # Check for existence of a key
899 print "Exists\n" if $h[1] ;
903 =head2 Locking Databases
905 Concurrent access of a read-write database by several parties requires
906 them all to use some kind of locking. Here's an example of Tom's that
907 uses the I<fd> method to get the file descriptor, and then a careful
908 open() to give something Perl will flock() for you. Run this repeatedly
909 in the background to watch the locks granted in proper order.
921 my($oldval, $fd, $db, %db, $value, $key);
923 $key = shift || 'default';
924 $value = shift || 'magic';
928 $db = tie(%db, 'DB_File', '/tmp/foo.db', O_CREAT|O_RDWR, 0644)
929 || die "dbcreat /tmp/foo.db $!";
931 print "$$: db fd is $fd\n";
932 open(DB_FH, "+<&=$fd") || die "dup $!";
935 unless (flock (DB_FH, LOCK_SH | LOCK_NB)) {
936 print "$$: CONTENTION; can't read during write update!
937 Waiting for read lock ($!) ....";
938 unless (flock (DB_FH, LOCK_SH)) { die "flock: $!" }
940 print "$$: Read lock granted\n";
943 print "$$: Old value was $oldval\n";
944 flock(DB_FH, LOCK_UN);
946 unless (flock (DB_FH, LOCK_EX | LOCK_NB)) {
947 print "$$: CONTENTION; must have exclusive lock!
948 Waiting for write lock ($!) ....";
949 unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" }
952 print "$$: Write lock granted\n";
957 flock(DB_FH, LOCK_UN);
961 print "$$: Updated db to $key=$value\n";
973 When B<DB_File> is opening a database file it no longer terminates the
974 process if I<dbopen> returned an error. This allows file protection
975 errors to be caught at run time. Thanks to Judith Grass
976 E<lt>grass@cybercash.comE<gt> for spotting the bug.
980 Added prototype support for multiple btree compare callbacks.
984 B<DB_File> has been in use for over a year. To reflect that, the
985 version number has been incremented to 1.0.
987 Added complete support for multiple concurrent callbacks.
989 Using the I<push> method on an empty list didn't work properly. This
994 Fixed a core dump problem with SunOS.
996 The return value from TIEHASH wasn't set to NULL when dbopen returned
1001 Merged OS2 specific code into DB_File.xs
1003 Removed some redundant code in DB_File.xs.
1005 Documentation update.
1007 Allow negative subscripts with RECNO interface.
1009 Changed the default flags from O_RDWR to O_CREAT|O_RDWR.
1011 The example code which showed how to lock a database needed a call to
1012 C<sync> added. Without it the resultant database file was empty.
1014 Added get_dups method.
1018 If you happen to find any other functions defined in the source for
1019 this module that have not been mentioned in this document -- beware. I
1020 may drop them at a moments notice.
1022 If you cannot find any, then either you didn't look very hard or the
1023 moment has passed and I have dropped them.
1027 Some older versions of Berkeley DB had problems with fixed length
1028 records using the RECNO file format. The newest version at the time of
1029 writing was 1.85 - this seems to have fixed the problems with RECNO.
1031 I am sure there are bugs in the code. If you do find any, or can
1032 suggest any enhancements, I would welcome your comments.
1036 Berkeley DB is available at your nearest CPAN archive (see
1037 L<perlmod/"CPAN"> for a list) in F<src/misc/db.1.85.tar.gz>, or via the
1038 host F<ftp.cs.berkeley.edu> in F</ucb/4bsd/db.tar.gz>. It is I<not> under
1041 If you are running IRIX, then get Berkeley DB from
1042 F<http://reality.sgi.com/ariel>. It has the patches necessary to
1043 compile properly on IRIX 5.3.
1047 L<perl(1)>, L<dbopen(3)>, L<hash(3)>, L<recno(3)>, L<btree(3)>
1049 Berkeley DB is available from F<ftp.cs.berkeley.edu> in the directory
1054 The DB_File interface was written by Paul Marquess
1055 E<lt>pmarquess@bfsec.bt.co.ukE<gt>.
1056 Questions about the DB system itself may be addressed to Keith Bostic
1057 E<lt>bostic@cs.berkeley.eduE<gt>.