1*37da2899SCharles.Forsythimplement Dbm; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsyth# Copyright © Caldera International Inc. 2001-2002. All rights reserved. 4*37da2899SCharles.Forsyth# Limbo transliteration (with amendment) Copyright © 2004 Vita Nuova Holdings Limited. 5*37da2899SCharles.Forsyth 6*37da2899SCharles.Forsythinclude "sys.m"; 7*37da2899SCharles.Forsyth sys: Sys; 8*37da2899SCharles.Forsyth OREAD, OWRITE, ORDWR: import Sys; 9*37da2899SCharles.Forsyth 10*37da2899SCharles.Forsythinclude "dbm.m"; 11*37da2899SCharles.Forsyth 12*37da2899SCharles.ForsythBYTESIZ: con 8; # bits 13*37da2899SCharles.ForsythSHORTSIZ: con 2; # bytes 14*37da2899SCharles.Forsyth 15*37da2899SCharles.ForsythPBLKSIZ: con 512; 16*37da2899SCharles.ForsythDBLKSIZ: con 8192; # was 4096 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsythinit() 19*37da2899SCharles.Forsyth{ 20*37da2899SCharles.Forsyth sys = load Sys Sys->PATH; 21*37da2899SCharles.Forsyth} 22*37da2899SCharles.Forsyth 23*37da2899SCharles.ForsythDbf.create(file: string, mode: int): ref Dbf 24*37da2899SCharles.Forsyth{ 25*37da2899SCharles.Forsyth pf := sys->create(file+".pag", ORDWR, mode); 26*37da2899SCharles.Forsyth if(pf == nil) 27*37da2899SCharles.Forsyth return nil; 28*37da2899SCharles.Forsyth df := sys->create(file+".dir", ORDWR, mode); 29*37da2899SCharles.Forsyth if(df == nil) 30*37da2899SCharles.Forsyth return nil; 31*37da2899SCharles.Forsyth return alloc(pf, df, ORDWR); 32*37da2899SCharles.Forsyth} 33*37da2899SCharles.Forsyth 34*37da2899SCharles.ForsythDbf.open(file: string, flags: int): ref Dbf 35*37da2899SCharles.Forsyth{ 36*37da2899SCharles.Forsyth if((flags & 3) == OWRITE) 37*37da2899SCharles.Forsyth flags = (flags & ~3) | ORDWR; 38*37da2899SCharles.Forsyth pf := sys->open(file+".pag", flags); 39*37da2899SCharles.Forsyth if(pf == nil) 40*37da2899SCharles.Forsyth return nil; 41*37da2899SCharles.Forsyth df := sys->open(file+".dir", flags); 42*37da2899SCharles.Forsyth if(df == nil) 43*37da2899SCharles.Forsyth return nil; 44*37da2899SCharles.Forsyth return alloc(pf, df, flags); 45*37da2899SCharles.Forsyth} 46*37da2899SCharles.Forsyth 47*37da2899SCharles.Forsythalloc(pf: ref Sys->FD, df: ref Sys->FD, flags: int): ref Dbf 48*37da2899SCharles.Forsyth{ 49*37da2899SCharles.Forsyth db := ref Dbf; 50*37da2899SCharles.Forsyth db.pagf = pf; 51*37da2899SCharles.Forsyth db.dirf = df; 52*37da2899SCharles.Forsyth db.flags = flags & 3; 53*37da2899SCharles.Forsyth db.maxbno = 0; 54*37da2899SCharles.Forsyth db.bitno = 0; 55*37da2899SCharles.Forsyth db.hmask = 0; 56*37da2899SCharles.Forsyth db.blkno = 0; 57*37da2899SCharles.Forsyth db.pagbno = -1; 58*37da2899SCharles.Forsyth db.pagbuf = array[PBLKSIZ] of byte; 59*37da2899SCharles.Forsyth db.dirbno = -1; 60*37da2899SCharles.Forsyth db.dirbuf = array[DBLKSIZ] of byte; 61*37da2899SCharles.Forsyth (ok, d) := sys->fstat(db.dirf); 62*37da2899SCharles.Forsyth if(ok < 0) 63*37da2899SCharles.Forsyth d.length = big 0; 64*37da2899SCharles.Forsyth db.maxbno = int (d.length*big BYTESIZ - big 1); 65*37da2899SCharles.Forsyth return db; 66*37da2899SCharles.Forsyth} 67*37da2899SCharles.Forsyth 68*37da2899SCharles.ForsythDbf.flush(db: self ref Dbf) 69*37da2899SCharles.Forsyth{ 70*37da2899SCharles.Forsyth db.pagbno = db.dirbno = -1; 71*37da2899SCharles.Forsyth} 72*37da2899SCharles.Forsyth 73*37da2899SCharles.ForsythDbf.isrdonly(db: self ref Dbf): int 74*37da2899SCharles.Forsyth{ 75*37da2899SCharles.Forsyth return db.flags == OREAD; 76*37da2899SCharles.Forsyth} 77*37da2899SCharles.Forsyth 78*37da2899SCharles.ForsythDbf.fetch(db: self ref Dbf, key: Datum): Datum 79*37da2899SCharles.Forsyth{ 80*37da2899SCharles.Forsyth access(db, calchash(key)); 81*37da2899SCharles.Forsyth for(i:=0;; i+=2){ 82*37da2899SCharles.Forsyth item := makdatum(db.pagbuf, i); 83*37da2899SCharles.Forsyth if(item == nil) 84*37da2899SCharles.Forsyth return item; 85*37da2899SCharles.Forsyth if(cmpdatum(key, item) == 0){ 86*37da2899SCharles.Forsyth item = makdatum(db.pagbuf, i+1); 87*37da2899SCharles.Forsyth if(item == nil){ 88*37da2899SCharles.Forsyth sys->fprint(sys->fildes(2), "dbm: items not in pairs\n"); 89*37da2899SCharles.Forsyth raise "dbm: items not in pairs"; 90*37da2899SCharles.Forsyth } 91*37da2899SCharles.Forsyth return item; 92*37da2899SCharles.Forsyth } 93*37da2899SCharles.Forsyth } 94*37da2899SCharles.Forsyth} 95*37da2899SCharles.Forsyth 96*37da2899SCharles.ForsythDbf.delete(db: self ref Dbf, key: Datum): int 97*37da2899SCharles.Forsyth{ 98*37da2899SCharles.Forsyth if(db.isrdonly()) 99*37da2899SCharles.Forsyth return -1; 100*37da2899SCharles.Forsyth access(db, calchash(key)); 101*37da2899SCharles.Forsyth for(i:=0;; i+=2){ 102*37da2899SCharles.Forsyth item := makdatum(db.pagbuf, i); 103*37da2899SCharles.Forsyth if(item == nil) 104*37da2899SCharles.Forsyth return -1; 105*37da2899SCharles.Forsyth if(cmpdatum(key, item) == 0){ 106*37da2899SCharles.Forsyth delitem(db.pagbuf, i); 107*37da2899SCharles.Forsyth delitem(db.pagbuf, i); 108*37da2899SCharles.Forsyth break; 109*37da2899SCharles.Forsyth } 110*37da2899SCharles.Forsyth } 111*37da2899SCharles.Forsyth sys->seek(db.pagf, big db.blkno*big PBLKSIZ, 0); 112*37da2899SCharles.Forsyth write(db.pagf, db.pagbuf, PBLKSIZ); 113*37da2899SCharles.Forsyth db.pagbno = db.blkno; 114*37da2899SCharles.Forsyth return 0; 115*37da2899SCharles.Forsyth} 116*37da2899SCharles.Forsyth 117*37da2899SCharles.ForsythDbf.store(db: self ref Dbf, key: Datum, dat: Datum, replace: int): int 118*37da2899SCharles.Forsyth{ 119*37da2899SCharles.Forsyth if(db.isrdonly()) 120*37da2899SCharles.Forsyth return -1; 121*37da2899SCharles.Forsyth for(;;){ 122*37da2899SCharles.Forsyth access(db, calchash(key)); 123*37da2899SCharles.Forsyth for(i:=0;; i+=2){ 124*37da2899SCharles.Forsyth item := makdatum(db.pagbuf, i); 125*37da2899SCharles.Forsyth if(item == nil) 126*37da2899SCharles.Forsyth break; 127*37da2899SCharles.Forsyth if(cmpdatum(key, item) == 0){ 128*37da2899SCharles.Forsyth if(!replace) 129*37da2899SCharles.Forsyth return 1; 130*37da2899SCharles.Forsyth delitem(db.pagbuf, i); 131*37da2899SCharles.Forsyth delitem(db.pagbuf, i); 132*37da2899SCharles.Forsyth break; 133*37da2899SCharles.Forsyth } 134*37da2899SCharles.Forsyth } 135*37da2899SCharles.Forsyth i = additem(db.pagbuf, key); 136*37da2899SCharles.Forsyth if(i >= 0){ 137*37da2899SCharles.Forsyth if(additem(db.pagbuf, dat) >= 0) 138*37da2899SCharles.Forsyth break; 139*37da2899SCharles.Forsyth delitem(db.pagbuf, i); 140*37da2899SCharles.Forsyth } 141*37da2899SCharles.Forsyth if(!split(db, key, dat)) 142*37da2899SCharles.Forsyth return -1; 143*37da2899SCharles.Forsyth } 144*37da2899SCharles.Forsyth sys->seek(db.pagf, big db.blkno*big PBLKSIZ, 0); 145*37da2899SCharles.Forsyth write(db.pagf, db.pagbuf, PBLKSIZ); 146*37da2899SCharles.Forsyth db.pagbno = db.blkno; 147*37da2899SCharles.Forsyth return 0; 148*37da2899SCharles.Forsyth} 149*37da2899SCharles.Forsyth 150*37da2899SCharles.Forsythsplit(db: ref Dbf, key: Datum, dat: Datum): int 151*37da2899SCharles.Forsyth{ 152*37da2899SCharles.Forsyth if(len key+len dat+3*SHORTSIZ >= PBLKSIZ) 153*37da2899SCharles.Forsyth return 0; 154*37da2899SCharles.Forsyth ovfbuf := array[PBLKSIZ] of {* => byte 0}; 155*37da2899SCharles.Forsyth for(i:=0;;){ 156*37da2899SCharles.Forsyth item := makdatum(db.pagbuf, i); 157*37da2899SCharles.Forsyth if(item == nil) 158*37da2899SCharles.Forsyth break; 159*37da2899SCharles.Forsyth if(calchash(item) & (db.hmask+1)){ 160*37da2899SCharles.Forsyth additem(ovfbuf, item); 161*37da2899SCharles.Forsyth delitem(db.pagbuf, i); 162*37da2899SCharles.Forsyth item = makdatum(db.pagbuf, i); 163*37da2899SCharles.Forsyth if(item == nil){ 164*37da2899SCharles.Forsyth sys->fprint(sys->fildes(2), "dbm: split not paired\n"); 165*37da2899SCharles.Forsyth raise "dbm: split not paired"; 166*37da2899SCharles.Forsyth #break; 167*37da2899SCharles.Forsyth } 168*37da2899SCharles.Forsyth additem(ovfbuf, item); 169*37da2899SCharles.Forsyth delitem(db.pagbuf, i); 170*37da2899SCharles.Forsyth continue; 171*37da2899SCharles.Forsyth } 172*37da2899SCharles.Forsyth i += 2; 173*37da2899SCharles.Forsyth } 174*37da2899SCharles.Forsyth sys->seek(db.pagf, big db.blkno*big PBLKSIZ, 0); 175*37da2899SCharles.Forsyth write(db.pagf, db.pagbuf, PBLKSIZ); 176*37da2899SCharles.Forsyth db.pagbno = db.blkno; 177*37da2899SCharles.Forsyth sys->seek(db.pagf, (big db.blkno+big db.hmask+big 1)*big PBLKSIZ, 0); 178*37da2899SCharles.Forsyth write(db.pagf, ovfbuf, PBLKSIZ); 179*37da2899SCharles.Forsyth setbit(db); 180*37da2899SCharles.Forsyth return 1; 181*37da2899SCharles.Forsyth} 182*37da2899SCharles.Forsyth 183*37da2899SCharles.ForsythDbf.firstkey(db: self ref Dbf): Datum 184*37da2899SCharles.Forsyth{ 185*37da2899SCharles.Forsyth return copy(firsthash(db, 0)); 186*37da2899SCharles.Forsyth} 187*37da2899SCharles.Forsyth 188*37da2899SCharles.ForsythDbf.nextkey(db: self ref Dbf, key: Datum): Datum 189*37da2899SCharles.Forsyth{ 190*37da2899SCharles.Forsyth hash := calchash(key); 191*37da2899SCharles.Forsyth access(db, hash); 192*37da2899SCharles.Forsyth item, bitem: Datum; 193*37da2899SCharles.Forsyth for(i:=0;; i+=2){ 194*37da2899SCharles.Forsyth item = makdatum(db.pagbuf, i); 195*37da2899SCharles.Forsyth if(item == nil) 196*37da2899SCharles.Forsyth break; 197*37da2899SCharles.Forsyth if(cmpdatum(key, item) <= 0) 198*37da2899SCharles.Forsyth continue; 199*37da2899SCharles.Forsyth if(bitem == nil || cmpdatum(bitem, item) < 0) 200*37da2899SCharles.Forsyth bitem = item; 201*37da2899SCharles.Forsyth } 202*37da2899SCharles.Forsyth if(bitem != nil) 203*37da2899SCharles.Forsyth return copy(bitem); 204*37da2899SCharles.Forsyth hash = hashinc(db, hash); 205*37da2899SCharles.Forsyth if(hash == 0) 206*37da2899SCharles.Forsyth return copy(item); 207*37da2899SCharles.Forsyth return copy(firsthash(db, hash)); 208*37da2899SCharles.Forsyth} 209*37da2899SCharles.Forsyth 210*37da2899SCharles.Forsythfirsthash(db: ref Dbf, hash: int): Datum 211*37da2899SCharles.Forsyth{ 212*37da2899SCharles.Forsyth for(;;){ 213*37da2899SCharles.Forsyth access(db, hash); 214*37da2899SCharles.Forsyth bitem := makdatum(db.pagbuf, 0); 215*37da2899SCharles.Forsyth item: Datum; 216*37da2899SCharles.Forsyth for(i:=2;; i+=2){ 217*37da2899SCharles.Forsyth item = makdatum(db.pagbuf, i); 218*37da2899SCharles.Forsyth if(item == nil) 219*37da2899SCharles.Forsyth break; 220*37da2899SCharles.Forsyth if(cmpdatum(bitem, item) < 0) 221*37da2899SCharles.Forsyth bitem = item; 222*37da2899SCharles.Forsyth } 223*37da2899SCharles.Forsyth if(bitem != nil) 224*37da2899SCharles.Forsyth return bitem; 225*37da2899SCharles.Forsyth hash = hashinc(db, hash); 226*37da2899SCharles.Forsyth if(hash == 0) 227*37da2899SCharles.Forsyth return item; 228*37da2899SCharles.Forsyth } 229*37da2899SCharles.Forsyth} 230*37da2899SCharles.Forsyth 231*37da2899SCharles.Forsythaccess(db: ref Dbf, hash: int) 232*37da2899SCharles.Forsyth{ 233*37da2899SCharles.Forsyth for(db.hmask=0;; db.hmask=(db.hmask<<1)+1){ 234*37da2899SCharles.Forsyth db.blkno = hash & db.hmask; 235*37da2899SCharles.Forsyth db.bitno = db.blkno + db.hmask; 236*37da2899SCharles.Forsyth if(getbit(db) == 0) 237*37da2899SCharles.Forsyth break; 238*37da2899SCharles.Forsyth } 239*37da2899SCharles.Forsyth if(db.blkno != db.pagbno){ 240*37da2899SCharles.Forsyth sys->seek(db.pagf, big db.blkno * big PBLKSIZ, 0); 241*37da2899SCharles.Forsyth read(db.pagf, db.pagbuf, PBLKSIZ); 242*37da2899SCharles.Forsyth chkblk(db.pagbuf); 243*37da2899SCharles.Forsyth db.pagbno = db.blkno; 244*37da2899SCharles.Forsyth } 245*37da2899SCharles.Forsyth} 246*37da2899SCharles.Forsyth 247*37da2899SCharles.Forsythgetbit(db: ref Dbf): int 248*37da2899SCharles.Forsyth{ 249*37da2899SCharles.Forsyth if(db.bitno > db.maxbno) 250*37da2899SCharles.Forsyth return 0; 251*37da2899SCharles.Forsyth n := db.bitno % BYTESIZ; 252*37da2899SCharles.Forsyth bn := db.bitno / BYTESIZ; 253*37da2899SCharles.Forsyth i := bn % DBLKSIZ; 254*37da2899SCharles.Forsyth b := bn / DBLKSIZ; 255*37da2899SCharles.Forsyth if(b != db.dirbno){ 256*37da2899SCharles.Forsyth sys->seek(db.dirf, big b * big DBLKSIZ, 0); 257*37da2899SCharles.Forsyth read(db.dirf, db.dirbuf, DBLKSIZ); 258*37da2899SCharles.Forsyth db.dirbno = b; 259*37da2899SCharles.Forsyth } 260*37da2899SCharles.Forsyth if(int db.dirbuf[i] & (1<<n)) 261*37da2899SCharles.Forsyth return 1; 262*37da2899SCharles.Forsyth return 0; 263*37da2899SCharles.Forsyth} 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsythsetbit(db: ref Dbf) 266*37da2899SCharles.Forsyth{ 267*37da2899SCharles.Forsyth if(db.bitno > db.maxbno){ 268*37da2899SCharles.Forsyth db.maxbno = db.bitno; 269*37da2899SCharles.Forsyth getbit(db); 270*37da2899SCharles.Forsyth } 271*37da2899SCharles.Forsyth n := db.bitno % BYTESIZ; 272*37da2899SCharles.Forsyth bn := db.bitno / BYTESIZ; 273*37da2899SCharles.Forsyth i := bn % DBLKSIZ; 274*37da2899SCharles.Forsyth b := bn / DBLKSIZ; 275*37da2899SCharles.Forsyth db.dirbuf[i] |= byte (1<<n); 276*37da2899SCharles.Forsyth sys->seek(db.dirf, big b * big DBLKSIZ, 0); 277*37da2899SCharles.Forsyth write(db.dirf, db.dirbuf, DBLKSIZ); 278*37da2899SCharles.Forsyth db.dirbno = b; 279*37da2899SCharles.Forsyth} 280*37da2899SCharles.Forsyth 281*37da2899SCharles.Forsythmakdatum(buf: array of byte, n: int): Datum 282*37da2899SCharles.Forsyth{ 283*37da2899SCharles.Forsyth ne := GETS(buf, 0); 284*37da2899SCharles.Forsyth if(n < 0 || n >= ne) 285*37da2899SCharles.Forsyth return nil; 286*37da2899SCharles.Forsyth t := PBLKSIZ; 287*37da2899SCharles.Forsyth if(n > 0) 288*37da2899SCharles.Forsyth t = GETS(buf, n+1-1); 289*37da2899SCharles.Forsyth v := GETS(buf, n+1); 290*37da2899SCharles.Forsyth return buf[v: t]; # size is t-v 291*37da2899SCharles.Forsyth} 292*37da2899SCharles.Forsyth 293*37da2899SCharles.Forsythcmpdatum(d1: Datum, d2: Datum): int 294*37da2899SCharles.Forsyth{ 295*37da2899SCharles.Forsyth n := len d1; 296*37da2899SCharles.Forsyth if(n != len d2) 297*37da2899SCharles.Forsyth return n - len d2; 298*37da2899SCharles.Forsyth if(n == 0) 299*37da2899SCharles.Forsyth return 0; 300*37da2899SCharles.Forsyth for(i := 0; i < len d1; i++) 301*37da2899SCharles.Forsyth if(d1[i] != d2[i]) 302*37da2899SCharles.Forsyth return int d1[i] - int d2[i]; 303*37da2899SCharles.Forsyth return 0; 304*37da2899SCharles.Forsyth} 305*37da2899SCharles.Forsyth 306*37da2899SCharles.Forsythcopy(d: Datum): Datum 307*37da2899SCharles.Forsyth{ 308*37da2899SCharles.Forsyth if(d == nil) 309*37da2899SCharles.Forsyth return nil; 310*37da2899SCharles.Forsyth a := array[len d] of byte; 311*37da2899SCharles.Forsyth a[0:] = d; 312*37da2899SCharles.Forsyth return a; 313*37da2899SCharles.Forsyth} 314*37da2899SCharles.Forsyth 315*37da2899SCharles.Forsyth# ken's 316*37da2899SCharles.Forsyth# 317*37da2899SCharles.Forsyth# 055,043,036,054,063,014,004,005, 318*37da2899SCharles.Forsyth# 010,064,077,000,035,027,025,071, 319*37da2899SCharles.Forsyth# 320*37da2899SCharles.Forsyth 321*37da2899SCharles.Forsythhitab := array[16] of { 322*37da2899SCharles.Forsyth 61, 57, 53, 49, 45, 41, 37, 33, 323*37da2899SCharles.Forsyth 29, 25, 21, 17, 13, 9, 5, 1, 324*37da2899SCharles.Forsyth}; 325*37da2899SCharles.Forsyth 326*37da2899SCharles.Forsythhltab := array[64] of { 327*37da2899SCharles.Forsyth 8r6100151277,8r6106161736,8r6452611562,8r5001724107, 328*37da2899SCharles.Forsyth 8r2614772546,8r4120731531,8r4665262210,8r7347467531, 329*37da2899SCharles.Forsyth 8r6735253126,8r6042345173,8r3072226605,8r1464164730, 330*37da2899SCharles.Forsyth 8r3247435524,8r7652510057,8r1546775256,8r5714532133, 331*37da2899SCharles.Forsyth 8r6173260402,8r7517101630,8r2431460343,8r1743245566, 332*37da2899SCharles.Forsyth 8r0261675137,8r2433103631,8r3421772437,8r4447707466, 333*37da2899SCharles.Forsyth 8r4435620103,8r3757017115,8r3641531772,8r6767633246, 334*37da2899SCharles.Forsyth 8r2673230344,8r0260612216,8r4133454451,8r0615531516, 335*37da2899SCharles.Forsyth 8r6137717526,8r2574116560,8r2304023373,8r7061702261, 336*37da2899SCharles.Forsyth 8r5153031405,8r5322056705,8r7401116734,8r6552375715, 337*37da2899SCharles.Forsyth 8r6165233473,8r5311063631,8r1212221723,8r1052267235, 338*37da2899SCharles.Forsyth 8r6000615237,8r1075222665,8r6330216006,8r4402355630, 339*37da2899SCharles.Forsyth 8r1451177262,8r2000133436,8r6025467062,8r7121076461, 340*37da2899SCharles.Forsyth 8r3123433522,8r1010635225,8r1716177066,8r5161746527, 341*37da2899SCharles.Forsyth 8r1736635071,8r6243505026,8r3637211610,8r1756474365, 342*37da2899SCharles.Forsyth 8r4723077174,8r3642763134,8r5750130273,8r3655541561, 343*37da2899SCharles.Forsyth}; 344*37da2899SCharles.Forsyth 345*37da2899SCharles.Forsythhashinc(db: ref Dbf, hash: int): int 346*37da2899SCharles.Forsyth{ 347*37da2899SCharles.Forsyth hash &= db.hmask; 348*37da2899SCharles.Forsyth bit := db.hmask+1; 349*37da2899SCharles.Forsyth for(;;){ 350*37da2899SCharles.Forsyth bit >>= 1; 351*37da2899SCharles.Forsyth if(bit == 0) 352*37da2899SCharles.Forsyth return 0; 353*37da2899SCharles.Forsyth if((hash&bit) == 0) 354*37da2899SCharles.Forsyth return hash|bit; 355*37da2899SCharles.Forsyth hash &= ~bit; 356*37da2899SCharles.Forsyth } 357*37da2899SCharles.Forsyth} 358*37da2899SCharles.Forsyth 359*37da2899SCharles.Forsythcalchash(item: Datum): int 360*37da2899SCharles.Forsyth{ 361*37da2899SCharles.Forsyth hashl := 0; 362*37da2899SCharles.Forsyth hashi := 0; 363*37da2899SCharles.Forsyth for(i:=0; i<len item; i++){ 364*37da2899SCharles.Forsyth f := int item[i]; 365*37da2899SCharles.Forsyth for(j:=0; j<BYTESIZ; j+=4){ 366*37da2899SCharles.Forsyth hashi += hitab[f&16rF]; 367*37da2899SCharles.Forsyth hashl += hltab[hashi&16r3F]; 368*37da2899SCharles.Forsyth f >>= 4; 369*37da2899SCharles.Forsyth } 370*37da2899SCharles.Forsyth } 371*37da2899SCharles.Forsyth return hashl; 372*37da2899SCharles.Forsyth} 373*37da2899SCharles.Forsyth 374*37da2899SCharles.Forsythdelitem(buf: array of byte, n: int) 375*37da2899SCharles.Forsyth{ 376*37da2899SCharles.Forsyth ne := GETS(buf, 0); 377*37da2899SCharles.Forsyth if(n < 0 || n >= ne){ 378*37da2899SCharles.Forsyth sys->fprint(sys->fildes(2), "dbm: bad delitem\n"); 379*37da2899SCharles.Forsyth raise "dbm: bad delitem"; 380*37da2899SCharles.Forsyth } 381*37da2899SCharles.Forsyth i1 := GETS(buf, n+1); 382*37da2899SCharles.Forsyth i2 := PBLKSIZ; 383*37da2899SCharles.Forsyth if(n > 0) 384*37da2899SCharles.Forsyth i2 = GETS(buf, n+1-1); 385*37da2899SCharles.Forsyth i3 := GETS(buf, ne+1-1); 386*37da2899SCharles.Forsyth if(i2 > i1) 387*37da2899SCharles.Forsyth while(i1 > i3){ 388*37da2899SCharles.Forsyth i1--; 389*37da2899SCharles.Forsyth i2--; 390*37da2899SCharles.Forsyth buf[i2] = buf[i1]; 391*37da2899SCharles.Forsyth buf[i1] = byte 0; 392*37da2899SCharles.Forsyth } 393*37da2899SCharles.Forsyth i2 -= i1; 394*37da2899SCharles.Forsyth for(i1=n+1; i1<ne; i1++) 395*37da2899SCharles.Forsyth PUTS(buf, i1+1-1, GETS(buf, i1+1) + i2); 396*37da2899SCharles.Forsyth PUTS(buf, 0, ne-1); 397*37da2899SCharles.Forsyth PUTS(buf, ne, 0); 398*37da2899SCharles.Forsyth} 399*37da2899SCharles.Forsyth 400*37da2899SCharles.Forsythadditem(buf: array of byte, item: Datum): int 401*37da2899SCharles.Forsyth{ 402*37da2899SCharles.Forsyth i1 := PBLKSIZ; 403*37da2899SCharles.Forsyth ne := GETS(buf, 0); 404*37da2899SCharles.Forsyth if(ne > 0) 405*37da2899SCharles.Forsyth i1 = GETS(buf, ne+1-1); 406*37da2899SCharles.Forsyth i1 -= len item; 407*37da2899SCharles.Forsyth i2 := (ne+2) * SHORTSIZ; 408*37da2899SCharles.Forsyth if(i1 <= i2) 409*37da2899SCharles.Forsyth return -1; 410*37da2899SCharles.Forsyth PUTS(buf, ne+1, i1); 411*37da2899SCharles.Forsyth buf[i1:] = item; 412*37da2899SCharles.Forsyth PUTS(buf, 0, ne+1); 413*37da2899SCharles.Forsyth return ne; 414*37da2899SCharles.Forsyth} 415*37da2899SCharles.Forsyth 416*37da2899SCharles.Forsythchkblk(buf: array of byte) 417*37da2899SCharles.Forsyth{ 418*37da2899SCharles.Forsyth t := PBLKSIZ; 419*37da2899SCharles.Forsyth ne := GETS(buf, 0); 420*37da2899SCharles.Forsyth for(i:=0; i<ne; i++){ 421*37da2899SCharles.Forsyth v := GETS(buf, i+1); 422*37da2899SCharles.Forsyth if(v > t) 423*37da2899SCharles.Forsyth badblk(); 424*37da2899SCharles.Forsyth t = v; 425*37da2899SCharles.Forsyth } 426*37da2899SCharles.Forsyth if(t < (ne+1)*SHORTSIZ) 427*37da2899SCharles.Forsyth badblk(); 428*37da2899SCharles.Forsyth} 429*37da2899SCharles.Forsyth 430*37da2899SCharles.Forsythread(fd: ref Sys->FD, buf: array of byte, n: int) 431*37da2899SCharles.Forsyth{ 432*37da2899SCharles.Forsyth nr := sys->read(fd, buf, n); 433*37da2899SCharles.Forsyth if(nr == 0){ 434*37da2899SCharles.Forsyth for(i := 0; i < len buf; i++) 435*37da2899SCharles.Forsyth buf[i] = byte 0; 436*37da2899SCharles.Forsyth }else if(nr != n) 437*37da2899SCharles.Forsyth raise "dbm: read error: "+sys->sprint("%r"); 438*37da2899SCharles.Forsyth} 439*37da2899SCharles.Forsyth 440*37da2899SCharles.Forsythwrite(fd: ref Sys->FD, buf: array of byte, n: int) 441*37da2899SCharles.Forsyth{ 442*37da2899SCharles.Forsyth if(sys->write(fd, buf, n) != n) 443*37da2899SCharles.Forsyth raise "dbm: write error: "+sys->sprint("%r"); 444*37da2899SCharles.Forsyth} 445*37da2899SCharles.Forsyth 446*37da2899SCharles.Forsythbadblk() 447*37da2899SCharles.Forsyth{ 448*37da2899SCharles.Forsyth sys->fprint(sys->fildes(2), "dbm: bad block\n"); 449*37da2899SCharles.Forsyth raise "dbm: bad block"; 450*37da2899SCharles.Forsyth} 451*37da2899SCharles.Forsyth 452*37da2899SCharles.ForsythGETS(buf: array of byte, sh: int): int 453*37da2899SCharles.Forsyth{ 454*37da2899SCharles.Forsyth sh *= SHORTSIZ; 455*37da2899SCharles.Forsyth return (int buf[sh]<<8) | int buf[sh+1]; 456*37da2899SCharles.Forsyth} 457*37da2899SCharles.Forsyth 458*37da2899SCharles.ForsythPUTS(buf: array of byte, sh: int, v: int) 459*37da2899SCharles.Forsyth{ 460*37da2899SCharles.Forsyth sh *= SHORTSIZ; 461*37da2899SCharles.Forsyth buf[sh] = byte (v>>8); 462*37da2899SCharles.Forsyth buf[sh+1] = byte v; 463*37da2899SCharles.Forsyth} 464