]> mj.ucw.cz Git - libucw.git/commitdiff
Added emulator of SDBM on top of GDBM.
authorMartin Mares <mj@ucw.cz>
Mon, 15 Nov 1999 22:46:56 +0000 (22:46 +0000)
committerMartin Mares <mj@ucw.cz>
Mon, 15 Nov 1999 22:46:56 +0000 (22:46 +0000)
lib/db-emul.c [new file with mode: 0644]

diff --git a/lib/db-emul.c b/lib/db-emul.c
new file mode 100644 (file)
index 0000000..533c996
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ *     Sherlock Library -- SDBM emulator at top of GDBM
+ *
+ *     (c) 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lib.h"
+#include "db.h"
+
+#include <gdbm.h>
+
+struct sdbm {
+  GDBM_FILE db;
+  datum prevkey;
+};
+
+struct sdbm *
+sdbm_open(struct sdbm_options *o)
+{
+  struct sdbm *d = xmalloc(sizeof(struct sdbm));
+  d->db = gdbm_open(o->name,
+                   (o->page_order ? (1 << o->page_order) : 0),
+                   ((o->flags & SDBM_WRITE) ? ((o->flags & SDBM_CREAT) ? GDBM_WRCREAT : GDBM_WRITER) : GDBM_READER)
+                     | ((o->flags & SDBM_SYNC) ? GDBM_SYNC : 0),
+                   0666,
+                   NULL);
+  if (o->cache_size)
+    gdbm_setopt(d->db, GDBM_CACHESIZE, &o->cache_size, sizeof(o->cache_size));
+  d->prevkey.dptr = NULL;
+  return d;
+}
+
+void
+sdbm_close(struct sdbm *d)
+{
+  sdbm_rewind(d);
+  gdbm_close(d->db);
+  free(d);
+}
+
+static int
+sdbm_put_user(byte *D, uns Dl, byte *val, uns *vallen)
+{
+  if (vallen)
+    {
+      if (*vallen < Dl)
+       return 1;
+      *vallen = Dl;
+    }
+  if (val)
+    memcpy(val, D, Dl);
+  return 0;
+}
+
+int
+sdbm_store(struct sdbm *d, byte *key, uns keylen, byte *val, uns vallen)
+{
+  datum K, V;
+  int rc;
+
+  K.dptr = key;
+  K.dsize = keylen;
+  V.dptr = val;
+  V.dsize = vallen;
+  rc = gdbm_store(d->db, K, V, GDBM_INSERT);
+  return (rc < 0) ? rc : !rc;
+}
+
+int
+sdbm_replace(struct sdbm *d, byte *key, uns keylen, byte *val, uns vallen)
+{
+  datum K, V;
+  int rc;
+
+  if (!val)
+    return sdbm_delete(d, key, keylen);
+  K.dptr = key;
+  K.dsize = keylen;
+  V.dptr = val;
+  V.dsize = vallen;
+  rc = gdbm_store(d->db, K, V, GDBM_REPLACE);
+  return (rc < 0) ? rc : !rc;
+}
+
+int
+sdbm_delete(struct sdbm *d, byte *key, uns keylen)
+{
+  datum K;
+
+  K.dptr = key;
+  K.dsize = keylen;
+  return !gdbm_delete(d->db, K);
+}
+
+int
+sdbm_fetch(struct sdbm *d, byte *key, uns keylen, byte *val, uns *vallen)
+{
+  datum K, V;
+  int rc;
+
+  K.dptr = key;
+  K.dsize = keylen;
+  if (!val && !vallen)
+    return gdbm_exists(d->db, K);
+  V = gdbm_fetch(d->db, K);
+  if (!V.dptr)
+    return 0;
+  rc = sdbm_put_user(V.dptr, V.dsize, val, vallen);
+  free(V.dptr);
+  return rc ? SDBM_ERROR_TOO_LARGE : 1;
+}
+
+void
+sdbm_rewind(struct sdbm *d)
+{
+  if (d->prevkey.dptr)
+    {
+      free(d->prevkey.dptr);
+      d->prevkey.dptr = NULL;
+    }
+}
+
+int
+sdbm_get_next(struct sdbm *d, byte *key, uns *keylen, byte *val, uns *vallen)
+{
+  datum K;
+
+  if (d->prevkey.dptr)
+    {
+      K = gdbm_nextkey(d->db, d->prevkey);
+      free(d->prevkey.dptr);
+    }
+  else
+    K = gdbm_firstkey(d->db);
+  d->prevkey = K;
+  if (!K.dptr)
+    return 0;
+  if (sdbm_put_user(K.dptr, K.dsize, key, keylen))
+    return SDBM_ERROR_TOO_LARGE;
+  if (val || vallen)
+    return sdbm_fetch(d, key, *keylen, val, vallen);
+  return 1;
+}
+
+void
+sdbm_sync(struct sdbm *d)
+{
+}