Time Based Key-Value Store in C++


Suppose we have to make a timebased key-value store class called TimeMap, that supports two operations.

  • set(string key, string value, int timestamp): This will store the key and value, along with the given timestamp.

  • get(string key, int timestamp): This will return a value such that set(key, value, timestamp_prev) was called previously, with timestamp_prev <= timestamp.

Now if there are multiple such values, it must return the value where the timestamp_prev value is largest. If there are no such values, it returns the empty string (""). So if we call the functions like below −

set("foo","bar",1), get("foo",1), get("foo",3), set("foo","bar2",4), set("foo",4), set("foo",5), then the outputs will be: [null, “bar”, “bar”, null, “bar2”, “bar2]

To solve this, we will follow these steps −

  • Define a map m

  • The set() method will be like

    • insert (timestamp, value) into m[key]

  • The get() method will work as follows

    • ret := an empty string

    • v := m[key]

    • low := 0 and high := size of v – 1

    • while low <= high

      • mid := low + (high – low) / 2

      • if key of v[mid] <= timestamp, then

        • ret := value of v[mid] and set low := mid + 1

      • otherwise high := mid – 1

    • return ret

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class TimeMap {
   public:
   /** Initialize your data structure here. */
   unordered_map <string, vector < pair <int, string> > > m;
   TimeMap() {
      m.clear();
   }
   void set(string key, string value, int timestamp) {
      m[key].push_back({timestamp, value});
   }
   string get(string key, int timestamp) {
      string ret = "";
      vector <pair <int, string> >& v = m[key];
      int low = 0;
      int high = v.size() - 1;
      while(low <= high){
         int mid = low + (high - low) / 2;
         if(v[mid].first <= timestamp){
            ret = v[mid].second;
            low = mid + 1;
         }else{
            high = mid - 1;
         }
      }
      return ret;
   }
};
main(){
   TimeMap ob;
   (ob.set("foo","bar",1));
   cout << (ob.get("foo", 1)) << endl;
   cout << (ob.get("foo", 3)) << endl;
   (ob.set("foo","bar2",4));
   cout << (ob.get("foo", 4)) << endl;
   cout << (ob.get("foo", 5)) << endl;
}

Input

Initialize it then call set and get methods as follows:
set("foo","bar",1))
get("foo", 1))
get("foo", 3))
set("foo","bar2",4))
get("foo", 4))
get("foo", 5))

Output

bar
bar
bar2
bar2

Updated on: 30-Apr-2020

510 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements