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