Skip to content

Commit 9fa9d08

Browse files
Chris WuChris Wu
authored andcommitted
time-based-key-value-store.py
1 parent 9591831 commit 9fa9d08

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""
2+
We need a hash-table to store the key-value information.
3+
For every key, there are multiple values and we need it to sort by`timestamp`.
4+
5+
First, we use two array, `t` and `v` to store timestamp and value separately.
6+
And becuase the problem says **The timestamps for all TimeMap.set operations are strictly increasing.**
7+
So for the `set()` method, we only need to simply append `value` and `timestamp` to the end of `v` and `t`.
8+
The array `t` and its corresponding `v` is sorted already.
9+
10+
[bisect](https://docs.python.org/2/library/bisect.html) can help us implement our `get()` method.
11+
It returns an insertion point which comes after (to the right of) any existing entries, if we insert the **`timestamp` we are going to get()** into a the array, `t`.
12+
So `bisect(t, timestamp)` returns `i`:
13+
* If `i==0`: it means that there are no value samller than the `timestamp`, `return ""`.
14+
* If `i>0`: it means `i` is the index where its value just exceed the `timestamp`, return the value at `i-1`.
15+
16+
We can also implement our own `bisect` by binary search.
17+
The implementation assume there are no duplicate value in the array.
18+
19+
Time Complexity, O(1) for `set()`. O(LogN) for `get()`.
20+
Space complexity is O(N)
21+
N is the number of value stored.
22+
"""
23+
import collections
24+
import bisect
25+
26+
class TimeMap(object):
27+
28+
def __init__(self):
29+
self.t = collections.defaultdict(list)
30+
self.v = collections.defaultdict(list)
31+
32+
def set(self, key, value, timestamp):
33+
self.t[key].append(timestamp)
34+
self.v[key].append(value)
35+
36+
def get(self, key, timestamp):
37+
if len(self.t[key])==0: return ""
38+
i = bisect.bisect(self.t[key], timestamp)
39+
return self.v[key][i-1] if i>0 else ""
40+
41+
42+
import collections
43+
44+
class TimeMap(object):
45+
def __init__(self):
46+
self.t = collections.defaultdict(list)
47+
self.v = collections.defaultdict(list)
48+
49+
def set(self, key, value, timestamp):
50+
self.t[key].append(timestamp)
51+
self.v[key].append(value)
52+
53+
def get(self, key, timestamp):
54+
if len(self.t[key])==0: return ""
55+
i = self.bisect(self.t[key], timestamp)
56+
return self.v[key][i-1] if i>0 else ""
57+
58+
def bisect(self, A, x):
59+
if A is None or len(A)==0: return 0
60+
61+
l = 0
62+
r = len(A)-1
63+
while l<=r:
64+
if x<A[l]: return l
65+
elif A[l]==x: return l+1
66+
elif A[r]<=x: return r+1
67+
68+
p = (l+r)/2
69+
if x<A[p]:
70+
r = p-1
71+
elif A[p]==x:
72+
return p+1
73+
else:
74+
l = p+1
75+
return l
76+
77+
t = TimeMap()
78+
t.set('love', 'low', 10)
79+
t.set('love', 'high', 20)
80+
print t.get('love', 5)
81+
print t.get('love', 10)
82+
print t.get('love', 15)
83+
print t.get('love', 20)
84+
print t.get('love', 25)
85+
86+
87+

0 commit comments

Comments
 (0)