DBM(2)DBM(2)NAME
Dbm: Dbf, init - data base with hashed indexing
SYNOPSIS
include "dbm.m";
dbm := load Dbm Dbm->PATH;
Datum, Dbf: import dbm;
Datum: type array of byte;
Dbf: adt {
create: fn(file: string, perm: int): ref Dbf;
open: fn(file: string, flags: int): ref Dbf;
fetch: fn(db: self ref Dbf, key: Datum): Datum;
delete: fn(db: self ref Dbf, key: Datum): int;
store: fn(db: self ref Dbf, key: Datum, data: Datum,
replace: int): int;
firstkey: fn(db: self ref Dbf): Datum;
nextkey: fn(db: self ref Dbf, key: Datum): Datum;
flush: fn(db: self ref Dbf);
isrdonly: fn(db: self ref Dbf): int;
};
init: fn();
DESCRIPTION
Dbm maintains key/content pairs in a data base. The functions will
handle very large (a billion blocks) databases and will access a keyed
item in one or two filesystem accesses.
Keys and contents are both represented by arrays of bytes (with the
synonym Datum), allowing arbitrary binary values.
The data base is stored in two files. One file is a directory contain‐
ing a bit map and has as its suffix. The second file contains all data
and has as its suffix. An application can access several databases at
once, but must avoid concurrent operations on any one database (eg, by
using a monitor process to control access).
Init must be called before any other operation of the module.
A database is created by Dbf.create, which accepts a file permission
parameter perm, as described for Sys->create (see sys-open(2)); it cre‐
ates the two files file.dir and file.pag. If successful, it returns a
Dbf reference describing the database, which is open for reading and
writing. (It will truncate an existing database.) It returns nil if
it cannot create the database for some reason, and sets the error
string.
Dbf.open accepts a mode parameter as described in sys-open(2), and
opens the existing database in file.dir and file.pag. If successful,
it returns a Dbf reference describing the database, which is open
either for reading and writing (ie, Sys->ORDWR), or only for reading
(Sys->OREAD) as determined by mode. It returns nil if the database
cannot be opened successfully, and sets the error string.
The remaining operations apply to an existing Dbf reference db:
db.fetch(key)
Return the data stored under a key; nil is returned if the key
is not in the database.
db.store(key, data, replace)
Store data under the given key. If replace is non-zero, store
will simply replace the existing value by the new one if the key
is already in the database; if replace is zero store will return
0 if the new item was inserted, but 1 if the key already appears
in the database, and the new value will not be stored.
db.delete(key)
Key and its associated value is removed from the database.
db.firstkey()
Return the first key in the database; return nil if the database
is empty.
db.nextkey(key)
Return the key following the given key, or nil if there is none.
db.flush()
Discard any data cached from the file. The cache is write-
through, so it is not necessary to flush the file before the
application exits.
db.isrdonly()
Return true if db was opened only for reading and writes are not
allowed.
EXAMPLE
A linear pass through all keys in a database may be made, in an (appar‐
ently) random order, by use of Dbf.firstkey and Dbf.nextkey. This code
will traverse the data base:
for(key := db.firstkey(); key != nil; key = db.nextkey(key)){
d := db.fetch(key);
}
The order of keys presented by Dbf.firstkey and Dbf.nextkey depends on
a hashing function, not on anything interesting.
SOURCE
/appl/lib/dbm.b
DIAGNOSTICS
All functions that return an int indicate errors with negative values.
A zero return indicates success. Routines that return pointers,
including values of Datum, return nil values on error. Dbf.create and
Dbf.open return nil on failure to access the database, setting the
error string to a more detailed diagnostic.
BUGS
On some systems (notably Plan 9 but also some Unix systems), the .pag
file might contain holes where no data block has ever been written so
that its apparent size is about four times its actual content. These
files cannot be copied by normal means (cp, cat) without filling in the
holes.
Except for firstkey and nextkey, Datum values returned by these func‐
tions point to storage that is changed by subsequent calls.
The sum of the sizes of a key/content pair must not exceed the internal
block size (currently 512 bytes). Moreover all key/content pairs that
hash together must fit on a single block. Dbf.store will return an
error in the event that a block fills with inseparable data.
DBM(2)