{"action":"created","comment":{"url":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/comments/82339860","pull_request_review_id":3254121,"id":82339860,"diff_hunk":"@@ -0,0 +1,87 @@\n+package in.ashwanthkumar.suuchi.store\n+\n+import in.ashwanthkumar.suuchi.store.Store\n+import in.ashwanthkumar.suuchi.utils.DateUtils\n+\n+import scala.util.hashing.MurmurHash3\n+\n+\n+object Versions {\n+  def fromString(versionString: String) = versionString.split('|').map(_.toLong)\n+  def toString(versions: List[Long]) = versions.map(_.toString).mkString(\"|\")\n+}\n+\n+object VersionedStore {\n+  val VERSION_PREFIX = \"V_\"\n+  val DATA_PREFIX = \"D_\"\n+  def vkey(key: Array[Byte]) = VERSION_PREFIX.getBytes ++ key\n+  def dkey(key: Array[Byte], version: Long) = DATA_PREFIX.getBytes ++ key ++ version.toString.getBytes\n+}\n+\n+class VersionedStore(store: Store, numVersions: Int) extends Store with DeleteStore with DateUtils {\n+  import VersionedStore._\n+  val SYNC_SLOTS = Array.fill(8192)(new Object)\n+\n+  override def get(key: Array[Byte]) : Option[Array[Byte]] = {\n+    // fetch version record\n+    val vRecord = store.get(vkey(key))\n+    if(vRecord.isEmpty) None\n+    else {\n+      val versions = Versions.fromString(new String(vRecord.get))\n+      get(key, versions.max)\n+    }\n+  }\n+\n+  def get(key: Array[Byte], version: Long) : Option[Array[Byte]] = {\n+    store.get(dkey(key, version))\n+  }\n+\n+  override def put(key: Array[Byte], value: Array[Byte]): Boolean = {\n+    val nowMs = now\n+\n+    // atomically update version metadata\n+    val versions = atomicUpdate(key, nowMs)\n+\n+    // remove oldest version, if we've exceeded max # of versions per record\n+    if(versions.size > numVersions) removeData(key, versions.min)\n+\n+    // Write out the actual data record\n+    store.put(dkey(key, versions.max), value)\n+\n+  }\n+\n+  def atomicUpdate(key: Array[Byte], version: Long) = {\n+    val versionKey = vkey(key)\n+    val absHash = math.abs(MurmurHash3.arrayHash(versionKey))\n+    // Synchronizing the version metadata update part alone\n+    val monitor = SYNC_SLOTS(absHash % SYNC_SLOTS.length)\n+    val versions  = monitor.synchronized {\n+      val vRecord = store.get(versionKey)\n+      val updatedVersions = vRecord.map(bytes => version :: Versions.fromString(new String(bytes)).toList).getOrElse(List(version))","path":"suuchi-core/src/main/scala/in/ashwanthkumar/suuchi/store/VersionedStore.scala","position":60,"original_position":60,"commit_id":"4cc7fefcc0c1a287dd8a9697946542e40e1bec56","original_commit_id":"4cc7fefcc0c1a287dd8a9697946542e40e1bec56","user":{"login":"brewkode","id":639214,"avatar_url":"https://avatars.githubusercontent.com/u/639214?v=3","gravatar_id":"","url":"https://api.github.com/users/brewkode","html_url":"https://github.com/brewkode","followers_url":"https://api.github.com/users/brewkode/followers","following_url":"https://api.github.com/users/brewkode/following{/other_user}","gists_url":"https://api.github.com/users/brewkode/gists{/gist_id}","starred_url":"https://api.github.com/users/brewkode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brewkode/subscriptions","organizations_url":"https://api.github.com/users/brewkode/orgs","repos_url":"https://api.github.com/users/brewkode/repos","events_url":"https://api.github.com/users/brewkode/events{/privacy}","received_events_url":"https://api.github.com/users/brewkode/received_events","type":"User","site_admin":false},"body":"Dint quite understand it.","created_at":"2016-10-07T07:23:04Z","updated_at":"2016-10-07T07:24:24Z","html_url":"https://github.com/ashwanthkumar/suuchi/pull/44#discussion_r82339860","pull_request_url":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/44","_links":{"self":{"href":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/comments/82339860"},"html":{"href":"https://github.com/ashwanthkumar/suuchi/pull/44#discussion_r82339860"},"pull_request":{"href":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/44"}}},"pull_request":{"url":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/44","id":88386420,"html_url":"https://github.com/ashwanthkumar/suuchi/pull/44","diff_url":"https://github.com/ashwanthkumar/suuchi/pull/44.diff","patch_url":"https://github.com/ashwanthkumar/suuchi/pull/44.patch","issue_url":"https://api.github.com/repos/ashwanthkumar/suuchi/issues/44","number":44,"state":"open","locked":false,"title":"Adding first-class support for versioned store","user":{"login":"brewkode","id":639214,"avatar_url":"https://avatars.githubusercontent.com/u/639214?v=3","gravatar_id":"","url":"https://api.github.com/users/brewkode","html_url":"https://github.com/brewkode","followers_url":"https://api.github.com/users/brewkode/followers","following_url":"https://api.github.com/users/brewkode/following{/other_user}","gists_url":"https://api.github.com/users/brewkode/gists{/gist_id}","starred_url":"https://api.github.com/users/brewkode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brewkode/subscriptions","organizations_url":"https://api.github.com/users/brewkode/orgs","repos_url":"https://api.github.com/users/brewkode/repos","events_url":"https://api.github.com/users/brewkode/events{/privacy}","received_events_url":"https://api.github.com/users/brewkode/received_events","type":"User","site_admin":false},"body":"Added a versioned store that wraps around any suuchi.Store implementation and provides versioning support for keys\r\nDifferentiates Version records & Actual data records with a prefix so that scans for versions (if need be) can be sped up\r\nExplicitly made this project source/target to be java 1.8\r\n\r\n@ashwanthkumar Please take a look. ","created_at":"2016-10-07T06:22:20Z","updated_at":"2016-10-07T07:24:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2c403201b1a8e32e49537c9ea3c1b43d2598f823","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/44/commits","review_comments_url":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/44/comments","review_comment_url":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ashwanthkumar/suuchi/issues/44/comments","statuses_url":"https://api.github.com/repos/ashwanthkumar/suuchi/statuses/4cc7fefcc0c1a287dd8a9697946542e40e1bec56","head":{"label":"ashwanthkumar:versioned-store","ref":"versioned-store","sha":"4cc7fefcc0c1a287dd8a9697946542e40e1bec56","user":{"login":"ashwanthkumar","id":600279,"avatar_url":"https://avatars.githubusercontent.com/u/600279?v=3","gravatar_id":"","url":"https://api.github.com/users/ashwanthkumar","html_url":"https://github.com/ashwanthkumar","followers_url":"https://api.github.com/users/ashwanthkumar/followers","following_url":"https://api.github.com/users/ashwanthkumar/following{/other_user}","gists_url":"https://api.github.com/users/ashwanthkumar/gists{/gist_id}","starred_url":"https://api.github.com/users/ashwanthkumar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ashwanthkumar/subscriptions","organizations_url":"https://api.github.com/users/ashwanthkumar/orgs","repos_url":"https://api.github.com/users/ashwanthkumar/repos","events_url":"https://api.github.com/users/ashwanthkumar/events{/privacy}","received_events_url":"https://api.github.com/users/ashwanthkumar/received_events","type":"User","site_admin":false},"repo":{"id":42899775,"name":"suuchi","full_name":"ashwanthkumar/suuchi","owner":{"login":"ashwanthkumar","id":600279,"avatar_url":"https://avatars.githubusercontent.com/u/600279?v=3","gravatar_id":"","url":"https://api.github.com/users/ashwanthkumar","html_url":"https://github.com/ashwanthkumar","followers_url":"https://api.github.com/users/ashwanthkumar/followers","following_url":"https://api.github.com/users/ashwanthkumar/following{/other_user}","gists_url":"https://api.github.com/users/ashwanthkumar/gists{/gist_id}","starred_url":"https://api.github.com/users/ashwanthkumar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ashwanthkumar/subscriptions","organizations_url":"https://api.github.com/users/ashwanthkumar/orgs","repos_url":"https://api.github.com/users/ashwanthkumar/repos","events_url":"https://api.github.com/users/ashwanthkumar/events{/privacy}","received_events_url":"https://api.github.com/users/ashwanthkumar/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ashwanthkumar/suuchi","description":"सूचि - Toolkit to build distributed Data Systems","fork":false,"url":"https://api.github.com/repos/ashwanthkumar/suuchi","forks_url":"https://api.github.com/repos/ashwanthkumar/suuchi/forks","keys_url":"https://api.github.com/repos/ashwanthkumar/suuchi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ashwanthkumar/suuchi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ashwanthkumar/suuchi/teams","hooks_url":"https://api.github.com/repos/ashwanthkumar/suuchi/hooks","issue_events_url":"https://api.github.com/repos/ashwanthkumar/suuchi/issues/events{/number}","events_url":"https://api.github.com/repos/ashwanthkumar/suuchi/events","assignees_url":"https://api.github.com/repos/ashwanthkumar/suuchi/assignees{/user}","branches_url":"https://api.github.com/repos/ashwanthkumar/suuchi/branches{/branch}","tags_url":"https://api.github.com/repos/ashwanthkumar/suuchi/tags","blobs_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/refs{/sha}","trees_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ashwanthkumar/suuchi/statuses/{sha}","languages_url":"https://api.github.com/repos/ashwanthkumar/suuchi/languages","stargazers_url":"https://api.github.com/repos/ashwanthkumar/suuchi/stargazers","contributors_url":"https://api.github.com/repos/ashwanthkumar/suuchi/contributors","subscribers_url":"https://api.github.com/repos/ashwanthkumar/suuchi/subscribers","subscription_url":"https://api.github.com/repos/ashwanthkumar/suuchi/subscription","commits_url":"https://api.github.com/repos/ashwanthkumar/suuchi/commits{/sha}","git_commits_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/commits{/sha}","comments_url":"https://api.github.com/repos/ashwanthkumar/suuchi/comments{/number}","issue_comment_url":"https://api.github.com/repos/ashwanthkumar/suuchi/issues/comments{/number}","contents_url":"https://api.github.com/repos/ashwanthkumar/suuchi/contents/{+path}","compare_url":"https://api.github.com/repos/ashwanthkumar/suuchi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ashwanthkumar/suuchi/merges","archive_url":"https://api.github.com/repos/ashwanthkumar/suuchi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ashwanthkumar/suuchi/downloads","issues_url":"https://api.github.com/repos/ashwanthkumar/suuchi/issues{/number}","pulls_url":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls{/number}","milestones_url":"https://api.github.com/repos/ashwanthkumar/suuchi/milestones{/number}","notifications_url":"https://api.github.com/repos/ashwanthkumar/suuchi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ashwanthkumar/suuchi/labels{/name}","releases_url":"https://api.github.com/repos/ashwanthkumar/suuchi/releases{/id}","deployments_url":"https://api.github.com/repos/ashwanthkumar/suuchi/deployments","created_at":"2015-09-21T23:42:33Z","updated_at":"2016-10-06T06:44:42Z","pushed_at":"2016-10-07T06:53:36Z","git_url":"git://github.com/ashwanthkumar/suuchi.git","ssh_url":"git@github.com:ashwanthkumar/suuchi.git","clone_url":"https://github.com/ashwanthkumar/suuchi.git","svn_url":"https://github.com/ashwanthkumar/suuchi","homepage":"https://ashwanthkumar.github.io/suuchi/","size":604,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":14,"forks":0,"open_issues":14,"watchers":0,"default_branch":"master"}},"base":{"label":"ashwanthkumar:master","ref":"master","sha":"110d7eb39f6332941bbc94562bcc4de2149083e5","user":{"login":"ashwanthkumar","id":600279,"avatar_url":"https://avatars.githubusercontent.com/u/600279?v=3","gravatar_id":"","url":"https://api.github.com/users/ashwanthkumar","html_url":"https://github.com/ashwanthkumar","followers_url":"https://api.github.com/users/ashwanthkumar/followers","following_url":"https://api.github.com/users/ashwanthkumar/following{/other_user}","gists_url":"https://api.github.com/users/ashwanthkumar/gists{/gist_id}","starred_url":"https://api.github.com/users/ashwanthkumar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ashwanthkumar/subscriptions","organizations_url":"https://api.github.com/users/ashwanthkumar/orgs","repos_url":"https://api.github.com/users/ashwanthkumar/repos","events_url":"https://api.github.com/users/ashwanthkumar/events{/privacy}","received_events_url":"https://api.github.com/users/ashwanthkumar/received_events","type":"User","site_admin":false},"repo":{"id":42899775,"name":"suuchi","full_name":"ashwanthkumar/suuchi","owner":{"login":"ashwanthkumar","id":600279,"avatar_url":"https://avatars.githubusercontent.com/u/600279?v=3","gravatar_id":"","url":"https://api.github.com/users/ashwanthkumar","html_url":"https://github.com/ashwanthkumar","followers_url":"https://api.github.com/users/ashwanthkumar/followers","following_url":"https://api.github.com/users/ashwanthkumar/following{/other_user}","gists_url":"https://api.github.com/users/ashwanthkumar/gists{/gist_id}","starred_url":"https://api.github.com/users/ashwanthkumar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ashwanthkumar/subscriptions","organizations_url":"https://api.github.com/users/ashwanthkumar/orgs","repos_url":"https://api.github.com/users/ashwanthkumar/repos","events_url":"https://api.github.com/users/ashwanthkumar/events{/privacy}","received_events_url":"https://api.github.com/users/ashwanthkumar/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ashwanthkumar/suuchi","description":"सूचि - Toolkit to build distributed Data Systems","fork":false,"url":"https://api.github.com/repos/ashwanthkumar/suuchi","forks_url":"https://api.github.com/repos/ashwanthkumar/suuchi/forks","keys_url":"https://api.github.com/repos/ashwanthkumar/suuchi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ashwanthkumar/suuchi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ashwanthkumar/suuchi/teams","hooks_url":"https://api.github.com/repos/ashwanthkumar/suuchi/hooks","issue_events_url":"https://api.github.com/repos/ashwanthkumar/suuchi/issues/events{/number}","events_url":"https://api.github.com/repos/ashwanthkumar/suuchi/events","assignees_url":"https://api.github.com/repos/ashwanthkumar/suuchi/assignees{/user}","branches_url":"https://api.github.com/repos/ashwanthkumar/suuchi/branches{/branch}","tags_url":"https://api.github.com/repos/ashwanthkumar/suuchi/tags","blobs_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/refs{/sha}","trees_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ashwanthkumar/suuchi/statuses/{sha}","languages_url":"https://api.github.com/repos/ashwanthkumar/suuchi/languages","stargazers_url":"https://api.github.com/repos/ashwanthkumar/suuchi/stargazers","contributors_url":"https://api.github.com/repos/ashwanthkumar/suuchi/contributors","subscribers_url":"https://api.github.com/repos/ashwanthkumar/suuchi/subscribers","subscription_url":"https://api.github.com/repos/ashwanthkumar/suuchi/subscription","commits_url":"https://api.github.com/repos/ashwanthkumar/suuchi/commits{/sha}","git_commits_url":"https://api.github.com/repos/ashwanthkumar/suuchi/git/commits{/sha}","comments_url":"https://api.github.com/repos/ashwanthkumar/suuchi/comments{/number}","issue_comment_url":"https://api.github.com/repos/ashwanthkumar/suuchi/issues/comments{/number}","contents_url":"https://api.github.com/repos/ashwanthkumar/suuchi/contents/{+path}","compare_url":"https://api.github.com/repos/ashwanthkumar/suuchi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ashwanthkumar/suuchi/merges","archive_url":"https://api.github.com/repos/ashwanthkumar/suuchi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ashwanthkumar/suuchi/downloads","issues_url":"https://api.github.com/repos/ashwanthkumar/suuchi/issues{/number}","pulls_url":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls{/number}","milestones_url":"https://api.github.com/repos/ashwanthkumar/suuchi/milestones{/number}","notifications_url":"https://api.github.com/repos/ashwanthkumar/suuchi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ashwanthkumar/suuchi/labels{/name}","releases_url":"https://api.github.com/repos/ashwanthkumar/suuchi/releases{/id}","deployments_url":"https://api.github.com/repos/ashwanthkumar/suuchi/deployments","created_at":"2015-09-21T23:42:33Z","updated_at":"2016-10-06T06:44:42Z","pushed_at":"2016-10-07T06:53:36Z","git_url":"git://github.com/ashwanthkumar/suuchi.git","ssh_url":"git@github.com:ashwanthkumar/suuchi.git","clone_url":"https://github.com/ashwanthkumar/suuchi.git","svn_url":"https://github.com/ashwanthkumar/suuchi","homepage":"https://ashwanthkumar.github.io/suuchi/","size":604,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":14,"forks":0,"open_issues":14,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/44"},"html":{"href":"https://github.com/ashwanthkumar/suuchi/pull/44"},"issue":{"href":"https://api.github.com/repos/ashwanthkumar/suuchi/issues/44"},"comments":{"href":"https://api.github.com/repos/ashwanthkumar/suuchi/issues/44/comments"},"review_comments":{"href":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/44/comments"},"review_comment":{"href":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ashwanthkumar/suuchi/pulls/44/commits"},"statuses":{"href":"https://api.github.com/repos/ashwanthkumar/suuchi/statuses/4cc7fefcc0c1a287dd8a9697946542e40e1bec56"}}}}
{"actor":{"display_login":"brewkode"}}