/*
* sdbm - ndbm work-alike hashed database library
* based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
* author: oz@nexus.yorku.ca
* status: public domain.
*
* core routines
*/
#include "INTERN.h"
#include "config.h"
#ifdef WIN32
#include "io.h"
#endif
#include "sdbm.h"
#include "tune.h"
#include "pair.h"
#ifdef I_FCNTL
# include <fcntl.h>
#endif
#ifdef I_SYS_FILE
#endif
#ifdef I_STRING
# ifndef __ultrix__
# include <string.h>
# endif
#else
# include <strings.h>
#endif
/*
* externals
*/
#ifndef WIN32
#ifndef sun
extern int errno;
#endif
#endif
/*
* forward
*/
/*
* useful macros
*/
static long masks[] = {
000000000000, 000000000001, 000000000003, 000000000007,
000000000017, 000000000037, 000000000077, 000000000177,
000000000377, 000000000777, 000000001777, 000000003777,
000000007777, 000000017777, 000000037777, 000000077777,
000000177777, 000000377777, 000000777777, 000001777777,
000003777777, 000007777777, 000017777777, 000037777777,
000077777777, 000177777777, 000377777777, 000777777777,
001777777777, 003777777777, 007777777777, 017777777777
};
DBM *
{
register char *dirname;
register char *pagname;
register int n;
/*
* need space for two seperate filenames
*/
/*
* build the file names
*/
return db;
}
DBM *
{
/*
* adjust user flags so that WRONLY becomes RDWR,
* as required by this package. Also set our internal
* flag for RDONLY if needed.
*/
/*
* open the files in sequence, and stat the dirfile.
* If we fail anywhere, undo everything, return NULL.
*/
# endif
/*
* need the dirfile size to establish max bit number.
*/
/*
* zero size: either a fresh database, or one with a single,
* unsplit data page: dirpage is all zeros.
*/
/*
* success
*/
return db;
}
}
}
}
void
{
else {
}
}
{
}
int
{
}
int
{
if (sdbm_rdonly(db))
return -1;
/*
* update the page file
*/
return 0;
}
}
int
{
int need;
register long hash;
if (sdbm_rdonly(db))
/*
* is the pair too big (or too small) for this database ??
*/
/*
* first. If it is not there, ignore.
*/
if (flags == DBM_REPLACE)
#ifdef SEEDUPS
return 1;
#endif
/*
* if we do not have enough room, we have to split.
*/
/*
* we have enough room or split is successful. insert the key,
* and update the page file.
*/
/*
* success
*/
return 0;
}
}
/*
* makroom - make room by splitting the overfull page
* this routine will attempt to make room for SPLTMAX times before
* giving up.
*/
static int
{
long newp;
long oldtail;
#endif
do {
/*
* split the current page
*/
/*
* address of the new page
*/
/*
* select the page for incoming pair: if key is to go to the new page,
* write out the previous one, and copy the new one over, thus making
* it the current page. If not, simply write the new page, and we are
* still looking at the page of interest. current page is not updated
* here, as sdbm_store will do so, after it inserts the incoming pair.
*/
/*
* Fill hole with 0 if made it.
* (hole is NOT read as 0)
*/
return 0;
}
}
#endif
return 0;
}
return 0;
return 0;
/*
* see if we have enough room now
*/
return 1;
/*
* try again... update curbit and hmask as getpage would have
* done. because of our update of the current page, we do not
* need to read in anything. BUT we have to write the current
* [deferred] page out, as the window of failure is too great.
*/
return 0;
} while (--smax);
/*
* if we are here, this is real bad news. After SPLTMAX splits,
* we still cannot fit the key. say goodnight.
*/
#ifdef BADMESS
#endif
return 0;
}
/*
* the following two routines will break if
* deletions aren't taken into account. (ndbm bug)
*/
{
/*
* start at page 0
*/
}
{
}
/*
* all important binary trie traversal
*/
static int
{
register int hbit;
register long dbit;
register long pagb;
dbit = 0;
hbit = 0;
/*
* see if the block we need is already in memory.
* note: this lookaside cache has about 10% hit rate.
*/
/*
* note: here, we assume a "hole" is read as 0s.
* if not, must zero pagbuf first.
*/
return 0;
return 0;
}
return 1;
}
static int
{
register long c;
register long dirb;
int got;
return 0;
if (got==0)
}
}
static int
{
register long c;
register long dirb;
int got;
return 0;
if (got==0)
}
#if 0
#else
#endif
return 0;
return 1;
}
/*
* getnext - get the next key in the page, and if done with
* the page, try the next page in sequence
*/
static datum
{
for (;;) {
return key;
/*
* we either run out, or there is nothing on this page..
* try the next one... If we lost our position on the
* file, we will have to seek.
*/
break;
break;
break;
}
}