]> mj.ucw.cz Git - libucw.git/commitdiff
Introduced obuck_slurp_pool() to make reading of the whole bucket
authorMartin Mares <mj@ucw.cz>
Sun, 6 Oct 2002 15:50:02 +0000 (15:50 +0000)
committerMartin Mares <mj@ucw.cz>
Sun, 6 Oct 2002 15:50:02 +0000 (15:50 +0000)
pool faster, possibly using mmap.

Use it in `buckettool -c'.

lib/bucket.c
lib/bucket.h
lib/buckettool.c

index db00678a3a8f58ca39616cb6e8d89984817ce4da..aff993107924dcb08f70b55233840b5a59a83c00 100644 (file)
@@ -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
index 24e7ae00d13c1a5d810a2eae38559de8960aa7ab..798e9a9a37727dbe1c2fe7665e9710d0e9d938d2 100644 (file)
@@ -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)
index ae55b3ca4d4f92c784c25bae194ac3c0fae308fd..bc8ce32d10ceca1cca491ecea404c6807c264ffe 100644 (file)
@@ -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# <missing EOL>\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# <missing EOL>\n");
+    }
   obuck_cleanup();
 }