]> gitweb.ps.run Git - ziglmdb/blobdiff - src/db.zig
changes
[ziglmdb] / src / db.zig
index 4062ba9db56b95b459d14e1b01f72a40c67ed8cb..99d3eb3ead173345d62e4545ab6b335023ae4e04 100644 (file)
@@ -27,16 +27,22 @@ pub fn Db(comptime K: type, comptime V: type) type {
             return try self.dbi.has(k);
         }
         pub const Iterator = struct {
             return try self.dbi.has(k);
         }
         pub const Iterator = struct {
+            pub const Result = struct { key: K, val: V };
             cursor: lmdb.Cursor,
             cursor: lmdb.Cursor,
+            dir: enum { Forward, Backward },
             k: ?K,
             v: ?V,
 
             k: ?K,
             v: ?V,
 
-            pub fn next(self: *Iterator) ?struct { key: K, val: V } {
+            pub fn next(self: *Iterator) ?Result {
                 if (self.k != null and self.v != null) {
                 if (self.k != null and self.v != null) {
-                    const result = .{ .key = self.k.?, .val = self.v.? };
+                    const result = Result{ .key = self.k.?, .val = self.v.? };
 
                     var k = self.k.?;
 
                     var k = self.k.?;
-                    self.v = self.cursor.get(&k, V, .Next) catch return null;
+                    if (self.dir == .Forward) {
+                        self.v = self.cursor.get(&k, V, .Next) catch return null;
+                    } else {
+                        self.v = self.cursor.get(&k, V, .Prev) catch return null;
+                    }
                     if (self.v != null) {
                         self.k = k;
                     }
                     if (self.v != null) {
                         self.k = k;
                     }
@@ -51,7 +57,14 @@ pub fn Db(comptime K: type, comptime V: type) type {
 
             var k: K = undefined;
             const v = try cursor.get(&k, V, .First);
 
             var k: K = undefined;
             const v = try cursor.get(&k, V, .First);
-            return .{ .cursor = cursor, .k = k, .v = v };
+            return .{ .cursor = cursor, .dir = .Forward, .k = k, .v = v };
+        }
+        pub fn reverse_iterator(self: Self) !Iterator {
+            var cursor = try self.dbi.cursor();
+
+            var k: K = undefined;
+            const v = try cursor.get(&k, V, .Last);
+            return .{ .cursor = cursor, .dir = .Backward, .k = k, .v = v };
         }
     };
 }
         }
     };
 }
@@ -83,7 +96,7 @@ fn SetListBase(comptime K: type, comptime V: type) type {
         idx: ?Index = null,
 
         fn open_dbi(txn: lmdb.Txn) !lmdb.Dbi {
         idx: ?Index = null,
 
         fn open_dbi(txn: lmdb.Txn) !lmdb.Dbi {
-            return try txn.dbi("SetList");
+            return try txn.dbi(null);
         }
         pub fn init(txn: lmdb.Txn) !Self {
             const head = View.Head{};
         }
         pub fn init(txn: lmdb.Txn) !Self {
             const head = View.Head{};
@@ -131,6 +144,15 @@ fn SetListViewBase(comptime K: type, comptime V: type) type {
         idx: SetListBase(K, V).Index,
         head: Head,
 
         idx: SetListBase(K, V).Index,
         head: Head,
 
+        fn gen(self: @This()) !Key {
+            // TODO: limit loop
+            while (true) {
+                const key = try Prng.gen(self.dbi, Key);
+                if (!try self.dbi.has(self.item_idx(key))) {
+                    return key;
+                }
+            }
+        }
         fn item_idx(self: Self, k: K) ItemIndex {
             return .{ self.idx, k };
         }
         fn item_idx(self: Self, k: K) ItemIndex {
             return .{ self.idx, k };
         }
@@ -158,8 +180,8 @@ fn SetListViewBase(comptime K: type, comptime V: type) type {
                 try self.item_put(item.next.?, next);
             }
 
                 try self.item_put(item.next.?, next);
             }
 
-            if (self.head.first == k) self.head.first = item.next;
-            if (self.head.last == k) self.head.last = item.prev;
+            if (std.meta.eql(self.head.first, k)) self.head.first = item.next;
+            if (std.meta.eql(self.head.last, k)) self.head.last = item.prev;
             self.head.len -= 1;
             try self.head_update();
 
             self.head.len -= 1;
             try self.head_update();
 
@@ -206,13 +228,13 @@ fn SetListViewBase(comptime K: type, comptime V: type) type {
             return self.dbi.has(self.item_idx(key));
         }
         pub const Iterator = struct {
             return self.dbi.has(self.item_idx(key));
         }
         pub const Iterator = struct {
-            pub const Result = ?struct { key: K, val: V };
+            pub const Result = struct { key: K, val: V };
 
             slv: SetListViewBase(K, V),
             idx: ?K,
             dir: enum { Forward, Backward },
 
 
             slv: SetListViewBase(K, V),
             idx: ?K,
             dir: enum { Forward, Backward },
 
-            pub fn next(self: *Iterator) Result {
+            pub fn next(self: *Iterator) ?Result {
                 if (self.idx != null) {
                     const k = self.idx.?;
                     const item = self.slv.item_get(k) catch return null;
                 if (self.idx != null) {
                     const k = self.idx.?;
                     const item = self.slv.item_get(k) catch return null;
@@ -299,15 +321,6 @@ pub fn List(comptime V: type) type {
 
             base: ViewBase,
 
 
             base: ViewBase,
 
-            fn gen(self: @This()) !Key {
-                // TODO: limit loop
-                while (true) {
-                    const key = try Prng.gen(self.base.dbi, Key);
-                    if (!try self.base.dbi.has(self.base.item_idx(key))) {
-                        return key;
-                    }
-                }
-            }
             pub fn del(self: *@This(), key: Key) !void {
                 try self.base.del(key);
             }
             pub fn del(self: *@This(), key: Key) !void {
                 try self.base.del(key);
             }
@@ -318,7 +331,7 @@ pub fn List(comptime V: type) type {
                 return self.base.len();
             }
             pub fn append(self: *@This(), val: Val) !Key {
                 return self.base.len();
             }
             pub fn append(self: *@This(), val: Val) !Key {
-                const key = try self.gen();
+                const key = try self.base.gen();
                 try self.base.append(key, val);
                 return key;
             }
                 try self.base.append(key, val);
                 return key;
             }