From: Martin Mares Date: Sun, 6 Oct 2002 15:50:02 +0000 (+0000) Subject: Introduced obuck_slurp_pool() to make reading of the whole bucket X-Git-Tag: holmes-import~1326 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=98bc6b8a48b5cc006dd650cfdc5cf46966d501a6;p=libucw.git Introduced obuck_slurp_pool() to make reading of the whole bucket pool faster, possibly using mmap. Use it in `buckettool -c'. --- diff --git a/lib/bucket.c b/lib/bucket.c index db00678a..aff99310 100644 --- a/lib/bucket.c +++ b/lib/bucket.c @@ -30,12 +30,14 @@ static sh_off_t bucket_start, bucket_current; byte *obuck_name = "not/configured"; static uns obuck_io_buflen = 65536; static int obuck_shake_buflen = 1048576; +static uns obuck_slurp_buflen = 65536; static struct cfitem obuck_config[] = { { "Buckets", CT_SECTION, NULL }, { "BucketFile", CT_STRING, &obuck_name }, { "BufSize", CT_INT, &obuck_io_buflen }, { "ShakeBufSize", CT_INT, &obuck_shake_buflen }, + { "SlurpBufSize", CT_INT, &obuck_slurp_buflen }, { NULL, CT_STOP, NULL } }; @@ -314,6 +316,73 @@ obuck_delete(oid_t oid) obuck_unlock(); } +/*** Fast reading of the whole pool ***/ + +static struct fastbuf *obuck_rpf; + +static int +obuck_slurp_refill(struct fastbuf *f) +{ + uns l; + + if (!obuck_remains) + return 0; + l = bdirect_read_prepare(obuck_rpf, &f->buffer); + if (!l) + obuck_broken("Incomplete object"); + l = MIN(l, obuck_remains); + bdirect_read_commit(obuck_rpf, f->buffer + l); + obuck_remains -= l; + f->bptr = f->buffer; + f->bufend = f->bstop = f->buffer + l; + return 1; +} + +struct fastbuf * +obuck_slurp_pool(struct obuck_header *hdrp) +{ + static struct fastbuf limiter; + uns l; + + do + { + if (!obuck_rpf) + { + obuck_lock_read(); + obuck_rpf = bopen(obuck_name, O_RDONLY, obuck_slurp_buflen); + } + else + { + bsetpos(obuck_rpf, bucket_current - 4); + if (bgetl(obuck_rpf) != OBUCK_TRAILER) + obuck_broken("Missing trailer"); + } + bucket_start = btell(obuck_rpf); + l = bread(obuck_rpf, hdrp, sizeof(struct obuck_header)); + if (!l) + { + bclose(obuck_rpf); + obuck_unlock(); + return NULL; + } + if (l != sizeof(struct obuck_header)) + obuck_broken("Short header read"); + if (hdrp->magic != OBUCK_MAGIC) + obuck_broken("Missing magic number"); + bucket_current = (bucket_start + sizeof(obuck_hdr) + hdrp->length + + 4 + OBUCK_ALIGN - 1) & ~((sh_off_t)(OBUCK_ALIGN - 1)); + } + while (hdrp->oid == OBUCK_OID_DELETED); + if (obuck_get_pos(hdrp->oid) != bucket_start) + obuck_broken("Invalid backlink"); + obuck_remains = hdrp->length; + limiter.bptr = limiter.bstop = limiter.buffer = limiter.bufend = NULL; + limiter.name = "Bucket"; + limiter.pos = 0; + limiter.refill = obuck_slurp_refill; + return &limiter; +} + /*** Shakedown ***/ void diff --git a/lib/bucket.h b/lib/bucket.h index 24e7ae00..798e9a9a 100644 --- a/lib/bucket.h +++ b/lib/bucket.h @@ -62,6 +62,9 @@ void obuck_create_end(struct fastbuf *b, struct obuck_header *hdrp); /* Deleting buckets */ void obuck_delete(oid_t oid); +/* Fast reading of the whole pool */ +struct fastbuf *obuck_slurp_pool(struct obuck_header *hdrp); + /* Convert bucket ID to file position (for size limitations etc.) */ static inline sh_off_t obuck_get_pos(oid_t oid) diff --git a/lib/buckettool.c b/lib/buckettool.c index ae55b3ca..bc8ce32d 100644 --- a/lib/buckettool.c +++ b/lib/buckettool.c @@ -135,22 +135,18 @@ cat(void) int l, lf; obuck_init(0); - if (obuck_find_first(&h, 0)) - do - { - printf("### %08x %6d %6d\n", h.oid, h.length, h.orig_length); - b = obuck_fetch(); - lf = 1; - while ((l = bread(b, buf, sizeof(buf)))) - { - fwrite(buf, 1, l, stdout); - lf = (buf[l-1] == '\n'); - } - obuck_fetch_end(b); - if (!lf) - printf("\n# \n"); - } - while (obuck_find_next(&h, 0)); + while (b = obuck_slurp_pool(&h)) + { + printf("### %08x %6d %6d\n", h.oid, h.length, h.orig_length); + lf = 1; + while ((l = bread(b, buf, sizeof(buf)))) + { + fwrite(buf, 1, l, stdout); + lf = (buf[l-1] == '\n'); + } + if (!lf) + printf("\n# \n"); + } obuck_cleanup(); }