Untitled
unknown
c_cpp
3 years ago
2.8 kB
2
Indexable
Never
#include "bits/stdc++.h" #include <boost/thread/shared_mutex.hpp> #include <boost/thread/shared_lock_guard.hpp> using namespace std; class threadsafe_key_value_store { private: unordered_map<int, vector<pair<int, int>>> key_to_snapid_value; unordered_map<int, unordered_map<int, int>> key_to_snapid_index; int current_snap_id; boost::shared_mutex m; public: threadsafe_key_value_store() { key_to_snapid_index.clear(); key_to_snapid_value.clear(); current_snap_id = 0; } threadsafe_key_value_store(threadsafe_key_value_store const &other) = delete; threadsafe_key_value_store operator&=(threadsafe_key_value_store const &other) = delete; void put_key_value(int key, int value) { unique_lock<boost::shared_mutex> lock1(m); if (key_to_snapid_value.find(key) != key_to_snapid_value.end()) { if (key_to_snapid_value[key].back().second == current_snap_id) { key_to_snapid_value[key].pop_back(); } } key_to_snapid_value[key].push_back(make_pair(current_snap_id, value)); key_to_snapid_index[key][current_snap_id] = key_to_snapid_value[key].size() - 1; } int get_key_value(int key, int snap_id) { boost::shared_lock_guard<boost::shared_mutex> lock(m); if (key_to_snapid_value.find(key) != key_to_snapid_value.end()) { if (key_to_snapid_index[key].find(snap_id) != key_to_snapid_index[key].end()) { return key_to_snapid_value[key][key_to_snapid_index[key][snap_id]].second; } else { auto pos = lower_bound(key_to_snapid_value[key].begin(), key_to_snapid_value[key].end(), make_pair(snap_id, INT_MAX)); if (pos != key_to_snapid_value[key].end()) { return (*pos).second; } } } throw "Key not present in kvs"; } int take_snapshot() { unique_lock<boost::shared_mutex> lock(m); int to_ret = current_snap_id; current_snap_id++; return to_ret; } }; int main() { threadsafe_key_value_store kvs; kvs.put_key_value(1, 10); kvs.put_key_value(2, 20); kvs.put_key_value(3, 30); kvs.put_key_value(4, 40); kvs.put_key_value(5, 50); kvs.put_key_value(6, 60); int csid = kvs.take_snapshot(); cout << "Key: " << 1 << " Value: " << kvs.get_key_value(1, csid) << "\n"; kvs.put_key_value(1, 100); int csid_2 = kvs.take_snapshot(); cout << "Old \t"; cout << "Key: " << 1 << " Value: " << kvs.get_key_value(1, csid) << "\n"; cout << "New \t"; cout << "Key: " << 1 << " Value: " << kvs.get_key_value(1, csid_2) << "\n"; return 0; }