mdbm(3B)

mdbm: mdbm_open, mdbm_close, mdbm_fetch, mdbm_store, mdbm_delete, mdbm_first, mdbm_firstkey, mdbm_next, mdbm_nextkey, mdbm_pre_split, mdbm_set_alignment, mdbm_limit_size, mdbm_invalidate, mdbm_close_fd, mdbm_sync, mdbm_lock, mdbm_unlock, mdbm_sethash- data base subroutines

As shipped in IRIX 6.5. First release of IRIX 6.5.

NAME
     mdbm: mdbm_open, mdbm_close, mdbm_fetch, mdbm_store, mdbm_delete,
     mdbm_first, mdbm_firstkey, mdbm_next, mdbm_nextkey, mdbm_pre_split,
     mdbm_set_alignment, mdbm_limit_size, mdbm_invalidate, mdbm_close_fd,
     mdbm_sync, mdbm_lock, mdbm_unlock, mdbm_sethash- data base subroutines

SYNOPSIS
     cc [flag ...] file ...  -lmdbm [library ...]

     #include <mdbm.h>

     MDBM *mdbm_open(const char *file, int flags, mode_t mode, int pagesize);

     void mdbm_close(MDBM *db);

     datum mdbm_fetch(MDBM *db, kvpair kv);

     int mdbm_store(MDBM *db, datum key, datum content, int flags);

     int mdbm_delete(MDBM *db, datum key);

     kvpair mdbm_first(MDBM *db, kvpair kv);

     datum mdbm_firstkey(MDBM *db, datum key);

     kvpair mdbm_next(MDBM *db, kvpair kv);

     datum mdbm_nextkey(MDBM *db, datum key);

     int mdbm_pre_split(MDBM *db, uint64 pages, int

     int mdbm_set_alignment(MDBM *db, int power);

     int mdbm_limit_size(MDBM *db, uint64 pages, int (*func)(MDBM *db, datum
     key, datum content, void *priority));

     int mdbm_invalidate(MDBM *db);

     void mdbm_close_fd(MDBM *db);

     void mdbm_sync(MDBM *db);

     int mdbm_lock(MDBM *db);

     int mdbm_unlock(MDBM *db);

     int mdbm_sethash(MDBM *db, int number);

     int mdbm_set_chain(MDBM *db);

     datumt mdbm_chain_fetch(MDBM *db, kvpair kv);

     kvpair mdbm_chain_first(MDBM *db, kvpair kv);

     kvpair mdbm_chain_next(MDBM *db, kvpair kv);

     int mdbm_chain_store(MDBM *db, datum key, datum val, int flags);

     int mdbm_chain_delete(MDBM *db, datum key);

     int mdbm_bytes_per_page(MDBM *db, int *pages);

     int mdbm_elem_per_page(MDBM *db, int *pages);

DESCRIPTION
     The mdbm routines are used to store key/content pairs in a high
     performance mapped hash file.  It uses fixed size pages, but the page
     size can be set on first open.  The database does per page writer
     locking, and readers can detect and automaticly deal with writers.  This
     allows for scalable multiple simultaneous readers and writers to be
     operating on the same mdbm file at the same time.

     Core functions are bult into libc, the rest of them require linking with
     libmdbm.  The functions in libc are:  mdbm_close, mdbm_close_fd,
     mdbm_fetch, mdbm_first, mdbm_firstkey, mdbm_invalidate, mdbm_next,
     mdbm_nextkey, mdbm_open, mdbm_sethash, mdbm_store, mdbm_sync.

     Before a database can be accessed, it must be opened by mdbm_open.  This
     will open and/or create the given file depending on the flags patameter
     (see open(2)).  The pagesize parameter is a power of two between 8 (256
     bytes) and 16 (65536 bytes).

     Once open, the data stored under a key is accessed by mdbm_fetch . The
     kvpair argument must be setup as follows:

          typedef struct {
               char *dptr;
               int  dsize;
          } datum;
          typedef struct {
               datum key;
               datum val;
          } kvpair;

     kv.key.dptr should point to the key, and kv.key.dsize should be set to
     the length of the key.   kv.val.dptr should be set to allocated memory,
     which will be used to copy the result into.  kv.val.dsize should be the
     size of the data.   If kv.val.dptr is null, the returned datum's dsize
     will be the size of the key.   It is always save to allocate
     MDBM_PAGE_SIZE(db) bytes.
     A linear pass through all keys in a database may be made, in an
     (apparently) random order, by use of mdbm_firstkey (mdbm_first) and
     mdbm_nextkey(mdbm_next).  Mdbm_firstkey will return the first key
     (key/content) in the database.  Mdbm_nextkey will return the next key
     (key/content) in the database.  Space for both the key and the value must
     be allocated as above.  The following code will traverse the data base:

          int pagesize = MDBM_PAGE_SUZE(db);
          char *key = alloca(pagesize);
          char *val = alloca(pagesize);
          for (kv.key.dptr = key , kv.key.dsize=pagesize,
               kv.val.dptr = val, kv.val.dsize=pagesize,
               kv.key = mdbm_firstkey(db,kv);
               key.dptr != NULL;
               kv.key.dptr = key , kv.key.dsize=pagesize,
               kv.val.dptr = val, kv.val.dsize=pagesize,
               key = mdbm_nextkey(db,kv))


     Data is placed under a key by mdbm_store.  The flags field can be either
     MDBM_INSERT or MDBM_REPLACE. MDBM_INSERT will only insert new entries
     into the database and will not change an existing entry with the same
     key.  MDBM_REPLACE will replace an existing entry if it has the same key.
     A key (and its associated contents) is deleted by mdbm_delete.

     The mdbm_pre_split function can be used immediately after first open to
     expand the directory to a specified size.  This helps to reduce the
     number of pages that will be split when storing a large amount of data.
     The pages parameter is a power of two for the depth of the tree.

     The contents may be forced to exist at a particular byte alignment using
     mdbm_set_alignment so that you can store structures in the database.  The
     parameter is a power of two between 0 and 3.  The only time this is
     needed is when accessing non-copied data from a mdbm file.  This is not
     safe unless all access are protected by global.

     The flags field can be 0, or MDBM_ALLOC_SPACE. MDBM_ALLOC_SPACE attempts
     to pre-allocate blocks to back the file if it is on a holely filesystem.
     It will return -1 if it can not allocate the space.

     The mdbm_limit_size function can be used after first open to set a
     maximum size limit on the database.  If supplied func is a function which
     will be called with each item on a page if an item needs to be stored,
     but there is no space.  The priority argument is an integer between 1 and
     3 giving the pass number.  After three passes through the data, if space
     has not been freed the store will fail.

     Mdbm_sync simply forces the data to disk.  Since the database is a mapped
     file most work is simply done in memory, and the state of the disk file
     is only guarenteed after mdbm_sync.
     Mdbm_invalidate should be called to mark a mdbm file as invalid or
     outdated.  This should be done before unlinking the mdbm file.  If this
     is not done long running programs that may have the mdbm file open will
     not detect that another process has remove the file.

     If the database is a fixed size then the associated file descriptor can
     be closed using mdbm_close_fd.  Otherwise the database will grow the file
     and possibly remap it into memory as data is added.

     The routines mdbm_lock/mdbm_unlock can be used to syncronize access to an
     mdbm file.  These use a very unsophisticated spinlock in the shared file
     to do the locking.  It is almost always unecessary to use these
     functions.

     Mdbm_sethash will set the has function of a database to number.   This
     must be done immediately after creating the mdbm file.  The default hash
     is 0.

     0   32 bit CRC.

     1   ejb's hsearch hash.  Not recommended.

     2   Phong Vo's linear congruential hash.  Good for short keys.

     3   Ozan Yigit's sdbm hash.  Good for long keys.

     4   Torek's Duff device hash.  Good for ASCII key.  Bad for binary key.

     5   Fowler/Noll/Vo prime hash.  Very good keys under ~20 bytes.

     There are a number of function that allow storage of unlimited size
     values via mdbm.   These are the the mdbm_chain_* functions.   Before any
     keys are stored in a mdbm database, use the mdbm_set_chain routine to
     enable this feature in a given database.   Use mdbm_open and mdbm_close
     with a mdbm file that supports chaining.  When chaining is enabled, the
     first character of a key may NOT start with a NULL byte.   Also, it is
     impossible to get a pointer to the copy of the data in the database by
     passing a NULL value.  In this case the val.dsize field will be set the
     size needed to retrieve the data. Simultaneous replacement and fetching
     of a single key should not be done with chained data, and can return
     bogus values.

     The mdbm_chain_fetch, mdbm_chain_store, and mdbm_chain_delete behave
     similar to the non chaining versions.   The mdbm_chain_first and
     mdbm_chain_next do NOT return the value.  The kv.val should be NULL with
     a 0 length, and will be set to the size needed to copyout the data.

     The mdbm_bytes_per_page, and mdbm_elem_per_page take an pointer to array
     of length MDBM_NUMBER_PAGES(MDBM *db) which will be filled with the
     appropriate statistic.
DIAGNOSTICS
     All functions that return an int indicate errors with negative values.  A
     zero return indicates ok.  Routines that return a datum indicate errors
     with a null (0) dptr. If dbm_store called with a flags value of
     DBM_INSERT finds an existing entry with the same key it returns 1.

     If there is an error during an mdbm call, the global error value errno
     will be set.  The following errors will will be set.

     EDEADLK   A accessed page was locked, and after a number of attempts did
               not become unlocked.

     EBADFD    During the open of a database the file magic number was not
               valid.  File is not a recognised mdbm file.

     EBADF     During the open or access of a database the file version was
               not valid, or internal structures are invalid.  This implies
               that the mdbm file is corrupted.

     EINVAL    An invlid argument was passed.

     ENOEXIST  The requested key does not exist in the database.

     ENOMEM    Internal allocation of memory failed.  The only allocation that
               is performed is the MDBM structure that is returned by
               mdbm_open which is freed by mdbm_close.

     ENOSPC    There is insufficient space in the database to store the
               requested key.

     EPERM     Permission to perform a write to the mdbm file is denied.

     ESTALE    The mdbm file has been invalidated.  It is suggested that an
               attempt to re-open the database is made, since a writing
               process may invalidate a mdbm file, and create a new one with
               the same filename.

BUGS
     The file is designed to contain holes in files.  The EFS file system does
     not implement holes, so the file will frequently be significantly larger
     than the actual content.

     The sum of the sizes of a key/content pair must not exceed the internal
     block size (defaults to 4096 bytes).  Moreover all key/content pairs that
     hash together must fit on a single block.  The block size can be set to a
     maximum of 64KB on first open.  Mdbm_store will return an error in the
     event that a disk block fills with inseparable data.

     Mdbm_delete does not physically reclaim file space, although it does make
     it available for reuse.
     The order of keys presented by mdbm_first, mdbm_firstkey, mdbm_next and
     mdbm_nextkey depends on a hashing function, not on anything interesting.