]> mj.ucw.cz Git - libucw.git/blobdiff - lib/fastbuf.h
sped up approximately 6 times:
[libucw.git] / lib / fastbuf.h
index f3a05952c9db60a16021f66da5e1eaf2d9e2badd..2ed05341dbcaa42b7268b09abd83de112024aba6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     Sherlock Library -- Fast Buffered I/O
  *
- *     (c) 1997--2002 Martin Mares <mj@ucw.cz>
+ *     (c) 1997--2004 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
  *
  *  When writing:
  *
- *  +----------------+---------------------------+
- *  | written data   | free space                |
- *  +----------------+---------------------------+
- *  ^                 ^                           ^
- *  buffer=bstop      bptr                        bufend
+ *  +--------+--------------+--------------------+
+ *  | unused | written data | free space         |
+ *  +--------+--------------+--------------------+
+ *  ^         ^              ^                    ^
+ *  buffer    bstop          bptr                 bufend
  *
  *  Dirty tricks:
  *
@@ -62,34 +62,52 @@ struct fastbuf {
   void (*spout)(struct fastbuf *);     /* Write buffer data to the file */
   void (*seek)(struct fastbuf *, sh_off_t, int);  /* Slow path for bseek(), buffer already flushed */
   void (*close)(struct fastbuf *);     /* Close the stream */
+  int (*config)(struct fastbuf *, uns, int);   /* Configure the stream */
 };
 
-/* FastIO on standard files */
-
-struct fb_file {
-  struct fastbuf fb;
-  int fd;                              /* File descriptor, -1 if not a real file */
-  int is_temp_file;                    /* Is a temporary file, delete on close */
-};
-#define FB_FILE(f) ((struct fb_file *)(f)->is_fastbuf)
+/* FastIO on standard files (specify buffer size 0 to enable mmaping) */
 
 struct fastbuf *bopen(byte *name, uns mode, uns buffer);
 struct fastbuf *bopen_tmp(uns buffer);
 struct fastbuf *bfdopen(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
+struct fastbuf *bfdopen_shared(int fd, uns buffer);
 
 /* FastIO on in-memory streams */
 
 struct fastbuf *fbmem_create(unsigned blocksize);      /* Create stream and return its writing fastbuf */
 struct fastbuf *fbmem_clone_read(struct fastbuf *);    /* Create reading fastbuf */
 
+/* FastIO on memory mapped files */
+
+struct fastbuf *bopen_mm(byte *name, uns mode);
+
+/* FastI on file descriptors with limit */
+
+struct fastbuf *bopen_limited_fd(int fd, uns bufsize, uns limit);
+
+/* FastIO on static buffers */
+
+void fbbuf_init_read(struct fastbuf *f, byte *buffer, uns size);
+void fbbuf_init_write(struct fastbuf *f, byte *buffer, uns size);
+static inline uns
+fbbuf_count_written(struct fastbuf *f)
+{
+  return f->bptr - f->bstop;
+}
+
+/* Configuring stream parameters */
+
+int bconfig(struct fastbuf *f, uns type, int data);
+
+#define BCONFIG_IS_TEMP_FILE 0
+
 /* Universal functions working on all fastbuf's */
 
 void bclose(struct fastbuf *f);
 void bflush(struct fastbuf *f);
 void bseek(struct fastbuf *f, sh_off_t pos, int whence);
 void bsetpos(struct fastbuf *f, sh_off_t pos);
+void brewind(struct fastbuf *f);
 
 static inline sh_off_t btell(struct fastbuf *f)
 {
@@ -264,6 +282,7 @@ static inline void bwrite(struct fastbuf *f, void *b, uns l)
 }
 
 byte *bgets(struct fastbuf *f, byte *b, uns l);        /* Non-std */
+int bgets_nodie(struct fastbuf *f, byte *b, uns l);
 byte *bgets0(struct fastbuf *f, byte *b, uns l);
 
 static inline void
@@ -285,6 +304,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
@@ -297,9 +331,39 @@ 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 uns
+bdirect_read_prepare(struct fastbuf *f, byte **buf)
+{
+  if (f->bptr == f->bstop && !f->refill(f))
+    return 0;
+  *buf = f->bptr;
+  return f->bstop - f->bptr;
+}
+
+static inline void
+bdirect_read_commit(struct fastbuf *f, byte *pos)
+{
+  f->bptr = pos;
+}
+
+static inline uns
+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;
+}
+
+/* Formatted output */
+
+int bprintf(struct fastbuf *b, byte *msg, ...);
+int vbprintf(struct fastbuf *b, byte *msg, va_list args);
 
 #endif