DB(3)DB(3)NAMEdb - introduction to the hashed database library functions
SYNOPSIS
#include <db/db.h>
typedef struct {
char *s;
short n;
} Datum;
typedef struct {
Datum k, c;
} Data;
typedef struct {
char *name; /* the name of the database */
int flag; /* flag word - see bit defines in db.h */
int D, L; /* directory and leaf file descriptors */
} Database;
DESCRIPTION
These functions constitute the hashed database library, libdb. The
link editor searches this library under the "-ldb_p" or "-lsys_s"
options. Declarations for these functions may be obtained from the
include file <db/db.h>.
libdb implements extensibly hashed databases whose records are
arbitrary key/content pairs. The databases can be very large - on the
order of 500 million blocks. A single key/content pair is retrieved in
0, 1, or sometimes 2, disk accesses.
Sample code to open, read and write a database:
#include <db/db.h>
Database *db = dbOpen("x");
Data d;
char k[500], c[500];
d.k = StrDatum("foo");
d.c = StrDatum("bar");
if (! dbStore(db, &d))
dbError(...);
d.k = StrDatum("barbar");
if (dbFetch(db, &d))
printf("%s", d.c.s);
SUMMARY
Database *dbOpen(char *name)
Opens database name for access, creating the directory and leaf files
"name.[DL]" if they don't already exist. An open Database descriptor
is returned, or NULL if there was some failure.
int dbClose(Database *db)
Closes db, closing the directory and leaf files "name.[DL]", freeing up
memory used by db, and flushing any unwritten data to disk.
int dbStore(Database *db, Data *d)
Stores the key/content pair d in database db.
int dbFetch(Database *db, Data *d)
With the key portion d->k known, attempts to fill in the content
portion, d->c, from the database. Only the key portion, d->k, need be
specified.
int dbFind(Database *db, Data *d)
True if d->k is in db. Only the key portion, d->k, need be specified.
The sizes of both portions of the record are returned in d. dbGet()
may be called subsequently to read the contents.
int dbDelete(Database *db, Data *d)
Removes d from database db. Only the key portion, d->k, need be
specified.
int dbFirst(Database *db, Data *d)
Locates the first record in database db. The sizes of both portions of
the record are returned in d.
To traverse and print a database of string pairs:
Data d;
char k[1024], c[1024];
d.k.s = k;
d.c.s = c;
for (dbFirst(db, &d); dbGet(db, &d); dbNext(db, &d))
printf("%s: %s\n", k, c);
int dbGet(Database *db, Data *d)
Puts both the key and content portions of the current record in d.
dbGet() may be called following a call to dbFirst(), dbNext() or
dbFind().
int dbSetKey(Database *db, Data *d)
Puts the key portion and the size of the content portion of the current
record in d. dbSetKey() may be called following a call to dbFirst(),
dbNext() or dbFind(). dbSetKey() is useful for ascertaining the size
of the content portion before calling dbGet().
int dbNext(Database *db, Data *d)
Locates the next record in Database db. The sizes of both the key and
content portions of the record are returned in d. The order followed
by dbNext() is uninteresting, being determined by a hash function.
dbNext() fails when the end of the database is reached. See dbFirst().
int dbExists(char *name)
True if database name exists (ie, if directory and leaf files
``name.[DL]'' exist).
int dbCreate(char *name)
Creates directory and leaf files ``name.[DL]'' for a new database.
Both the directory and leaf files will be truncated (overwritten) if
they already exist. The default leaf size, dbLeafSize, will be LEAFSIZE
as defined in db.h unless set by the application to some other value.
All leaf sizes are rounded to the nearest larger magic number for
memory allocation.
Database * dbInit(char *name)
Prepares database name for use. The directory file, usually name.D,
and the leaf file, usually name.L, must already exist (they can be
created with dbCreate()). The directory and leaf files are opened for
access using the global variable dbFlags. If write access is requested
by dbFlags, but denied by the operating system, dnInit() will attempt
to open the files for reading only. The type of access acquired is
indicated by the dbFlagReadOnly bit in the descriptor flag word.
Returns the opened Database if successful, otherwise returns NULL.
int dbCompress(Database *db)
Compresses database db by removing all empty space from existing
blocks. A compressed database is readable only, and does not support
writing or deletion.
int dbExpand(Database *db)
Reverses the compression of database db performed by dbCompress(). An
expanded database supports writing and deletion.
int dbUnlink(char *name)
Unlinks (removes) ``name.[DL]'', the directory and leaf files
associated with database name.
void dbFlush(Database *db)
Writes any unwritten blocks to disk. Unwritten blocks are also written
by dbClose(). All leaf and directory writes are buffered if db->flag &
dbFlagBuffered. This is the default. Set db->flag &= ~dbFlagBuffered
after calling dbInit() or dbOpen() to make writes synchronous.
void dbSetCache(Database *db, short limit, int private)
dbSetCache() changes the open block cache used by database db. By
default, all open databases share a public cache.
If private is true, a private cache is established for db. The new
cache will hold at most limit blocks. Any private cache previously in
use by db is flushed and deallocated.
If private is false, db is returned to the public cache. Any private
cache previously in use by db is flushed and deallocated.
Any read of db following a call to dbSetCache() is guaranteed to be
synchronous. The number of blocks in the public cache is limited by
the global variable dbMaxLeafBuf.
int dbLock(Database *db)
Guarantees exclusive access to db by locking the leaf file with
flock(). May block indefinitely waiting for exclusive access.
int dbUnlock(Database *db)
Unlocks db.
int dbWaitLock(Database *db, count, unsigned pause)
Tries to lock db. Makes count attempts, trying forever if count < 0,
and waiting for pause seconds after each unsuccessful try. Returns 1
if db is successfully locked, otherwise 0.
For example, to try at most 5 times, pausing 3 seconds between
attempts:
if (! dbWaitLock(db, 5, 3))
fprintf(stderr, "Couldn't lock '%s'\n", db->name);
Datum StrDatum(char *s)
Constructs and returns a Datum from string s.
Data StrData(char *k, char *c)
Constructs and returns a Data pair from strings k and c.
Data dbData(Datum k, Datum c)
Constructs and returns a Data pair with key k and content c.
int dbPrint(Database *db, char *k, char *c)
Stores the key/content pair (k, c) in Database db.
int dbScan(Database *db, char *k, char *c)
Given key k, fetches the contents of the matching record from db and
puts them in c.
void dbCat(FILE *f, Database *db, int (*pfunc) ())
Catenates the contents of db on FILE f, calling the function pfunc(f,
data) for each key/content pair in the database. If pfunc is null,
dbPrintKC() is used by default.
void dbPrintKC(FILE *f, Data *d)
Prints the key/content pair d on stream f, separating the key from the
content by a tab. Both key and content are assumed to be strings.
int dbError(dbErrorType errno, char *fmt, args)
If the global variable dbErrors is zero, which it is by default,
dbError sets errno into the global variable dbErrorNo. dbErrorNo is
set reliably by every call to the library. If the global variable
dbErrors is non zero, dbError prints a diagnostic message to the FILE
dbMsgs, which is stderr by default. fmt and args are used as in
printf().
GLOBALS
char *dbDirExtension, *dbLeafExtension;
The leaf and directory file extensions, normally D and L by
default.
int dbErrors;
If true, error messages are printed. By default, error messages
are not printed.
int dbMaxLeafBuf;
Maximum number of open blocks in the public cache. See
dbSetCache().
int dbLeafSize;
Used by dbCreate() to set the block size for new databases. The
value of dbLeafSize is rounded to the nearest larger magic
number for memory allocation. The default is LEAFSIZE, as
defined in db.h.
int dbMode;
Sets the file creation mode used by dbCreate(). The default is
0644. The actual protection mode of a file created by
dbCreate() will be determined by the combination of dbMode and
the current umask.
int dbFlags;
Sets the file access flags used by dbInit(). The default, -1, is
ignored.
FILE *dbMsgs;
The file descriptor for error message output. The default is
stderr.
DIAGNOSTICS
Unless otherwise indicated, all functions return SUCCESS (1) or FAILURE
(0).
NeXT Computer, Inc. June 6, 1989 DB(3)