14 #include "ruby/config.h"
32 #define SEEK_SET L_SET
33 #define memset(s,c,n) bzero((s), (n))
34 #define memcpy(s1,s2,n) bcopy((s2), (s1), (n))
35 #define memcmp(s1,s2,n) bcmp((s1),(s2),(n))
54 #define debug(x) printf x
60 #define GET_SHORT(p, i) (((unsigned)((unsigned char *)(p))[(i)*2] << 8) + (((unsigned char *)(p))[(i)*2 + 1]))
61 #define PUT_SHORT(p, i, s) (((unsigned char *)(p))[(i)*2] = (unsigned char)((s) >> 8), ((unsigned char *)(p))[(i)*2 + 1] = (unsigned char)(s))
63 #define GET_SHORT(p, i) ((p)[(i)])
64 #define PUT_SHORT(p, i, s) ((p)[(i)] = (s))
84 #include <sys/types.h>
113 #if !defined sun && !defined _WIN32 && !defined __CYGWIN__ && !defined(errno)
129 #define bad(x) ((x).dptr == NULL || (x).dsize < 0)
130 #define exhash(item) sdbm_hash((item).dptr, (item).dsize)
131 #define ioerr(db) ((db)->flags |= DBM_IOERR)
133 #define OFF_PAG(off) (long) (off) * PBLKSIZ
134 #define OFF_DIR(off) (long) (off) * DBLKSIZ
137 000000000000L, 000000000001L, 000000000003L,
138 000000000007L, 000000000017L, 000000000037L,
139 000000000077L, 000000000177L, 000000000377L,
140 000000000777L, 000000001777L, 000000003777L,
141 000000007777L, 000000017777L, 000000037777L,
142 000000077777L, 000000177777L, 000000377777L,
143 000000777777L, 000001777777L, 000003777777L,
144 000007777777L, 000017777777L, 000037777777L,
145 000077777777L, 000177777777L, 000377777777L,
146 000777777777L, 001777777777L, 003777777777L,
147 007777777777L, 017777777777L
153 sdbm_open(
register char *file,
register int flags,
register int mode)
156 register char *dirname;
157 register char *pagname;
160 if (file ==
NULL || !*file)
161 return errno = EINVAL, (
DBM *)
NULL;
168 return errno = ENOMEM, (
DBM *)
NULL;
172 dirname = strcat(strcpy(dirname, file),
DIRFEXT);
173 pagname = strcpy(dirname +
strlen(dirname) + 1, file);
174 pagname = strcat(pagname,
PAGFEXT);
176 db =
sdbm_prep(dirname, pagname, flags, mode);
177 free((
char *) dirname);
182 sdbm_prep(
char *dirname,
char *pagname,
int flags,
int mode)
188 return errno = ENOMEM, (
DBM *)
NULL;
199 if (flags & O_WRONLY)
200 flags = (flags & ~O_WRONLY) | O_RDWR;
201 if (flags & O_RDONLY)
208 if ((db->
pagf = open(pagname, flags, mode)) > -1) {
209 if ((db->
dirf = open(dirname, flags, mode)) > -1) {
218 db->
dirbno = (!dstat.st_size) ? 0 : -1;
229 (void) close(db->
dirf);
231 (void) close(db->
pagf);
243 (void) close(db->
dirf);
244 (void) close(db->
pagf);
265 return errno = EINVAL, -1;
267 return errno =
EPERM, -1;
277 return ioerr(db), -1;
282 return ioerr(db), -1;
292 return errno = EINVAL, -1;
294 return errno =
EPERM, -1;
300 if (need < 0 || need >
PAIRMAX)
301 return errno = EINVAL, -1;
319 return ioerr(db), -1;
328 return ioerr(db), -1;
335 return ioerr(db), -1;
348 #if defined _WIN32 && !defined __CYGWIN__
365 debug((
"newp: %ld\n", newp));
375 #if defined _WIN32 && !defined __CYGWIN__
382 while (
OFF_PAG(newp) > oldtail) {
392 if (hash & (db->
hmask + 1)) {
397 (void) memcpy(pag,
new,
PBLKSIZ);
417 ((hash & (db->
hmask + 1)) ? 2 : 1);
430 (void) (write(2,
"sdbm: cannot insert after SPLTMAX attempts.\n", 44) < 0);
479 while (dbit < db->maxbno &&
getdbit(db, dbit))
480 dbit = 2 * dbit + ((hash & ((
long) 1 << hbit++)) ? 2 : 1);
482 debug((
"dbit: %d...", dbit));
485 db->
hmask = masks[hbit];
487 pagb = hash & db->
hmask;
507 debug((
"pag read: %d\n", pagb));
527 debug((
"dir read: %d\n", dirb));
548 debug((
"dir read: %d\n", dirb));
615 #define exhash(item) sdbm_hash((item).dptr, (item).dsize)
648 register short *ino = (
short *) pag;
651 free = off - (n + 1) *
sizeof(
short);
652 need += 2 *
sizeof(short);
654 debug((
"free %d need %d\n", free, need));
664 register short *ino = (
short *) pag;
672 (void) memcpy(pag + off, key.
dptr, key.
dsize);
679 (void) memcpy(pag + off, val.
dptr, val.
dsize);
693 register short *ino = (
short *) pag;
710 register short *ino = (
short *) pag;
721 register short *ino = (
short *) pag;
740 register short *ino = (
short *) pag;
757 register char *src = pag +
GET_SHORT(ino,i + 1);
758 register ptrdiff_t zoo = dst - src;
766 #define MOVB *--dst = *--src
769 register int loop = (m + 8 - 1) >> 3;
771 switch (m & (8 - 1)) {
774 case 6: MOVB;
case 5: MOVB;
775 case 4: MOVB;
case 3: MOVB;
776 case 2: MOVB;
case 1: MOVB;
806 seepair(
char *pag,
register int n,
register char *
key,
register int siz)
810 register short *ino = (
short *) pag;
812 for (i = 1; i < n; i += 2) {
830 register short *ino = (
short *) cur;
832 (void) memcpy(cur, pag,
PBLKSIZ);
833 (void) memset(pag, 0,
PBLKSIZ);
834 (void) memset(
new, 0,
PBLKSIZ);
837 for (ino++; n > 0; ino += 2) {
851 debug((
"%d split %d/%d\n", ((
short *) cur)[0] / 2,
852 ((
short *)
new)[0] / 2,
853 ((
short *) pag)[0] / 2));
867 register short *ino = (
short *) pag;
874 for (ino++; n > 0; ino += 2) {
905 register unsigned long n = 0;
909 #define HASHC n = *str++ + 65599 * n
912 register int loop = (len + 8 - 1) >> 3;
914 switch(len & (8 - 1)) {
916 HASHC;
case 7: HASHC;
917 case 6: HASHC;
case 5: HASHC;
918 case 4: HASHC;
case 3: HASHC;
919 case 2: HASHC;
case 1: HASHC;
926 n = ((*str++) & 255) + 65587L * n;
static int makroom(register DBM *db, long int hash, int need)
long sdbm_hash(register char *str, register int len)
size_t strlen(const char *)
static datum getnext(register DBM *db)
static int chkpage(char *pag)
static int duppair(char *pag, datum key)
static datum getpair(char *pag, datum key)
static int getpage(register DBM *db, register long int hash)
RUBY_EXTERN void * memmove(void *, const void *, size_t)
void sdbm_close(register DBM *db)
DBM * sdbm_open(register char *file, register int flags, register int mode)
static int seepair(char *pag, register int n, register char *key, register int siz)
datum sdbm_firstkey(register DBM *db)
DBM * sdbm_prep(char *dirname, char *pagname, int flags, int mode)
static void putpair(char *pag, datum key, datum val)
register unsigned int len
int memcmp(const void *s1, const void *s2, size_t len)
static int fitpair(char *pag, int need)
static int delpair(char *pag, datum key)
#define PUT_SHORT(p, i, s)
static int getdbit(register DBM *db, register long int dbit)
int sdbm_store(register DBM *db, datum key, datum val, int flags)
static void splpage(char *pag, char *new, long int sbit)
static unsigned int hash(const char *str, unsigned int len)
datum sdbm_nextkey(register DBM *db)
static int fitpair proto((char *, int))
static datum getnkey(char *pag, int num)
int sdbm_delete(register DBM *db, datum key)
datum sdbm_fetch(register DBM *db, datum key)
static int setdbit(register DBM *db, register long int dbit)