]> mj.ucw.cz Git - libucw.git/commitdiff
Atomic fastbufs: the first sketch of the interface.
authorMartin Mares <mj@ucw.cz>
Wed, 13 Sep 2006 19:38:05 +0000 (21:38 +0200)
committerMartin Mares <mj@ucw.cz>
Wed, 13 Sep 2006 19:38:05 +0000 (21:38 +0200)
lib/Makefile
lib/fastbuf.h
lib/fb-atomic.c [new file with mode: 0644]

index 2a5548704f52c9b3957fbbb17032d7abf5be7133..775c7de6c89412b96a5812c0ad44b2d010dad9a5 100644 (file)
@@ -15,7 +15,7 @@ LIBUCW_MODS= \
        ipaccess \
        profile \
        fastbuf ff-binary ff-string ff-printf ff-utf8 \
-       fb-file carefulio fb-mem fb-temp fb-mmap fb-limfd fb-buffer fb-grow \
+       fb-file carefulio fb-mem fb-temp fb-mmap fb-limfd fb-buffer fb-grow fb-atomic \
        str_ctype str_upper str_lower unicode-utf8 stkstring \
        wildmatch wordsplit ctmatch patimatch patmatch regex \
        prime primetable random timer randomkey \
index 6dbacce5dcebf52c73b5fdeac47cfd8511ceda23..2d1c1eb3b5fc641eb6e8ba0b300ec8447e8a3cbe 100644 (file)
@@ -118,6 +118,11 @@ struct fastbuf *fbgrow_create(unsigned basic_size);
 void fbgrow_reset(struct fastbuf *b);                  /* Reset stream and prepare for writing */
 void fbgrow_rewind(struct fastbuf *b);                 /* Prepare for reading */
 
+/* FastO with atomic writes for multi-threaded programs */
+
+struct fastbuf *fbatomic_create(byte *name, struct fastbuf *master, uns bufsize, int record_len);
+void fbatomic_checkpoint(struct fastbuf *b);
+
 /* Configuring stream parameters */
 
 int bconfig(struct fastbuf *f, uns type, int data);
diff --git a/lib/fb-atomic.c b/lib/fb-atomic.c
new file mode 100644 (file)
index 0000000..29e7c30
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *     UCW Library -- Atomic Buffered Write to Files
+ *
+ *     (c) 2006 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+/*
+ *     This fastbuf backend is intended for cases where several threads
+ *     of a single program append records to a single file and while the
+ *     record can mix in an arbitrary way, the bytes inside a single
+ *     record must remain uninterrupted.
+ *
+ *     In case of files with fixed record size, we just allocate the
+ *     buffer to hold a whole number of records and take advantage
+ *     of the atomicity of the write() system call.
+ *
+ *     With variable-sized records, we need another solution: when
+ *     writing a record, we keep the fastbuf in a locked state, which
+ *     prevents buffer flushing (and if the buffer becomes full, we extend it),
+ *     and we wait for an explicit commit operation which write()s the buffer
+ *     if the free space in the buffer falls below the expected maximum record
+ *     length.
+ *
+ *     fbatomic_create() is called with the following parameters:
+ *         name - name of the file to open
+ *         master - fbatomic for the master thread or NULL if it's the first open
+ *         bufsize - initial buffer size
+ *         record_len - record length for fixed-size records;
+ *             or -(expected maximum record length) for variable-sized ones.
+ */
+
+#include "lib/lib.h"
+#include "lib/fastbuf.h"
+#include "lib/lfs.h"
+
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+struct fb_atomic {
+  struct fastbuf fb;
+  int fd;                              /* File descriptor */
+  uns locked;
+  uns expected_max_len;
+  byte *expected_max_bptr;
+};
+#define FB_ATOMIC(f) ((struct fb_atomic *)(f)->is_fastbuf)