From a256a05fe3785c245f77761db19658c8bbc2b87a Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 24 Sep 2002 21:38:21 +0000 Subject: [PATCH] After a lot of benchmarking replaced the old super-smart bbcopy() 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 | 41 ++++++++++++++++------------------------- lib/fastbuf.h | 49 ++++++++++++++++++++++++++++++++++++++++++++----- lib/fb-file.c | 45 --------------------------------------------- 3 files changed, 60 insertions(+), 75 deletions(-) diff --git a/lib/fastbuf.c b/lib/fastbuf.c index 1b89a813..2631be06 100644 --- a/lib/fastbuf.c +++ b/lib/fastbuf.c @@ -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; + } } diff --git a/lib/fastbuf.h b/lib/fastbuf.h index 7baa5013..4f6c5e66 100644 --- a/lib/fastbuf.h +++ b/lib/fastbuf.h @@ -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 diff --git a/lib/fb-file.c b/lib/fb-file.c index 73a2f143..b5e6b646 100644 --- a/lib/fb-file.c +++ b/lib/fb-file.c @@ -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) -- 2.39.2