Untitled

mail@pastecode.io avatar
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;
}