Blame


1 d957951b 2005-02-11 devnull #include <u.h>
2 d957951b 2005-02-11 devnull #include <libc.h>
3 d957951b 2005-02-11 devnull #include <bio.h>
4 d957951b 2005-02-11 devnull #include <ndb.h>
5 d957951b 2005-02-11 devnull
6 d957951b 2005-02-11 devnull /*
7 d957951b 2005-02-11 devnull * make the hash table completely in memory and then write as a file
8 d957951b 2005-02-11 devnull */
9 d957951b 2005-02-11 devnull
10 d957951b 2005-02-11 devnull uchar *ht;
11 d957951b 2005-02-11 devnull ulong hlen;
12 d957951b 2005-02-11 devnull Ndb *db;
13 d957951b 2005-02-11 devnull ulong nextchain;
14 d957951b 2005-02-11 devnull
15 d957951b 2005-02-11 devnull char*
16 d957951b 2005-02-11 devnull syserr(void)
17 d957951b 2005-02-11 devnull {
18 d957951b 2005-02-11 devnull static char buf[ERRMAX];
19 d957951b 2005-02-11 devnull
20 d957951b 2005-02-11 devnull errstr(buf, sizeof buf);
21 d957951b 2005-02-11 devnull return buf;
22 d957951b 2005-02-11 devnull }
23 d957951b 2005-02-11 devnull
24 d957951b 2005-02-11 devnull void
25 d957951b 2005-02-11 devnull enter(char *val, ulong dboff)
26 d957951b 2005-02-11 devnull {
27 d957951b 2005-02-11 devnull ulong h;
28 d957951b 2005-02-11 devnull uchar *last;
29 d957951b 2005-02-11 devnull ulong ptr;
30 d957951b 2005-02-11 devnull
31 d957951b 2005-02-11 devnull h = ndbhash(val, hlen);
32 d957951b 2005-02-11 devnull h *= NDBPLEN;
33 d957951b 2005-02-11 devnull last = &ht[h];
34 d957951b 2005-02-11 devnull ptr = NDBGETP(last);
35 d957951b 2005-02-11 devnull if(ptr == NDBNAP){
36 d957951b 2005-02-11 devnull NDBPUTP(dboff, last);
37 d957951b 2005-02-11 devnull return;
38 d957951b 2005-02-11 devnull }
39 d957951b 2005-02-11 devnull
40 d957951b 2005-02-11 devnull if(ptr & NDBCHAIN){
41 d957951b 2005-02-11 devnull /* walk the chain to the last entry */
42 d957951b 2005-02-11 devnull for(;;){
43 d957951b 2005-02-11 devnull ptr &= ~NDBCHAIN;
44 d957951b 2005-02-11 devnull last = &ht[ptr+NDBPLEN];
45 d957951b 2005-02-11 devnull ptr = NDBGETP(last);
46 d957951b 2005-02-11 devnull if(ptr == NDBNAP){
47 d957951b 2005-02-11 devnull NDBPUTP(dboff, last);
48 d957951b 2005-02-11 devnull return;
49 d957951b 2005-02-11 devnull }
50 d957951b 2005-02-11 devnull if(!(ptr & NDBCHAIN)){
51 d957951b 2005-02-11 devnull NDBPUTP(nextchain|NDBCHAIN, last);
52 d957951b 2005-02-11 devnull break;
53 d957951b 2005-02-11 devnull }
54 d957951b 2005-02-11 devnull }
55 d957951b 2005-02-11 devnull } else
56 d957951b 2005-02-11 devnull NDBPUTP(nextchain|NDBCHAIN, last);
57 d957951b 2005-02-11 devnull
58 d957951b 2005-02-11 devnull /* add a chained entry */
59 d957951b 2005-02-11 devnull NDBPUTP(ptr, &ht[nextchain]);
60 d957951b 2005-02-11 devnull NDBPUTP(dboff, &ht[nextchain + NDBPLEN]);
61 d957951b 2005-02-11 devnull nextchain += 2*NDBPLEN;
62 d957951b 2005-02-11 devnull }
63 d957951b 2005-02-11 devnull
64 d957951b 2005-02-11 devnull uchar nbuf[16*1024];
65 d957951b 2005-02-11 devnull
66 d957951b 2005-02-11 devnull void
67 d957951b 2005-02-11 devnull main(int argc, char **argv)
68 d957951b 2005-02-11 devnull {
69 d957951b 2005-02-11 devnull Ndbtuple *t, *nt;
70 d957951b 2005-02-11 devnull int n;
71 fa325e9b 2020-01-10 cross Dir *d;
72 d957951b 2005-02-11 devnull uchar buf[8];
73 d957951b 2005-02-11 devnull char file[128];
74 d957951b 2005-02-11 devnull int fd;
75 d957951b 2005-02-11 devnull ulong off;
76 d957951b 2005-02-11 devnull uchar *p;
77 d957951b 2005-02-11 devnull
78 d957951b 2005-02-11 devnull if(argc != 3){
79 d957951b 2005-02-11 devnull fprint(2, "mkhash: usage file attribute\n");
80 d957951b 2005-02-11 devnull exits("usage");
81 d957951b 2005-02-11 devnull }
82 d957951b 2005-02-11 devnull db = ndbopen(argv[1]);
83 d957951b 2005-02-11 devnull if(db == 0){
84 d957951b 2005-02-11 devnull fprint(2, "mkhash: can't open %s\n", argv[1]);
85 d957951b 2005-02-11 devnull exits(syserr());
86 d957951b 2005-02-11 devnull }
87 d957951b 2005-02-11 devnull
88 d957951b 2005-02-11 devnull /* try a bigger than normal buffer */
89 d957951b 2005-02-11 devnull Binits(&db->b, Bfildes(&db->b), OREAD, nbuf, sizeof(nbuf));
90 d957951b 2005-02-11 devnull
91 d957951b 2005-02-11 devnull /* count entries to calculate hash size */
92 d957951b 2005-02-11 devnull n = 0;
93 d957951b 2005-02-11 devnull
94 d957951b 2005-02-11 devnull while(nt = ndbparse(db)){
95 d957951b 2005-02-11 devnull for(t = nt; t; t = t->entry){
96 d957951b 2005-02-11 devnull if(strcmp(t->attr, argv[2]) == 0)
97 d957951b 2005-02-11 devnull n++;
98 d957951b 2005-02-11 devnull }
99 d957951b 2005-02-11 devnull ndbfree(nt);
100 d957951b 2005-02-11 devnull }
101 d957951b 2005-02-11 devnull
102 d957951b 2005-02-11 devnull /* allocate an array large enough for worst case */
103 d957951b 2005-02-11 devnull hlen = 2*n+1;
104 d957951b 2005-02-11 devnull n = hlen*NDBPLEN + hlen*2*NDBPLEN;
105 d957951b 2005-02-11 devnull ht = mallocz(n, 1);
106 d957951b 2005-02-11 devnull if(ht == 0){
107 d957951b 2005-02-11 devnull fprint(2, "mkhash: not enough memory\n");
108 d957951b 2005-02-11 devnull exits(syserr());
109 d957951b 2005-02-11 devnull }
110 d957951b 2005-02-11 devnull for(p = ht; p < &ht[n]; p += NDBPLEN)
111 d957951b 2005-02-11 devnull NDBPUTP(NDBNAP, p);
112 d957951b 2005-02-11 devnull nextchain = hlen*NDBPLEN;
113 d957951b 2005-02-11 devnull
114 d957951b 2005-02-11 devnull /* create the in core hash table */
115 d957951b 2005-02-11 devnull Bseek(&db->b, 0, 0);
116 d957951b 2005-02-11 devnull off = 0;
117 d957951b 2005-02-11 devnull while(nt = ndbparse(db)){
118 d957951b 2005-02-11 devnull for(t = nt; t; t = t->entry){
119 d957951b 2005-02-11 devnull if(strcmp(t->attr, argv[2]) == 0)
120 d957951b 2005-02-11 devnull enter(t->val, off);
121 d957951b 2005-02-11 devnull }
122 d957951b 2005-02-11 devnull ndbfree(nt);
123 d957951b 2005-02-11 devnull off = Boffset(&db->b);
124 d957951b 2005-02-11 devnull }
125 d957951b 2005-02-11 devnull
126 d957951b 2005-02-11 devnull /* create the hash file */
127 d957951b 2005-02-11 devnull snprint(file, sizeof(file), "%s.%s", argv[1], argv[2]);
128 d957951b 2005-02-11 devnull fd = create(file, ORDWR, 0664);
129 d957951b 2005-02-11 devnull if(fd < 0){
130 d957951b 2005-02-11 devnull fprint(2, "mkhash: can't create %s\n", file);
131 d957951b 2005-02-11 devnull exits(syserr());
132 d957951b 2005-02-11 devnull }
133 d957951b 2005-02-11 devnull NDBPUTUL(db->mtime, buf);
134 d957951b 2005-02-11 devnull NDBPUTUL(hlen, buf+NDBULLEN);
135 d957951b 2005-02-11 devnull if(write(fd, buf, NDBHLEN) != NDBHLEN){
136 d957951b 2005-02-11 devnull fprint(2, "mkhash: writing %s\n", file);
137 d957951b 2005-02-11 devnull exits(syserr());
138 d957951b 2005-02-11 devnull }
139 d957951b 2005-02-11 devnull if(write(fd, ht, nextchain) != nextchain){
140 d957951b 2005-02-11 devnull fprint(2, "mkhash: writing %s\n", file);
141 d957951b 2005-02-11 devnull exits(syserr());
142 d957951b 2005-02-11 devnull }
143 d957951b 2005-02-11 devnull close(fd);
144 d957951b 2005-02-11 devnull
145 d957951b 2005-02-11 devnull /* make sure file didn't change while we were making the hash */
146 d957951b 2005-02-11 devnull d = dirstat(argv[1]);
147 d957951b 2005-02-11 devnull if(d == nil || d->qid.path != db->qid.path
148 d957951b 2005-02-11 devnull || d->qid.vers != db->qid.vers){
149 d957951b 2005-02-11 devnull fprint(2, "mkhash: %s changed underfoot\n", argv[1]);
150 d957951b 2005-02-11 devnull remove(file);
151 d957951b 2005-02-11 devnull exits("changed");
152 d957951b 2005-02-11 devnull }
153 d957951b 2005-02-11 devnull
154 d957951b 2005-02-11 devnull exits(0);
155 d957951b 2005-02-11 devnull }