storage.zig 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. const std = @import("std");
  2. const hashing = @import("hashing.zig");
  3. const MAX_RECORDS = 10_000_000;
  4. const Entry = struct {
  5. key: []const u8,
  6. value: []const u8,
  7. next: ?*Entry,
  8. };
  9. var buf: [MAX_RECORDS]?*Entry = undefined;
  10. var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
  11. const allocator = arena.allocator();
  12. const EMPTY = "";
  13. var mutex: std.Thread.Mutex = .{};
  14. pub fn write(key: []const u8, value: []const u8) bool {
  15. mutex.lock();
  16. defer mutex.unlock();
  17. const hash = hashing.hashKey(key);
  18. const index = hash % buf.len;
  19. var current = buf[index];
  20. while (current) |entry| {
  21. if (std.mem.eql(u8, entry.key, key)) {
  22. allocator.free(entry.value);
  23. entry.value = allocator.dupe(u8, value) catch return false;
  24. return true;
  25. }
  26. current = entry.next;
  27. }
  28. const newEntry = allocator.create(Entry) catch return false;
  29. errdefer allocator.destroy(newEntry);
  30. newEntry.* = Entry{
  31. .key = allocator.dupe(u8, key) catch return false,
  32. .value = allocator.dupe(u8, value) catch return false,
  33. .next = buf[index],
  34. };
  35. buf[index] = newEntry;
  36. return true;
  37. }
  38. pub fn read(key: []const u8) ?[]const u8 {
  39. mutex.lock();
  40. defer mutex.unlock();
  41. const hash = hashing.hashKey(key);
  42. var current = buf[hash % buf.len];
  43. while (current) |entry| {
  44. if (std.mem.eql(u8, entry.key, key)) {
  45. return entry.value;
  46. }
  47. current = entry.next;
  48. }
  49. return null;
  50. }
  51. pub fn delete(key: []const u8) bool {
  52. mutex.lock();
  53. defer mutex.unlock();
  54. const hash = hashing.hashKey(key);
  55. const index = hash % buf.len;
  56. var current = buf[index];
  57. var prev: ?*Entry = null;
  58. while (current) |entry| {
  59. if (std.mem.eql(u8, entry.key, key)) {
  60. if (prev) |p| {
  61. p.next = entry.next;
  62. } else {
  63. buf[index] = entry.next;
  64. }
  65. allocator.free(entry.key);
  66. allocator.free(entry.value);
  67. allocator.destroy(entry);
  68. return true;
  69. }
  70. prev = entry;
  71. current = entry.next;
  72. }
  73. return false;
  74. }