Commit de5d83d
misc/key-value-store/main.rb
@@ -0,0 +1,39 @@
+def assert_equal(x, y)
+ return if x == y
+
+ raise "Expected `#{x.inspect}`, got `#{y.inspect}`"
+end
+
+class Store
+ def initialize
+ @hash = Hash.new do |hash, key|
+ hash[key] = []
+ end
+ end
+
+ def get(key, at: nil)
+ bucket = @hash[key]
+ return if bucket[-1].empty?
+
+ if at
+ bucket[-1].bsearch { |x| x <= at }[-1]
+ else
+ bucket[-1][-1]
+ end
+ end
+
+ def set(key, value)
+ @hash[key] << [Time.now.to_i, value]
+ end
+end
+
+store = Store.new
+store.set(:cart, 0)
+now = Time.now.to_i
+assert_equal(0, store.get(:cart))
+
+store.set(:cart, 3)
+assert_equal(3, store.get(:cart))
+
+assert_equal(0, store.get(:cart, at: now))
+puts "YAY!"
misc/key-value-store/README.md
@@ -2,3 +2,27 @@ Build a key value API that returns the time stamp of insertion when you insert a
1. Given the key only, return the value of the latest time stamp.
1. Given a key and time stamp return the value of the nearest time stamp in the past or equal for the key
+
+* Maybe Hash Addressing with Chaining
+* Time constantly increments
+* Inserts happen in order so data can be stored in order
+* This is sort of like commit log or event store/stream
+
+```plaintext
+
+key -> bucket
+
+-----
+| | -> [ [timestamp, value], , , ]
+-----
+-----
+| |
+-----
+-----
+| |
+-----
+```
+
+Because data is already sorted we can hash the key,
+to find the correct bucket. Then perform a binary search
+to find the value closest to the desired timestamp.