]> mj.ucw.cz Git - libucw.git/commitdiff
After a lot of benchmarking replaced the old super-smart bbcopy()
authorMartin Mares <mj@ucw.cz>
Tue, 24 Sep 2002 21:38:21 +0000 (21:38 +0000)
committerMartin Mares <mj@ucw.cz>
Tue, 24 Sep 2002 21:38:21 +0000 (21:38 +0000)
by a much simpler solution based on the bdirect interface and inlined
the fast path. Surprisingly, the new version is faster under real load
(the explanation is very simple: we use very large buffers for the
indexer and hence the bbcopy optimizations triggered rarely) and it also
works on all fastbuf streams, not only file-based ones.

Also, made bdirect_* inline.

lib/fastbuf.c
lib/fastbuf.h
lib/fb-file.c

index 1b89a813998d7db2aea31dd0789a09a138d17a75..2631be06c1d7bf4c143228dba6a19ee331a58005 100644 (file)
@@ -284,32 +284,23 @@ bgets0(struct fastbuf *f, byte *b, uns l)
   die("%s: Line too long", f->name);
 }
 
-int
-bdirect_read_prepare(struct fastbuf *f, byte **buf)
-{
-  if (f->bptr == f->bstop && !f->refill(f))
-    return EOF;
-  *buf = f->bptr;
-  return f->bstop - f->bptr;
-}
-
 void
-bdirect_read_commit(struct fastbuf *f, byte *pos)
-{
-  f->bptr = pos;
-}
-
-int
-bdirect_write_prepare(struct fastbuf *f, byte **buf)
+bbcopy_slow(struct fastbuf *f, struct fastbuf *t, uns l)
 {
-  if (f->bptr == f->bufend)
-    f->spout(f);
-  *buf = f->bptr;
-  return f->bufend - f->bptr;
-}
+  while (l)
+    {
+      byte *fptr, *tptr;
+      uns favail, tavail, n;
 
-void
-bdirect_write_commit(struct fastbuf *f, byte *pos)
-{
-  f->bptr = pos;
+      favail = bdirect_read_prepare(f, &fptr);
+      if (favail == (uns)EOF)
+       die("bbcopy: source exhausted");
+      tavail = bdirect_write_prepare(t, &tptr);
+      n = MIN(l, favail);
+      n = MIN(n, tavail);
+      memcpy(tptr, fptr, n);
+      bdirect_read_commit(f, fptr + n);
+      bdirect_write_commit(t, tptr + n);
+      l -= n;
+    }
 }
index 7baa5013b77355546c7b8e5a4db1dc59f4cc7f85..4f6c5e66f8ab8fa3e386f0d6a796d0ba67e80c35 100644 (file)
@@ -77,7 +77,6 @@ struct fastbuf *bopen(byte *name, uns mode, uns buffer);
 struct fastbuf *bopen_tmp(uns buffer);
 struct fastbuf *bfdopen(int fd, uns buffer);
 struct fastbuf *bfdopen_shared(int fd, uns buffer);
-void bbcopy(struct fastbuf *f, struct fastbuf *t, uns l);
 #define FB_IS_TEMP_FILE(f) FB_FILE(f)->is_temp_file
 
 /* FastIO on in-memory streams */
@@ -286,6 +285,21 @@ bputsn(struct fastbuf *f, byte *b)
   bputc(f, '\n');
 }
 
+void bbcopy_slow(struct fastbuf *f, struct fastbuf *t, uns l);
+static inline void
+bbcopy(struct fastbuf *f, struct fastbuf *t, uns l)
+{
+  if (f->bptr + l <= f->bstop &&
+      t->bptr + l <= t->bufend)
+    {
+      memcpy(t->bptr, f->bptr, l);
+      t->bptr += l;
+      f->bptr += l;
+    }
+  else
+    bbcopy_slow(f, t, l);
+}
+
 /* I/O on addr_int_t */
 
 #ifdef CPU_64BIT_POINTERS
@@ -298,9 +312,34 @@ bputsn(struct fastbuf *f, byte *b)
 
 /* Direct I/O on buffers */
 
-int bdirect_read_prepare(struct fastbuf *f, byte **buf);
-void bdirect_read_commit(struct fastbuf *f, byte *pos);
-int bdirect_write_prepare(struct fastbuf *f, byte **buf);
-void bdirect_write_commit(struct fastbuf *f, byte *pos);
+static inline int
+bdirect_read_prepare(struct fastbuf *f, byte **buf)
+{
+  if (f->bptr == f->bstop && !f->refill(f))
+    return EOF;
+  *buf = f->bptr;
+  return f->bstop - f->bptr;
+}
+
+static inline void
+bdirect_read_commit(struct fastbuf *f, byte *pos)
+{
+  f->bptr = pos;
+}
+
+static inline int
+bdirect_write_prepare(struct fastbuf *f, byte **buf)
+{
+  if (f->bptr == f->bufend)
+    f->spout(f);
+  *buf = f->bptr;
+  return f->bufend - f->bptr;
+}
+
+static inline void
+bdirect_write_commit(struct fastbuf *f, byte *pos)
+{
+  f->bptr = pos;
+}
 
 #endif
index 73a2f14337a856f3034b3cca9e04276b7adec297..b5e6b6466f21c1c5bc5ba8fcc24c002562fea63d 100644 (file)
@@ -126,51 +126,6 @@ bfdopen_shared(int fd, uns buffer)
   return f;
 }
 
-void bbcopy(struct fastbuf *f, struct fastbuf *t, uns l)
-{
-  uns rf = f->bstop - f->bptr;
-  uns tbuflen = t->bufend - t->buffer;
-
-  ASSERT(f->close == bfd_close);
-  ASSERT(t->close == bfd_close);
-  if (!l)
-    return;
-  if (rf)
-    {
-      uns k = MIN(rf, l);
-      bwrite(t, f->bptr, k);
-      f->bptr += k;
-      l -= k;
-      if (!l)
-       return;
-    }
-  while (l >= tbuflen)
-    {
-      t->spout(t);
-      if ((uns) read(FB_FILE(f)->fd, t->buffer, tbuflen) != tbuflen)
-       die("bbcopy: %s exhausted", f->name);
-      f->pos += tbuflen;
-      f->bstop = f->bptr = f->buffer;
-      t->bptr = t->bufend;
-      l -= tbuflen;
-    }
-  while (l)
-    {
-      uns k = t->bufend - t->bptr;
-
-      if (!k)
-       {
-         t->spout(t);
-         k = t->bufend - t->bptr;
-       }
-      if (k > l)
-       k = l;
-      bread(f, t->bptr, k);
-      t->bptr += k;
-      l -= k;
-    }
-}
-
 #ifdef TEST
 
 int main(int argc, char **argv)