dbm/ndbm notes and some code.
Chris Torek
chris at mimsy.UUCP
Sat May 13 00:49:50 AEST 1989
>In article <1889 at yunexus.UUCP> oz at yunexus.UUCP (Ozan Yigit) writes:
>>This is where the "database traversal" turns into a pumpkin. Because of
>>internal caching of the key position for dbm_nextkey (dbm_keyptr ??),
>>which is appearently NOT adjusted for deletions, this traversal will never
>>display the key right after the one just deleted. Workaround is to save
>>all keys to be deleted, then perform all deletions once the sequential
>>traversal is complete.
In article <6847 at cbmvax.UUCP> grr at cbmvax.UUCP (George Robbins) writes:
>Say what? Where are you going to save this potentially unbounded list of
>to be deleted keys? Surely there is a better solution???
Indeed there is. dbm_nextkey does not cache the key position. Rather,
what is going on is that the dptr of the key returned by dbm_nextkey
points into a private region of memory (one holding a page from the .pag
file) which is modified by the dbm_delete operation. This effectively
changes the text of the key (in a predictable manner, but which requires
knowing the current contents of the .pag page) so that the next
dbm_nextkey does not fetch the key following the one just deleted.
If all you are going to do is delete the just-found <key,datum>
pair, it suffices to save the contents of the key:
newspace = malloc(key.dsize);
if (newspace == NULL) ... error ...
memcpy(newspace, key.dptr, key.dsize);
key.dptr = newspace;
dbm_delete(...);
key = dbm_nextkey(key);
free(newspace);
You must not, however, do a dbm_store, which could completely
discombobulate the current order of the database (by splitting).
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at mimsy.umd.edu Path: uunet!mimsy!chris
More information about the Comp.unix.wizards
mailing list