Patchwork [18,of,21,V2] speedy: a dict-like interface to the leveldb database

login
register
mail settings
Submitter Tomasz Kleczek
Date Dec. 14, 2012, 2:52 a.m.
Message ID <1c7e6abfe5949c7134ba.1355453550@dev408.prn1.facebook.com>
Download mbox | patch
Permalink /patch/100/
State Deferred, archived
Headers show

Comments

Tomasz Kleczek - Dec. 14, 2012, 2:52 a.m.
# HG changeset patch
# User Tomasz Kleczek <tkleczek at fb.com>
# Date 1355360712 28800
# Node ID 1c7e6abfe5949c7134ba498e6ae5ae3b74031997
# Parent  3a2c9270ca9847f9ae4f09bfce2b1e112e567afc
speedy: a dict-like interface to the leveldb database

This is a first patch in a series that adds persistency for the history
server indices.

Patch

diff --git a/hgext/speedy/leveldbdict.py b/hgext/speedy/leveldbdict.py
new file mode 100644
--- /dev/null
+++ b/hgext/speedy/leveldbdict.py
@@ -0,0 +1,72 @@ 
+# Copyright 2012 Facebook
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+"""Dict interface on top of leveldb bindings."""
+
+import leveldb
+
+class leveldbdict(object):
+    """Provides a dict interface to the underlying LevelDB instance.
+
+    Only some of the dict methods are supported.
+    """
+    def __init__(self, path, serialize, deserialize, *args, **kwargs):
+        self.path = path
+        self.db = leveldb.LevelDB(self.path, *args, **kwargs)
+        self.serialize = serialize
+        self.deserialize = deserialize
+
+    def __getitem__(self, key):
+        return self.deserialize(self.db.Get(key))
+
+    def __setitem__(self, key, value):
+        self.db.Put(self.serialize(key))
+
+    def __delitem__(self, key):
+        self.db.Delete(key)
+
+    def __iter__(self):
+        for k, v in self.db.RangeIter():
+            yield k
+
+    def __len__(self):
+        # There is no way to get number of keys in the database other than
+        # iterate through all elements. It's better to just disallow the
+        # operation.
+        raise NotImplementedError
+
+    def keys(self):
+        return [k for k, v in self.db.RangeIter()]
+
+    def iteritems(self):
+        for k, v in self.db.RangeIter():
+            yield k, self.deserialize(v)
+
+    def update(self, d):
+        """Inserts (key, value) pairs from an iterable `d` to the database.
+
+        Uses LevelDB batch operations to update faster.
+        """
+        batch = leveldb.WriteBatch()
+        for k, v in d:
+            batch.Put(k, self.serialize(v))
+        self.db.Write(batch, sync=True)
+
+    def get(self, k, default=None):
+        try:
+            return self[k]
+        except KeyError:
+            return default
+
+    def clear(self):
+        """Deletes all entries from the database.
+
+        Uses LevelDB batch operations to delete faster.
+        """
+        batch = leveldb.WriteBatch()
+        for k in self:
+            batch.Delete(k)
+        self.db.Write(batch, sync=True)
+