static char sccsid
[] = "@(#)ndbm.c 4.4 (Berkeley) %G%";
static datum
firsthash();
dbm_open(file
, flags
, mode
)
if ((db
= (DBM
*)malloc(sizeof *db
)) == 0) {
db
->dbm_flags
= (flags
& 03) == O_RDONLY
? _DBM_RDONLY
: 0;
if ((flags
& 03) == O_WRONLY
)
flags
= (flags
& ~03) | O_RDWR
;
strcpy(db
->dbm_pagbuf
, file
);
strcat(db
->dbm_pagbuf
, ".pag");
db
->dbm_pagf
= open(db
->dbm_pagbuf
, flags
, mode
);
strcpy(db
->dbm_pagbuf
, file
);
strcat(db
->dbm_pagbuf
, ".dir");
db
->dbm_dirf
= open(db
->dbm_pagbuf
, flags
, mode
);
fstat(db
->dbm_dirf
, &statb
);
db
->dbm_maxbno
= statb
.st_size
*BYTESIZ
-1;
db
->dbm_pagbno
= db
->dbm_dirbno
= -1;
(void) close(db
->dbm_pagf
);
(void) close(db
->dbm_dirf
);
(void) close(db
->dbm_pagf
);
for (db
->dbm_hmask
=0;; db
->dbm_hmask
=(db
->dbm_hmask
<<1)+1) {
db
->dbm_blkno
= hash
& db
->dbm_hmask
;
db
->dbm_bitno
= db
->dbm_blkno
+ db
->dbm_hmask
;
dbm_access(db
, dcalchash(key
));
item
= makdatum(db
->dbm_pagbuf
, i
);
if (cmpdatum(key
, item
) == 0) {
item
= makdatum(db
->dbm_pagbuf
, i
+1);
fprintf(stderr
, "dbm: items not in pairs\n");
dbm_access(db
, dcalchash(key
));
item
= makdatum(db
->dbm_pagbuf
, i
);
if (cmpdatum(key
, item
) == 0) {
if (!delitem(db
->dbm_pagbuf
, i
) ||
!delitem(db
->dbm_pagbuf
, i
))
db
->dbm_flags
|= _DBM_IOERR
;
db
->dbm_pagbno
= db
->dbm_blkno
;
(void) lseek(db
->dbm_pagf
, db
->dbm_blkno
*PBLKSIZ
, L_SET
);
if (write(db
->dbm_pagf
, db
->dbm_pagbuf
, PBLKSIZ
) != PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
dbm_store(db
, key
, dat
, replace
)
dbm_access(db
, dcalchash(key
));
item
= makdatum(db
->dbm_pagbuf
, i
);
if (cmpdatum(key
, item
) == 0) {
if (!delitem(db
->dbm_pagbuf
, i
) ||
!delitem(db
->dbm_pagbuf
, i
)) {
db
->dbm_flags
|= _DBM_IOERR
;
if (!additem(db
->dbm_pagbuf
, key
))
if (!additem(db
->dbm_pagbuf
, dat
)) {
/* special case of delitem() expanded inline here */
((short *) db
->dbm_pagbuf
)[0]--;
db
->dbm_pagbno
= db
->dbm_blkno
;
(void) lseek(db
->dbm_pagf
, db
->dbm_blkno
*PBLKSIZ
, L_SET
);
if (write(db
->dbm_pagf
, db
->dbm_pagbuf
, PBLKSIZ
) != PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
if (key
.dsize
+dat
.dsize
+2*sizeof(short) >= PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
item
= makdatum(db
->dbm_pagbuf
, i
);
if (dcalchash(item
) & (db
->dbm_hmask
+1)) {
if (!additem(ovfbuf
, item
) ||
!delitem(db
->dbm_pagbuf
, i
)) {
db
->dbm_flags
|= _DBM_IOERR
;
item
= makdatum(db
->dbm_pagbuf
, i
);
fprintf(stderr
, "ndbm: split not paired\n");
db
->dbm_flags
|= _DBM_IOERR
;
if (!additem(ovfbuf
, item
) ||
!delitem(db
->dbm_pagbuf
, i
)) {
db
->dbm_flags
|= _DBM_IOERR
;
db
->dbm_pagbno
= db
->dbm_blkno
;
(void) lseek(db
->dbm_pagf
, db
->dbm_blkno
*PBLKSIZ
, L_SET
);
if (write(db
->dbm_pagf
, db
->dbm_pagbuf
, PBLKSIZ
) != PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
(void) lseek(db
->dbm_pagf
, (db
->dbm_blkno
+db
->dbm_hmask
+1)*PBLKSIZ
, L_SET
);
if (write(db
->dbm_pagf
, ovfbuf
, PBLKSIZ
) != PBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
return (firsthash(db
, 0L));
dbm_access(db
, hash
= dcalchash(key
));
item
= makdatum(db
->dbm_pagbuf
, i
);
if (cmpdatum(key
, item
) <= 0)
if (f
|| cmpdatum(bitem
, item
) < 0) {
hash
= hashinc(db
, hash
);
return (firsthash(db
, hash
));
bitem
= makdatum(db
->dbm_pagbuf
, 0);
item
= makdatum(db
->dbm_pagbuf
, i
);
if (cmpdatum(bitem
, item
) < 0)
hash
= hashinc(db
, hash
);
for (db
->dbm_hmask
=0;; db
->dbm_hmask
=(db
->dbm_hmask
<<1)+1) {
db
->dbm_blkno
= hash
& db
->dbm_hmask
;
db
->dbm_bitno
= db
->dbm_blkno
+ db
->dbm_hmask
;
if (db
->dbm_blkno
!= db
->dbm_pagbno
) {
db
->dbm_pagbno
= db
->dbm_blkno
;
(void) lseek(db
->dbm_pagf
, db
->dbm_blkno
*PBLKSIZ
, L_SET
);
if (read(db
->dbm_pagf
, db
->dbm_pagbuf
, PBLKSIZ
) != PBLKSIZ
)
bzero(db
->dbm_pagbuf
, PBLKSIZ
);
else if (chkblk(db
->dbm_pagbuf
) < 0)
db
->dbm_flags
|= _DBM_IOERR
;
if (db
->dbm_bitno
> db
->dbm_maxbno
)
n
= db
->dbm_bitno
% BYTESIZ
;
bn
= db
->dbm_bitno
/ BYTESIZ
;
if (b
!= db
->dbm_dirbno
) {
(void) lseek(db
->dbm_dirf
, (long)b
*DBLKSIZ
, L_SET
);
if (read(db
->dbm_dirf
, db
->dbm_dirbuf
, DBLKSIZ
) != DBLKSIZ
)
bzero(db
->dbm_dirbuf
, DBLKSIZ
);
if (db
->dbm_dirbuf
[i
] & (1<<n
))
if (db
->dbm_bitno
> db
->dbm_maxbno
) {
db
->dbm_maxbno
= db
->dbm_bitno
;
n
= db
->dbm_bitno
% BYTESIZ
;
bn
= db
->dbm_bitno
/ BYTESIZ
;
db
->dbm_dirbuf
[i
] |= 1<<n
;
(void) lseek(db
->dbm_dirf
, (long)b
*DBLKSIZ
, L_SET
);
if (write(db
->dbm_dirf
, db
->dbm_dirbuf
, DBLKSIZ
) != DBLKSIZ
) {
db
->dbm_flags
|= _DBM_IOERR
;
if (n
< 0 || n
>= sp
[0]) {
item
.dsize
= t
- sp
[n
+1];
055,043,036,054,063,014,004,005,
010,064,077,000,035,027,025,071,
= { 61, 57, 53, 49, 45, 41, 37, 33,
29, 25, 21, 17, 13, 9, 5, 1,
06100151277L,06106161736L,06452611562L,05001724107L,
02614772546L,04120731531L,04665262210L,07347467531L,
06735253126L,06042345173L,03072226605L,01464164730L,
03247435524L,07652510057L,01546775256L,05714532133L,
06173260402L,07517101630L,02431460343L,01743245566L,
00261675137L,02433103631L,03421772437L,04447707466L,
04435620103L,03757017115L,03641531772L,06767633246L,
02673230344L,00260612216L,04133454451L,00615531516L,
06137717526L,02574116560L,02304023373L,07061702261L,
05153031405L,05322056705L,07401116734L,06552375715L,
06165233473L,05311063631L,01212221723L,01052267235L,
06000615237L,01075222665L,06330216006L,04402355630L,
01451177262L,02000133436L,06025467062L,07121076461L,
03123433522L,01010635225L,01716177066L,05161746527L,
01736635071L,06243505026L,03637211610L,01756474365L,
04723077174L,03642763134L,05750130273L,03655541561L,
for (cp
= item
.dptr
, s
=item
.dsize
; --s
>= 0; ) {
for (j
=0; j
<BYTESIZ
; j
+=4) {
hashl
+= hltab
[hashi
&63];
register short *sp
, *sp1
;
bcopy(&buf
[i2
], &buf
[i2
+ i1
], sp
[n
+1] - i2
);
for (sp1
= sp
+ sp
[0]--, sp
+= n
+1; sp
< sp1
; sp
++)
i2
= (i2
+2) * sizeof(short);
bcopy(item
.dptr
, &buf
[i1
], item
.dsize
);
for (i
=0; i
<sp
[0]; i
++) {
if (t
< (sp
[0]+1)*sizeof(short))