From 37da2899f40661e3e9631e497da8dc59b971cbd0 Mon Sep 17 00:00:00 2001 From: "Charles.Forsyth" Date: Fri, 22 Dec 2006 17:07:39 +0000 Subject: 20060303a --- appl/cmd/ndb/mkhash.b | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 appl/cmd/ndb/mkhash.b (limited to 'appl/cmd/ndb/mkhash.b') diff --git a/appl/cmd/ndb/mkhash.b b/appl/cmd/ndb/mkhash.b new file mode 100644 index 00000000..f1876355 --- /dev/null +++ b/appl/cmd/ndb/mkhash.b @@ -0,0 +1,119 @@ +implement Mkhash; + +# +# for compatibility, this is closely modelled on Plan 9's ndb/mkhash +# + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "bufio.m"; +include "attrdb.m"; + attrdb: Attrdb; + Db, Dbf, Dbentry, Tuples, Attr: import attrdb; + attrhash: Attrhash; + NDBPLEN, NDBHLEN, NDBCHAIN, NDBNAP: import Attrhash; + +Mkhash: module +{ + init: fn(nil: ref Draw->Context, nil: list of string); +}; + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + attrdb = load Attrdb Attrdb->PATH; + if(attrdb == nil) + error(sys->sprint("can't load %s: %r", Attrdb->PATH)); + attrdb->init(); + attrhash = load Attrhash Attrhash->PATH; + if(attrhash == nil) + error(sys->sprint("can't load %s: %r", Attrhash->PATH)); + + if(len args != 3) + error("usage: mkhash file attr"); + args = tl args; + dbname := hd args; + args = tl args; + attr := hd args; + dbf := Dbf.open(dbname); + if(dbf == nil) + error(sys->sprint("can't open %s: %r", dbname)); + offset := 0; + n := 0; + for(;;){ + (e, nil, next) := dbf.readentry(offset, nil, nil, 0); + if(e == nil) + break; + m := len e.find(attr); + if(0 && m != 0) + sys->fprint(sys->fildes(2), "%ud [%d]\n", offset, m); + n += m; + offset = next; + } + hlen := 2*n+1; + chains := n*2*NDBPLEN; + file := array[NDBHLEN + hlen*NDBPLEN + chains] of byte; + tab := file[NDBHLEN:]; + for(i:=0; icreate(hashfile, Sys->OWRITE, 8r666); + if(hfd == nil) + error(sys->sprint("can't create %s: %r", hashfile)); + mtime := 0; + if(dbf.dir != nil) + mtime = dbf.dir.mtime; + put4(file, mtime); + put4(file[4:], hlen); + if(sys->write(hfd, file, NDBHLEN+chain) != NDBHLEN+chain) + error(sys->sprint("error writing %s: %r", hashfile)); +} + +error(s: string) +{ + sys->fprint(sys->fildes(2), "mkhash: %s\n", s); + raise "fail:error"; +} + +enter(tab: array of byte, a: ref Attr, hlen: int, chain: int, offset: int): int +{ + o := attrhash->hash(a.val, hlen)*NDBPLEN; + for(; (p := attrhash->get3(tab[o:])) != NDBNAP; o = p & ~NDBCHAIN) + if((p & NDBCHAIN) == 0){ + put3(tab[o:], chain | NDBCHAIN); + put3(tab[chain:], p); + put3(tab[chain+NDBPLEN:], offset); + return chain+2*NDBPLEN; + } + put3(tab[o:], offset); + return chain; +} + +put3(a: array of byte, v: int) +{ + a[0] = byte v; + a[1] = byte (v>>8); + a[2] = byte (v>>16); +} + +put4(a: array of byte, v: int) +{ + a[0] = byte v; + a[1] = byte (v>>8); + a[2] = byte (v>>16); + a[3] = byte (v>>24); +} -- cgit v1.2.3