/*
* Sherlock Library -- Object Buckets
*
- * (c) 2001 Martin Mares <mj@ucw.cz>
+ * (c) 2001--2002 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
static unsigned int obuck_remains, obuck_check_pad;
static struct fastbuf *obuck_fb;
static struct obuck_header obuck_hdr;
-static sh_off_t bucket_start;
+static sh_off_t bucket_start, bucket_current;
/*** Configuration ***/
byte *obuck_name = "not/configured";
-static int obuck_io_buflen = 65536;
+static uns obuck_io_buflen = 65536;
static int obuck_shake_buflen = 1048576;
static struct cfitem obuck_config[] = {
static int
obuck_fb_refill(struct fastbuf *f)
{
- unsigned limit = (f->buflen < obuck_remains) ? f->buflen : obuck_remains;
+ unsigned limit = (obuck_io_buflen < obuck_remains) ? obuck_io_buflen : obuck_remains;
unsigned size = (limit == obuck_remains) ? (limit+obuck_check_pad+4) : limit;
int l;
if (!limit)
return 0;
- l = sh_pread(f->fd, f->buffer, size, f->fdpos);
+ l = sh_pread(obuck_fd, f->buffer, size, bucket_current);
if (l < 0)
die("Error reading bucket: %m");
if ((unsigned) l != size)
obuck_broken("Short read");
f->bptr = f->buffer;
f->bstop = f->buffer + limit;
- f->pos = f->fdpos;
- f->fdpos += limit;
+ bucket_current += limit;
+ f->pos = bucket_current - bucket_start - sizeof(obuck_hdr);
obuck_remains -= limit;
if (!obuck_remains) /* Should check the trailer */
{
while (l)
{
- int z = sh_pwrite(f->fd, c, l, f->fdpos);
+ int z = sh_pwrite(obuck_fd, c, l, bucket_current);
if (z <= 0)
die("Error writing bucket: %m");
- f->fdpos += z;
+ bucket_current += z;
l -= z;
c += z;
}
f->bptr = f->buffer;
- f->pos = f->fdpos;
-}
-
-static void
-obuck_fb_close(struct fastbuf *f)
-{
- close(f->fd);
+ f->pos = bucket_current - bucket_start - sizeof(obuck_hdr);
}
/*** Exported functions ***/
if (obuck_fd < 0)
die("Unable to open bucket file %s: %m", obuck_name);
obuck_fb = b = xmalloc_zero(sizeof(struct fastbuf) + obuck_io_buflen + OBUCK_ALIGN + 4);
- b->buflen = obuck_io_buflen;
b->buffer = (char *)(b+1);
b->bptr = b->bstop = b->buffer;
b->bufend = b->buffer + obuck_io_buflen;
b->name = "bucket";
- b->fd = obuck_fd;
b->refill = obuck_fb_refill;
b->spout = obuck_fb_spout;
- b->close = obuck_fb_close;
obuck_lock_read();
size = sh_seek(obuck_fd, 0, SEEK_END);
if (size)
obuck_cleanup(void)
{
bclose(obuck_fb);
+ close(obuck_fd);
+ xfree(obuck_fb);
}
void
bflush(b);
if (sh_pread(obuck_fd, &obuck_hdr, sizeof(obuck_hdr), bucket_start) != sizeof(obuck_hdr))
obuck_broken("Short header read");
- b->fdpos = bucket_start + sizeof(obuck_hdr);
+ bucket_current = bucket_start + sizeof(obuck_hdr);
if (obuck_hdr.magic != OBUCK_MAGIC)
obuck_broken("Missing magic number");
if (obuck_hdr.oid == OBUCK_OID_DELETED)
return 0;
if (c != sizeof(obuck_hdr))
obuck_broken("Short header read");
- b->fdpos = bucket_start + sizeof(obuck_hdr);
+ bucket_current = bucket_start + sizeof(obuck_hdr);
if (obuck_hdr.magic != OBUCK_MAGIC)
obuck_broken("Missing magic number");
if (obuck_hdr.oid != OBUCK_OID_DELETED || full)
struct fastbuf *
obuck_fetch(void)
{
+ obuck_fb->pos = 0;
obuck_remains = obuck_hdr.length;
obuck_check_pad = (OBUCK_ALIGN - sizeof(obuck_hdr) - obuck_hdr.length - 4) & (OBUCK_ALIGN - 1);
return obuck_fb;
obuck_hdr.magic = OBUCK_INCOMPLETE_MAGIC;
obuck_hdr.oid = bucket_start >> OBUCK_SHIFT;
obuck_hdr.length = obuck_hdr.orig_length = 0;
- obuck_fb->fdpos = obuck_fb->pos = bucket_start;
+ bucket_current = bucket_start;
bwrite(obuck_fb, &obuck_hdr, sizeof(obuck_hdr));
+ obuck_fb->pos = -sizeof(obuck_hdr);
return obuck_fb;
}
{
int pad;
obuck_hdr.magic = OBUCK_MAGIC;
- obuck_hdr.length = obuck_hdr.orig_length = btell(obuck_fb) - bucket_start - sizeof(obuck_hdr);
+ obuck_hdr.length = obuck_hdr.orig_length = btell(obuck_fb);
pad = (OBUCK_ALIGN - sizeof(obuck_hdr) - obuck_hdr.length - 4) & (OBUCK_ALIGN - 1);
while (pad--)
bputc(obuck_fb, 0);
bputl(obuck_fb, OBUCK_TRAILER);
bflush(obuck_fb);
- ASSERT(!(btell(obuck_fb) & (OBUCK_ALIGN - 1)));
+ ASSERT(!(bucket_current & (OBUCK_ALIGN - 1)));
sh_pwrite(obuck_fd, &obuck_hdr, sizeof(obuck_hdr), bucket_start);
obuck_unlock();
memcpy(hdrp, &obuck_hdr, sizeof(obuck_hdr));