2 * Sherlock Library -- Object Buckets
4 * (c) 2001 Martin Mares <mj@ucw.cz>
6 * Warning: Touches internals of the fb-file module!
10 #include "lib/bucket.h"
11 #include "lib/fastbuf.h"
19 static struct fastbuf *obuck_fb;
20 static struct obuck_header obuck_hdr;
21 static sh_off_t start_of_this, start_of_next;
22 static char *obuck_name = "db/objects"; /* FIXME */
25 obuck_init(int writeable)
27 obuck_fb = bopen(obuck_name, (writeable ? O_RDWR | O_CREAT : O_RDONLY), 65536);
28 obuck_fd = obuck_fb->fd;
38 obuck_broken(char *msg)
40 die("Object pool corrupted: %s", msg); /* FIXME */
46 flock(obuck_fd, LOCK_SH);
50 obuck_lock_write(void)
52 flock(obuck_fd, LOCK_EX);
58 flock(obuck_fd, LOCK_UN);
62 obuck_fetch_header(oid_t oid)
64 start_of_this = ((sh_off_t) oid) << OBUCK_SHIFT;
65 bsetpos(obuck_fb, start_of_this);
66 bread(obuck_fb, &obuck_hdr, sizeof(obuck_hdr));
67 if (obuck_hdr.magic != OBUCK_MAGIC)
68 obuck_broken("Missing magic number");
69 if (obuck_hdr.oid == OBUCK_OID_DELETED)
70 obuck_broken("Access to deleted bucket");
71 if (obuck_hdr.oid != oid)
72 obuck_broken("Invalid backlink");
76 obuck_fetch(struct obuck_header *hdrp)
79 obuck_fetch_header(hdrp->oid);
80 memcpy(hdrp, &obuck_hdr, sizeof(obuck_hdr));
85 obuck_fetch_abort(struct fastbuf *b UNUSED)
91 obuck_fetch_end(struct fastbuf *b UNUSED)
93 if (bgetl(b) != OBUCK_TRAILER)
94 obuck_broken("Corrupted trailer");
102 bseek(obuck_fb, 0, SEEK_END);
103 start_of_this = btell(obuck_fb);
104 if (start_of_this & (OBUCK_ALIGN - 1))
105 obuck_broken("Misaligned file");
107 obuck_hdr.oid = start_of_this >> OBUCK_SHIFT;
108 obuck_hdr.length = obuck_hdr.orig_length = 0;
109 bwrite(obuck_fb, &obuck_hdr, sizeof(obuck_hdr));
114 obuck_write_end(struct fastbuf *b UNUSED, struct obuck_header *hdrp)
117 obuck_hdr.magic = OBUCK_MAGIC;
118 obuck_hdr.length = obuck_hdr.orig_length = btell(obuck_fb) - start_of_this - sizeof(obuck_hdr);
119 bputl(obuck_fb, OBUCK_TRAILER);
120 pad = (OBUCK_ALIGN - sizeof(obuck_hdr) - obuck_hdr.length - 4) & (OBUCK_ALIGN - 1);
124 bsetpos(obuck_fb, start_of_this);
125 /* FIXME: Can be replaced with single pwrite */
126 bwrite(obuck_fb, &obuck_hdr, sizeof(obuck_hdr));
129 memcpy(hdrp, &obuck_hdr, sizeof(obuck_hdr));
133 obuck_delete(oid_t oid)
136 obuck_fetch_header(oid);
137 obuck_hdr.oid = OBUCK_OID_DELETED;
139 bsetpos(obuck_fb, start_of_this);
140 bwrite(obuck_fb, &obuck_hdr, sizeof(obuck_hdr));
146 obuck_walk_init(void)
148 start_of_this = start_of_next = 0;
154 obuck_walk_next(struct fastbuf *b, struct obuck_header *hdrp)
159 start_of_this = start_of_next;
160 bsetpos(b, start_of_this);
165 bread(b, &obuck_hdr, sizeof(obuck_hdr));
166 if (obuck_hdr.magic != OBUCK_MAGIC)
167 obuck_broken("Missing magic number");
168 start_of_next = (start_of_this + sizeof(obuck_hdr) + obuck_hdr.orig_length +
169 4 + OBUCK_ALIGN - 1) & ~((sh_off_t)(OBUCK_ALIGN - 1));
170 if (obuck_hdr.oid == OBUCK_OID_DELETED)
172 memcpy(hdrp, &obuck_hdr, sizeof(obuck_hdr));
177 obuck_walk_end(struct fastbuf *b UNUSED)
186 struct obuck_header h;
192 for(i=0; i<100*j; i++)
194 obuck_write_end(b, &h);
195 printf("%d\t%08x\t%d\n", j, h.oid, h.orig_length);
198 b = obuck_walk_init();
199 while (b = obuck_walk_next(b, &h))
201 printf("<<< %08x\t%d\n", h.oid, h.orig_length);