]> git.ozlabs.org Git - ccan/blobdiff - ccan/tdb2/test/layout.c
tdb2: provide tdb_layout_write() rather than implying it by new_tdb_layout arg.
[ccan] / ccan / tdb2 / test / layout.c
index d4f68cbf836a6d5f836215cb8e221a39df16bf3d..50b3cbe7cefd0282aa1a53d374d52f900c41fbd0 100644 (file)
@@ -6,10 +6,9 @@
 #include <err.h>
 #include "logging.h"
 
-struct tdb_layout *new_tdb_layout(const char *filename)
+struct tdb_layout *new_tdb_layout(void)
 {
        struct tdb_layout *layout = malloc(sizeof(*layout));
-       layout->filename = filename;
        layout->num_elems = 0;
        layout->elem = NULL;
        return layout;
@@ -92,6 +91,12 @@ static void set_free_record(void *mem, tdb_len_t len)
        /* We do all the work in add_to_freetable */
 }
 
+static void add_zero_pad(struct tdb_used_record *u, size_t len, size_t extra)
+{
+       if (extra)
+               ((char *)(u + 1))[len] = '\0';
+}
+
 static void set_data_record(void *mem, struct tdb_context *tdb,
                            struct tle_used *used)
 {
@@ -103,6 +108,7 @@ static void set_data_record(void *mem, struct tdb_context *tdb,
        memcpy(u + 1, used->key.dptr, used->key.dsize);
        memcpy((char *)(u + 1) + used->key.dsize,
               used->data.dptr, used->data.dsize);
+       add_zero_pad(u, used->key.dsize + used->data.dsize, used->extra);
 }
 
 static void set_hashtable(void *mem, struct tdb_context *tdb,
@@ -113,6 +119,7 @@ static void set_hashtable(void *mem, struct tdb_context *tdb,
 
        set_header(tdb, u, TDB_HTABLE_MAGIC, 0, len, len + htable->extra, 0);
        memset(u + 1, 0, len);
+       add_zero_pad(u, len, htable->extra);
 }
 
 static void set_freetable(void *mem, struct tdb_context *tdb,
@@ -139,9 +146,10 @@ static void add_to_freetable(struct tdb_context *tdb,
                             unsigned ftable,
                             struct tle_freetable *freetable)
 {
-       tdb->ftable_off = freetable->base.off;
-       tdb->ftable = ftable;
-       add_free_record(tdb, eoff, sizeof(struct tdb_used_record) + elen);
+       tdb->tdb2.ftable_off = freetable->base.off;
+       tdb->tdb2.ftable = ftable;
+       add_free_record(tdb, eoff, sizeof(struct tdb_used_record) + elen,
+                       TDB_LOCK_WAIT, false);
 }
 
 static tdb_off_t hbucket_off(tdb_off_t group_start, unsigned ingroup)
@@ -197,7 +205,7 @@ static void add_to_hashtable(struct tdb_context *tdb,
                b_off = hbucket_off(group_start, bucket);               
                if (tdb_read_off(tdb, b_off) == 0) {
                        tdb_write_off(tdb, b_off,
-                                     encode_offset(eoff, bucket, h));
+                                     encode_offset(eoff, in_group, h));
                        return;
                }
        }
@@ -219,7 +227,8 @@ static struct tle_freetable *find_ftable(struct tdb_layout *layout, unsigned num
 }
 
 /* FIXME: Support TDB_CONVERT */
-struct tdb_context *tdb_layout_get(struct tdb_layout *layout)
+struct tdb_context *tdb_layout_get(struct tdb_layout *layout,
+                                  union tdb_attribute *attr)
 {
        unsigned int i;
        tdb_off_t off, len, last_ftable;
@@ -252,14 +261,16 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout)
        }
 
        mem = malloc(off);
+       /* Fill with some weird pattern. */
+       memset(mem, 0x99, off);
        /* Now populate our header, cribbing from a real TDB header. */
-       tdb = tdb_open(NULL, TDB_INTERNAL, O_RDWR, 0, &tap_log_attr);
-       memcpy(mem, tdb->map_ptr, sizeof(struct tdb_header));
+       tdb = tdb_open(NULL, TDB_INTERNAL, O_RDWR, 0, attr);
+       memcpy(mem, tdb->file->map_ptr, sizeof(struct tdb_header));
 
        /* Mug the tdb we have to make it use this. */
-       free(tdb->map_ptr);
-       tdb->map_ptr = mem;
-       tdb->map_size = off;
+       free(tdb->file->map_ptr);
+       tdb->file->map_ptr = mem;
+       tdb->file->map_size = off;
 
        last_ftable = 0;
        for (i = 0; i < layout->num_elems; i++) {
@@ -301,22 +312,36 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout)
                }
        }
 
-       tdb->ftable_off = find_ftable(layout, 0)->base.off;
-
-       /* Get physical if they asked for it. */
-       if (layout->filename) {
-               int fd = open(layout->filename, O_WRONLY|O_TRUNC|O_CREAT,
-                             0600);
-               if (fd < 0)
-                       err(1, "opening %s for writing", layout->filename);
-               if (write(fd, tdb->map_ptr, tdb->map_size) != tdb->map_size)
-                       err(1, "writing %s", layout->filename);
-               close(fd);
-               tdb_close(tdb);
-               /* NOMMAP is for lockcheck. */
-               tdb = tdb_open(layout->filename, TDB_NOMMAP, O_RDWR, 0,
-                              &tap_log_attr);
-       }
-
+       tdb->tdb2.ftable_off = find_ftable(layout, 0)->base.off;
        return tdb;
 }
+
+void tdb_layout_write(struct tdb_layout *layout, union tdb_attribute *attr,
+                     const char *filename)
+{
+       struct tdb_context *tdb = tdb_layout_get(layout, attr);
+       int fd;
+
+       fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT,  0600);
+       if (fd < 0)
+               err(1, "opening %s for writing", filename);
+       if (write(fd, tdb->file->map_ptr, tdb->file->map_size)
+           != tdb->file->map_size)
+               err(1, "writing %s", filename);
+       close(fd);
+       tdb_close(tdb);
+}
+
+void tdb_layout_free(struct tdb_layout *layout)
+{
+       unsigned int i;
+
+       for (i = 0; i < layout->num_elems; i++) {
+               if (layout->elem[i].base.type == DATA) {
+                       free(layout->elem[i].used.key.dptr);
+                       free(layout->elem[i].used.data.dptr);
+               }
+       }
+       free(layout->elem);
+       free(layout);
+}