Next: , Previous: , Up: Top   [Contents][Index]


9 Sequential access to records

The next two functions allow for accessing all items in the database. This access is not key sequential, but it is guaranteed to visit every key in the database once. The order has to do with the hash values. gdbm_firstkey starts the visit of all keys in the database. gdbm_nextkey finds and reads the next entry in the hash structure for dbf.

gdbm interface: datum gdbm_firstkey (GDBM_FILE dbf)

Initiate sequential access to the database dbf. The returned value is the first key accessed in the database. If the dptr field in the returned datum is NULL, inspect the gdbm_errno variable (see gdbm_errno). The value of GDBM_ITEM_NOT_FOUND means that the database contains no data. Other value means an error occurred.

On success, dptr points to a memory block obtained from malloc, which holds the key value. The caller is responsible for freeing this memory block when no longer needed.

gdbm interface: datum gdbm_nextkey (GDBM_FILE dbf, datum prev)

This function continues iteration over the keys in dbf, initiated by gdbm_firstkey. The parameter prev holds the value returned from a previous call to gdbm_nextkey or gdbm_firstkey.

The function returns next key from the database. If the dptr field in the returned datum is NULL inspect the gdbm_errno variable (see gdbm_errno). The value of GDBM_ITEM_NOT_FOUND means that all keys in the database has been visited. Any other value means an error occurred.

Otherwise, dptr points to a memory block obtained from malloc, which holds the key value. The caller is responsible for freeing this memory block when no longer needed.

These functions are intended to visit the database in read-only algorithms, for instance, to validate the database or similar operations. The usual algorithm for sequential access is:

   key = gdbm_firstkey (dbf);
   while (key.dptr)
     {
        datum nextkey;

        /* do something with the key */
        ...

        /* Obtain the next key */
        nextkey = gdbm_nextkey (dbf, key);
        /* Reclaim the memory used by the key */
        free (key.dptr);
        /* Use nextkey in the next iteration. */
        key = nextkey;
     }

Don’t use gdbm_delete or gdbm_store in such a loop. File visiting is based on a hash table. The gdbm_delete function re-arranges the hash table to make sure that any collisions in the table do not leave some item un-findable. The original key order is not guaranteed to remain unchanged in all instances. So it is possible that some key will not be visited or will be visited twice, if a loop like the following is executed:

   key = gdbm_firstkey (dbf);
   while (key.dptr)
     {
        datum nextkey;
        if (some condition)
          {
             gdbm_delete (dbf, key);
          }
         nextkey = gdbm_nextkey (dbf, key);
         free (key.dptr);
         key = nextkey;
      }

Next: , Previous: , Up: Top   [Contents][Index]