-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTimeBasedKey-ValueStore.cpp
126 lines (118 loc) · 3.95 KB
/
TimeBasedKey-ValueStore.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
* Design a time-based key-value data structure that can store multiple values for the same key at different time stamps and retrieve the key's value at a certain timestamp.
* Implement the TimeMap class:
* TimeMap() Initializes the object of the data structure.
* void set(String key, String value, int timestamp) Stores the key key with the value value at the given time timestamp.
* String get(String key, int timestamp) Returns a value such that set was called previously, with timestamp_prev <= timestamp.
* If there are multiple such values, it returns the value associated with the largest timestamp_prev. If there are no values, it returns "".
*/
#include <vector>
#include <algorithm>
#include <utility>
#include <string>
using namespace std;
typedef pair<string, vector<pair<int, string> > > time_key_pair;
class TimeMap
{
private:
vector<time_key_pair> key;
public:
TimeMap() {}
int search_key(string key)
{
int begin = 0;
int end = this->key.size() - 1;
while (begin <= end)
{
int mid = begin + (end - begin) / 2;
// cout << mid << " " << this->key[mid].first << " " << key << endl;
if (this->key[mid].first == key)
{
// cout << "find at " << mid << endl;
return mid;
}
else if (this->key[mid].first < key)
{
begin = mid + 1;
}
else
{
end = mid - 1;
}
}
return begin;
}
void set(string key, string value, int timestamp)
{
if (this->key.empty())
{
vector<pair<int, string> > new_pair;
new_pair.push_back(make_pair(timestamp, value));
this->key.push_back(make_pair(key, new_pair));
}
else
{
int pos = this->search_key(key);
if (pos < this->key.size() && this->key[pos].first == key)
{
auto new_pair = this->key[pos].second;
new_pair.push_back(make_pair(timestamp, value));
this->key[pos] = make_pair(key, new_pair);
}
else
{
vector<pair<int, string> > new_pair;
new_pair.push_back(make_pair(timestamp, value));
if (pos == this->key.size())
{
this->key.push_back(make_pair(key, new_pair));
}
else
{
this->key.insert(this->key.begin() + pos, make_pair(key, new_pair));
}
}
// cout << "insert " << key << " at " << pos << endl;
// cout << this->key.front().first << " " << this->key.back().first << endl;
}
}
string get(string key, int timestamp)
{
if (this->key.empty())
return "";
// cout << "find " << key << endl;
int pos = this->search_key(key);
// cout << "find " << key << " at " << pos << endl;
if (pos < this->key.size() && this->key[pos].first == key)
{
auto record = this->key[pos].second;
int end = record.size() - 1;
int begin = 0;
while (begin <= end)
{
int mid = begin + (end - begin) / 2;
if (record[mid].first == timestamp)
return record[mid].second;
else if (record[mid].first < timestamp)
{
begin = mid + 1;
}
else
{
end = mid - 1;
}
}
if (end < 0)
return "";
else
return record[end].second;
}
return "";
}
};
/**
* Your TimeMap object will be instantiated and called as such:
* TimeMap* obj = new TimeMap();
* obj->set(key,value,timestamp);
* string param_2 = obj->get(key,timestamp);
*/