{"action":"created","comment":{"url":"https://api.github.com/repos/pingcap/tikv/pulls/comments/74176556","id":74176556,"diff_hunk":"@@ -0,0 +1,187 @@\n+// Copyright 2016 PingCAP, Inc.\n+//\n+// Licensed under the Apache License, Version 2.0 (the \"License\");\n+// you may not use this file except in compliance with the License.\n+// You may obtain a copy of the License at\n+//\n+//     http://www.apache.org/licenses/LICENSE-2.0\n+//\n+// Unless required by applicable law or agreed to in writing, software\n+// distributed under the License is distributed on an \"AS IS\" BASIS,\n+// See the License for the specific language governing permissions and\n+// limitations under the License.\n+\n+use storage::engine::{Snapshot, Cursor};\n+use storage::{Key, Value, CF_LOCK, CF_WRITE};\n+use util::codec::number::NumberDecoder;\n+use super::{Error, Result};\n+use super::lock::Lock;\n+\n+pub struct MvccReader<'a> {\n+    snapshot: &'a Snapshot,\n+    // cursors are used for speeding up scans.\n+    data_cursor: Option<Box<Cursor + 'a>>,\n+    lock_cursor: Option<Box<Cursor + 'a>>,\n+    write_cursor: Option<Box<Cursor + 'a>>,\n+}\n+\n+impl<'a> MvccReader<'a> {\n+    pub fn new(snapshot: &Snapshot) -> MvccReader {\n+        MvccReader {\n+            snapshot: snapshot,\n+            data_cursor: None,\n+            lock_cursor: None,\n+            write_cursor: None,\n+        }\n+    }\n+\n+    fn load_data(&mut self, key: &Key, ts: u64) -> Result<Option<Value>> {\n+        let k = key.append_ts(ts);\n+        if let Some(ref mut cursor) = self.data_cursor {\n+            cursor.get(&k).map(|x| x.map(|x| x.to_vec())).map_err(Error::from)\n+        } else {\n+            self.snapshot.get(&k).map_err(Error::from)\n+        }\n+    }\n+\n+    pub fn load_lock(&mut self, key: &Key) -> Result<Option<Lock>> {\n+        if let Some(ref mut cursor) = self.lock_cursor {\n+            match try!(cursor.get(&key)) {\n+                Some(v) => Ok(Some(try!(Lock::parse(v)))),\n+                None => Ok(None),\n+            }\n+        } else {\n+            match try!(self.snapshot.get_cf(CF_LOCK, &key)) {\n+                Some(v) => Ok(Some(try!(Lock::parse(&v)))),\n+                None => Ok(None),\n+            }\n+        }\n+    }\n+\n+    pub fn seek_write(&mut self, key: &Key, ts: u64) -> Result<Option<(u64, u64)>> {\n+        self.seek_write_impl(key, ts, false)\n+    }\n+\n+    pub fn reverse_seek_write(&mut self, key: &Key, ts: u64) -> Result<Option<(u64, u64)>> {\n+        self.seek_write_impl(key, ts, true)\n+    }\n+\n+    fn seek_write_impl(&mut self, key: &Key, ts: u64, reverse: bool) -> Result<Option<(u64, u64)>> {\n+        let (k, v) = {\n+            if self.write_cursor.is_none() {\n+                self.write_cursor = Some(try!(self.snapshot.iter_cf(CF_WRITE)));\n+            }\n+            let mut cursor = self.write_cursor.as_mut().unwrap();\n+            let ok = if reverse {\n+                try!(cursor.reverse_seek(&key.append_ts(ts)))\n+            } else {\n+                try!(cursor.seek(&key.append_ts(ts)))\n+            };\n+            if !ok {\n+                return Ok(None);\n+            }\n+            (cursor.key().to_vec(), cursor.value().to_vec())\n+        };\n+        let (k, s, c) = try!(self.decode_write(k, v));\n+        if &k == key {\n+            Ok(Some((s, c)))\n+        } else {\n+            Ok(None)\n+        }\n+    }\n+\n+    fn decode_write(&self, key: Vec<u8>, value: Vec<u8>) -> Result<(Key, u64, u64)> {\n+        let k = Key::from_encoded(key);\n+        let commit_ts = try!(k.decode_ts());\n+        let key = try!(k.truncate_ts());\n+        let start_ts = try!(value.as_slice().decode_var_u64());\n+        Ok((key, start_ts, commit_ts))\n+    }\n+\n+    pub fn get(&mut self, key: &Key, ts: u64) -> Result<Option<Value>> {\n+        // Check for locks that signal concurrent writes.\n+        if let Some(lock) = try!(self.load_lock(key)) {\n+            if lock.ts <= ts {\n+                // There is a pending lock. Client should wait or clean it.\n+                return Err(Error::KeyIsLocked {\n+                    key: try!(key.raw()),\n+                    primary: lock.primary,\n+                    ts: lock.ts,\n+                });\n+            }\n+        }\n+        match try!(self.seek_write(key, ts)) {\n+            Some((start_ts, _)) => self.load_data(key, start_ts),\n+            None => Ok(None),\n+        }\n+    }\n+\n+    pub fn get_txn_commit_ts(&mut self, key: &Key, start_ts: u64) -> Result<Option<u64>> {\n+        match try!(self.reverse_seek_write(key, start_ts)) {\n+            Some((s, commit_ts)) if s == start_ts => Ok(Some(commit_ts)),\n+            _ => Ok(None),\n+        }\n+    }\n+\n+    fn create_data_cursor(&mut self) -> Result<()> {\n+        if self.data_cursor.is_none() {\n+            self.data_cursor = Some(try!(self.snapshot.iter()));\n+        }\n+        Ok(())\n+    }\n+\n+    pub fn seek(&mut self, mut key: Key, ts: u64) -> Result<Option<(Key, Value)>> {","path":"src/storage/mvcc/reader.rs","position":133,"original_position":133,"commit_id":"abb9f4839d4d220a6f0648bcca31f860021928e9","original_commit_id":"abb9f4839d4d220a6f0648bcca31f860021928e9","user":{"login":"disksing","id":12077877,"avatar_url":"https://avatars.githubusercontent.com/u/12077877?v=3","gravatar_id":"","url":"https://api.github.com/users/disksing","html_url":"https://github.com/disksing","followers_url":"https://api.github.com/users/disksing/followers","following_url":"https://api.github.com/users/disksing/following{/other_user}","gists_url":"https://api.github.com/users/disksing/gists{/gist_id}","starred_url":"https://api.github.com/users/disksing/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/disksing/subscriptions","organizations_url":"https://api.github.com/users/disksing/orgs","repos_url":"https://api.github.com/users/disksing/repos","events_url":"https://api.github.com/users/disksing/events{/privacy}","received_events_url":"https://api.github.com/users/disksing/received_events","type":"User","site_admin":false},"body":"`seek()` should only return values that are written before `ts`.","created_at":"2016-08-10T02:19:24Z","updated_at":"2016-08-10T02:19:24Z","html_url":"https://github.com/pingcap/tikv/pull/915#discussion_r74176556","pull_request_url":"https://api.github.com/repos/pingcap/tikv/pulls/915","_links":{"self":{"href":"https://api.github.com/repos/pingcap/tikv/pulls/comments/74176556"},"html":{"href":"https://github.com/pingcap/tikv/pull/915#discussion_r74176556"},"pull_request":{"href":"https://api.github.com/repos/pingcap/tikv/pulls/915"}}},"pull_request":{"url":"https://api.github.com/repos/pingcap/tikv/pulls/915","id":80204820,"html_url":"https://github.com/pingcap/tikv/pull/915","diff_url":"https://github.com/pingcap/tikv/pull/915.diff","patch_url":"https://github.com/pingcap/tikv/pull/915.patch","issue_url":"https://api.github.com/repos/pingcap/tikv/issues/915","number":915,"state":"open","locked":false,"title":"storage: remove meta, save commit log in CF_WRITE.","user":{"login":"disksing","id":12077877,"avatar_url":"https://avatars.githubusercontent.com/u/12077877?v=3","gravatar_id":"","url":"https://api.github.com/users/disksing","html_url":"https://github.com/disksing","followers_url":"https://api.github.com/users/disksing/followers","following_url":"https://api.github.com/users/disksing/following{/other_user}","gists_url":"https://api.github.com/users/disksing/gists{/gist_id}","starred_url":"https://api.github.com/users/disksing/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/disksing/subscriptions","organizations_url":"https://api.github.com/users/disksing/orgs","repos_url":"https://api.github.com/users/disksing/repos","events_url":"https://api.github.com/users/disksing/events{/privacy}","received_events_url":"https://api.github.com/users/disksing/received_events","type":"User","site_admin":false},"body":"@siddontang \r\n@zhangjinpeng1987 \r\n@BusyJay \r\n@ngaut \r\n","created_at":"2016-08-05T08:10:11Z","updated_at":"2016-08-10T02:19:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"57c5c2c12749f467925960fbadcf4beb3ce615e6","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/pingcap/tikv/pulls/915/commits","review_comments_url":"https://api.github.com/repos/pingcap/tikv/pulls/915/comments","review_comment_url":"https://api.github.com/repos/pingcap/tikv/pulls/comments{/number}","comments_url":"https://api.github.com/repos/pingcap/tikv/issues/915/comments","statuses_url":"https://api.github.com/repos/pingcap/tikv/statuses/abb9f4839d4d220a6f0648bcca31f860021928e9","head":{"label":"pingcap:disksing/write-cf","ref":"disksing/write-cf","sha":"abb9f4839d4d220a6f0648bcca31f860021928e9","user":{"login":"pingcap","id":11855343,"avatar_url":"https://avatars.githubusercontent.com/u/11855343?v=3","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"repo":{"id":48833910,"name":"tikv","full_name":"pingcap/tikv","owner":{"login":"pingcap","id":11855343,"avatar_url":"https://avatars.githubusercontent.com/u/11855343?v=3","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pingcap/tikv","description":"Distributed transactional key value database powered by Rust and Raft","fork":false,"url":"https://api.github.com/repos/pingcap/tikv","forks_url":"https://api.github.com/repos/pingcap/tikv/forks","keys_url":"https://api.github.com/repos/pingcap/tikv/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pingcap/tikv/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pingcap/tikv/teams","hooks_url":"https://api.github.com/repos/pingcap/tikv/hooks","issue_events_url":"https://api.github.com/repos/pingcap/tikv/issues/events{/number}","events_url":"https://api.github.com/repos/pingcap/tikv/events","assignees_url":"https://api.github.com/repos/pingcap/tikv/assignees{/user}","branches_url":"https://api.github.com/repos/pingcap/tikv/branches{/branch}","tags_url":"https://api.github.com/repos/pingcap/tikv/tags","blobs_url":"https://api.github.com/repos/pingcap/tikv/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pingcap/tikv/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pingcap/tikv/git/refs{/sha}","trees_url":"https://api.github.com/repos/pingcap/tikv/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pingcap/tikv/statuses/{sha}","languages_url":"https://api.github.com/repos/pingcap/tikv/languages","stargazers_url":"https://api.github.com/repos/pingcap/tikv/stargazers","contributors_url":"https://api.github.com/repos/pingcap/tikv/contributors","subscribers_url":"https://api.github.com/repos/pingcap/tikv/subscribers","subscription_url":"https://api.github.com/repos/pingcap/tikv/subscription","commits_url":"https://api.github.com/repos/pingcap/tikv/commits{/sha}","git_commits_url":"https://api.github.com/repos/pingcap/tikv/git/commits{/sha}","comments_url":"https://api.github.com/repos/pingcap/tikv/comments{/number}","issue_comment_url":"https://api.github.com/repos/pingcap/tikv/issues/comments{/number}","contents_url":"https://api.github.com/repos/pingcap/tikv/contents/{+path}","compare_url":"https://api.github.com/repos/pingcap/tikv/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pingcap/tikv/merges","archive_url":"https://api.github.com/repos/pingcap/tikv/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pingcap/tikv/downloads","issues_url":"https://api.github.com/repos/pingcap/tikv/issues{/number}","pulls_url":"https://api.github.com/repos/pingcap/tikv/pulls{/number}","milestones_url":"https://api.github.com/repos/pingcap/tikv/milestones{/number}","notifications_url":"https://api.github.com/repos/pingcap/tikv/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pingcap/tikv/labels{/name}","releases_url":"https://api.github.com/repos/pingcap/tikv/releases{/id}","deployments_url":"https://api.github.com/repos/pingcap/tikv/deployments","created_at":"2015-12-31T04:51:32Z","updated_at":"2016-08-09T17:57:08Z","pushed_at":"2016-08-09T11:10:50Z","git_url":"git://github.com/pingcap/tikv.git","ssh_url":"git@github.com:pingcap/tikv.git","clone_url":"https://github.com/pingcap/tikv.git","svn_url":"https://github.com/pingcap/tikv","homepage":"","size":5239,"stargazers_count":872,"watchers_count":872,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":69,"mirror_url":null,"open_issues_count":34,"forks":69,"open_issues":34,"watchers":872,"default_branch":"master"}},"base":{"label":"pingcap:master","ref":"master","sha":"80683ca4c60b2ef0c384183f841b18d40355a3e8","user":{"login":"pingcap","id":11855343,"avatar_url":"https://avatars.githubusercontent.com/u/11855343?v=3","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"repo":{"id":48833910,"name":"tikv","full_name":"pingcap/tikv","owner":{"login":"pingcap","id":11855343,"avatar_url":"https://avatars.githubusercontent.com/u/11855343?v=3","gravatar_id":"","url":"https://api.github.com/users/pingcap","html_url":"https://github.com/pingcap","followers_url":"https://api.github.com/users/pingcap/followers","following_url":"https://api.github.com/users/pingcap/following{/other_user}","gists_url":"https://api.github.com/users/pingcap/gists{/gist_id}","starred_url":"https://api.github.com/users/pingcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pingcap/subscriptions","organizations_url":"https://api.github.com/users/pingcap/orgs","repos_url":"https://api.github.com/users/pingcap/repos","events_url":"https://api.github.com/users/pingcap/events{/privacy}","received_events_url":"https://api.github.com/users/pingcap/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pingcap/tikv","description":"Distributed transactional key value database powered by Rust and Raft","fork":false,"url":"https://api.github.com/repos/pingcap/tikv","forks_url":"https://api.github.com/repos/pingcap/tikv/forks","keys_url":"https://api.github.com/repos/pingcap/tikv/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pingcap/tikv/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pingcap/tikv/teams","hooks_url":"https://api.github.com/repos/pingcap/tikv/hooks","issue_events_url":"https://api.github.com/repos/pingcap/tikv/issues/events{/number}","events_url":"https://api.github.com/repos/pingcap/tikv/events","assignees_url":"https://api.github.com/repos/pingcap/tikv/assignees{/user}","branches_url":"https://api.github.com/repos/pingcap/tikv/branches{/branch}","tags_url":"https://api.github.com/repos/pingcap/tikv/tags","blobs_url":"https://api.github.com/repos/pingcap/tikv/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pingcap/tikv/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pingcap/tikv/git/refs{/sha}","trees_url":"https://api.github.com/repos/pingcap/tikv/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pingcap/tikv/statuses/{sha}","languages_url":"https://api.github.com/repos/pingcap/tikv/languages","stargazers_url":"https://api.github.com/repos/pingcap/tikv/stargazers","contributors_url":"https://api.github.com/repos/pingcap/tikv/contributors","subscribers_url":"https://api.github.com/repos/pingcap/tikv/subscribers","subscription_url":"https://api.github.com/repos/pingcap/tikv/subscription","commits_url":"https://api.github.com/repos/pingcap/tikv/commits{/sha}","git_commits_url":"https://api.github.com/repos/pingcap/tikv/git/commits{/sha}","comments_url":"https://api.github.com/repos/pingcap/tikv/comments{/number}","issue_comment_url":"https://api.github.com/repos/pingcap/tikv/issues/comments{/number}","contents_url":"https://api.github.com/repos/pingcap/tikv/contents/{+path}","compare_url":"https://api.github.com/repos/pingcap/tikv/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pingcap/tikv/merges","archive_url":"https://api.github.com/repos/pingcap/tikv/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pingcap/tikv/downloads","issues_url":"https://api.github.com/repos/pingcap/tikv/issues{/number}","pulls_url":"https://api.github.com/repos/pingcap/tikv/pulls{/number}","milestones_url":"https://api.github.com/repos/pingcap/tikv/milestones{/number}","notifications_url":"https://api.github.com/repos/pingcap/tikv/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pingcap/tikv/labels{/name}","releases_url":"https://api.github.com/repos/pingcap/tikv/releases{/id}","deployments_url":"https://api.github.com/repos/pingcap/tikv/deployments","created_at":"2015-12-31T04:51:32Z","updated_at":"2016-08-09T17:57:08Z","pushed_at":"2016-08-09T11:10:50Z","git_url":"git://github.com/pingcap/tikv.git","ssh_url":"git@github.com:pingcap/tikv.git","clone_url":"https://github.com/pingcap/tikv.git","svn_url":"https://github.com/pingcap/tikv","homepage":"","size":5239,"stargazers_count":872,"watchers_count":872,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":69,"mirror_url":null,"open_issues_count":34,"forks":69,"open_issues":34,"watchers":872,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/pingcap/tikv/pulls/915"},"html":{"href":"https://github.com/pingcap/tikv/pull/915"},"issue":{"href":"https://api.github.com/repos/pingcap/tikv/issues/915"},"comments":{"href":"https://api.github.com/repos/pingcap/tikv/issues/915/comments"},"review_comments":{"href":"https://api.github.com/repos/pingcap/tikv/pulls/915/comments"},"review_comment":{"href":"https://api.github.com/repos/pingcap/tikv/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/pingcap/tikv/pulls/915/commits"},"statuses":{"href":"https://api.github.com/repos/pingcap/tikv/statuses/abb9f4839d4d220a6f0648bcca31f860021928e9"}}}}
{"actor":{"display_login":"disksing"}}