Danilo Fragoso hai 7 meses
pai
achega
3e6c5e96cc
Modificáronse 2 ficheiros con 63 adicións e 32 borrados
  1. 62 31
      index.zig
  2. 1 1
      main.zig

+ 62 - 31
index.zig

@@ -133,11 +133,16 @@ pub fn delete(key: []const u8) void {
     }
 }
 
-fn findNode(node: *RadixNode, key: []const u8) ?*RadixNode {
-    if (key.len == 0) return node;
+fn findNodeForPrefix(node: *RadixNode, prefix: []const u8, actual_path: *[]u8) ?*RadixNode {
+    if (prefix.len == 0) {
+        actual_path.* = &[_]u8{};
+        return node;
+    }
 
     var current = node;
-    var remaining = key;
+    var remaining = prefix;
+    var path_buffer: [MAX_KEY_LENGTH]u8 = undefined;
+    var path_len: usize = 0;
 
     while (remaining.len > 0) {
         var found = false;
@@ -145,30 +150,41 @@ fn findNode(node: *RadixNode, key: []const u8) ?*RadixNode {
         var it = current.children.iterator();
         while (it.next()) |entry| {
             const child = entry.value_ptr.*;
-            const prefix_len = commonPrefixLen(child.edge, remaining);
+            const prefix_match_len = commonPrefixLen(child.edge, remaining);
 
-            if (prefix_len > 0) {
-                if (prefix_len < child.edge.len) {
-                    return null;
+            if (prefix_match_len > 0) {
+                if (prefix_match_len == remaining.len) {
+                    actual_path.* = temp_allocator.dupe(u8, path_buffer[0..path_len]) catch &[_]u8{};
+                    return child;
                 }
 
-                if (prefix_len == remaining.len) {
-                    return child;
+                if (prefix_match_len == child.edge.len) {
+                    @memcpy(path_buffer[path_len .. path_len + prefix_match_len], child.edge[0..prefix_match_len]);
+                    path_len += prefix_match_len;
+                    remaining = remaining[prefix_match_len..];
+                    current = child;
+                    found = true;
+                    break;
                 }
 
-                remaining = remaining[prefix_len..];
-                current = child;
-                found = true;
-                break;
+                return null;
             }
         }
 
-        if (!found) return null;
+        if (!found) {
+            return null;
+        }
     }
 
+    actual_path.* = temp_allocator.dupe(u8, path_buffer[0..path_len]) catch &[_]u8{};
     return current;
 }
 
+fn findNode(node: *RadixNode, key: []const u8) ?*RadixNode {
+    var dummy_path: []u8 = &[_]u8{};
+    return findNodeForPrefix(node, key, &dummy_path);
+}
+
 pub fn searchByPrefix(prefix: []const u8) ?*RadixNode {
     ensureRoot();
     if (prefix.len == 0) return root;
@@ -188,40 +204,47 @@ fn countKeys(node: *RadixNode) usize {
     return count;
 }
 
-const MAX_KEYS_RETURN = 10000;
+const MAX_KEYS_RETURN = 100_000_000;
 const MAX_KEY_LENGTH = 1024;
 
-fn collectKeysWithBuffer(node: *RadixNode, prefix_buffer: []u8, prefix_len: usize, keys: *std.ArrayListUnmanaged([]const u8), max_keys: usize) void {
+fn collectKeysWithBuffer(node: *RadixNode, prefix_buffer: []u8, prefix_len: usize, keys: *std.ArrayListUnmanaged([]const u8), max_keys: usize, search_prefix: []const u8, include_node_edge: bool) void {
     if (keys.items.len >= max_keys) return;
 
+    var current_len = prefix_len;
+
+    if (include_node_edge and node.edge.len > 0) {
+        if (current_len + node.edge.len > MAX_KEY_LENGTH) return;
+        @memcpy(prefix_buffer[current_len .. current_len + node.edge.len], node.edge);
+        current_len += node.edge.len;
+    }
+
     if (node.is_terminal) {
-        const key = temp_allocator.dupe(u8, prefix_buffer[0..prefix_len]) catch return;
-        keys.append(temp_allocator, key) catch return;
+        const key = prefix_buffer[0..current_len];
+        if (key.len >= search_prefix.len and std.mem.eql(u8, key[0..search_prefix.len], search_prefix)) {
+            const key_copy = temp_allocator.dupe(u8, key) catch return;
+            keys.append(temp_allocator, key_copy) catch return;
+        }
     }
 
     var it = node.children.iterator();
     while (it.next()) |entry| {
         if (keys.items.len >= max_keys) break;
         const child = entry.value_ptr.*;
-        const edge_len = child.edge.len;
-
-        if (prefix_len + edge_len > MAX_KEY_LENGTH) continue;
 
-        @memcpy(prefix_buffer[prefix_len .. prefix_len + edge_len], child.edge);
-        collectKeysWithBuffer(child, prefix_buffer, prefix_len + edge_len, keys, max_keys);
+        collectKeysWithBuffer(child, prefix_buffer, current_len, keys, max_keys, search_prefix, true);
     }
 }
 
-fn collectKeys(node: *RadixNode, prefix: []const u8, keys: *std.ArrayListUnmanaged([]const u8), max_keys: usize) void {
+fn collectKeys(node: *RadixNode, prefix: []const u8, keys: *std.ArrayListUnmanaged([]const u8), max_keys: usize, search_prefix: []const u8) void {
     var prefix_buffer: [MAX_KEY_LENGTH]u8 = undefined;
     if (prefix.len > MAX_KEY_LENGTH) return;
     @memcpy(prefix_buffer[0..prefix.len], prefix);
-    collectKeysWithBuffer(node, &prefix_buffer, prefix.len, keys, max_keys);
+    collectKeysWithBuffer(node, &prefix_buffer, prefix.len, keys, max_keys, search_prefix, true);
 }
 
 pub fn getKeysFromNode(node: *RadixNode, prefix: []const u8) [][]const u8 {
     var keys_list = std.ArrayListUnmanaged([]const u8){};
-    collectKeys(node, prefix, &keys_list, MAX_KEYS_RETURN);
+    collectKeys(node, prefix, &keys_list, MAX_KEYS_RETURN, prefix);
     return keys_list.toOwnedSlice(temp_allocator) catch &[_][]const u8{};
 }
 
@@ -233,7 +256,7 @@ pub fn getKeysByPrefix(prefix: []const u8) []const u8 {
     const node = searchByPrefix(prefix) orelse return "";
     const keys = getKeysFromNode(node, prefix);
     if (keys.len == 0) return "";
-    return std.mem.join(temp_allocator, "\r", keys) catch "";
+    return std.mem.join(temp_allocator, "\n", keys) catch "";
 }
 
 pub fn getValuesByPrefix(prefix: []const u8) []const u8 {
@@ -241,8 +264,16 @@ pub fn getValuesByPrefix(prefix: []const u8) []const u8 {
     defer tree_mutex.unlock();
 
     ensureRoot();
-    const node = searchByPrefix(prefix) orelse return "";
-    const keys = getKeysFromNode(node, prefix);
+
+    var actual_path: []u8 = &[_]u8{};
+    const node = findNodeForPrefix(root, prefix, &actual_path) orelse {
+        return "";
+    };
+
+    var keys_list = std.ArrayListUnmanaged([]const u8){};
+    collectKeys(node, actual_path, &keys_list, MAX_KEYS_RETURN, prefix);
+    const keys = keys_list.toOwnedSlice(temp_allocator) catch &[_][]const u8{};
+
     if (keys.len == 0) return "";
 
     const values = temp_allocator.alloc([]const u8, keys.len) catch return "";
@@ -251,7 +282,7 @@ pub fn getValuesByPrefix(prefix: []const u8) []const u8 {
         values[i] = value;
     }
 
-    return std.mem.join(temp_allocator, "\r", values) catch "";
+    return std.mem.join(temp_allocator, "\n", values) catch "";
 }
 
 pub fn getAllKeys() []const u8 {
@@ -261,5 +292,5 @@ pub fn getAllKeys() []const u8 {
     ensureRoot();
     const keys = getKeysFromNode(root, &[_]u8{});
     if (keys.len == 0) return "";
-    return std.mem.join(temp_allocator, "\r", keys) catch "";
+    return std.mem.join(temp_allocator, "\n", keys) catch "";
 }

+ 1 - 1
main.zig

@@ -70,7 +70,7 @@ pub fn main() !void {
 
     if (instant_wal_mode) {
         persistence.setInstantWal(true);
-        std.debug.print("Instant WAL mode enabled\n", .{});
+        std.debug.print("\nInstant WAL mode enabled\n", .{});
     }
 
     while (!should_exit.load(.seq_cst)) {