payload: {"action":"created","comment":{"url":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/comments/266282778","pull_request_review_id":215400738,"id":266282778,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI2NjI4Mjc3OA==","diff_hunk":"@@ -0,0 +1,154 @@\n+# Percolator\n+\n+TiKV supports distributed transactions, which is inspired by Google's [Percolator](https://ai.google/research/pubs/pub36726.pdf). In this section, we will briefly introduce Percolator and how we make use of it in TiKV.\n+\n+## What is Percolator?\n+\n+*Percolator* is a system built by Google for incremental processing on a very large data set. Since this is just a brief introduction, you can view the full paper [here](https://ai.google/research/pubs/pub36726#) for more details. If you are already very familiar with it, you can skip this section and go directly to [Percolator in TiKV](#Percolator-in-TiKV)\n+\n+Percolator is built based on Google's BigTable, a distributed storage system that supports single-row transactions. Percolator implements distributed transactions in ACID snapshot-isolation semantics, which is not supported by BigTable. A column `c` of Percolator is actually divided into the following internal columns of BigTable:\n+\n+* `c:lock`\n+* `c:write`\n+* `c:data`\n+* `c:notify`\n+* `c:ack_O`\n+\n+Percolator also relies on a service named *timestamp oracle*. The timestamp oracle can produce timestamps in a strictly increasing order. All read and write operations need to apply for timestamps from the timestamp oracle, and a timestamp coming from the timestamp oracle will be regarded as the logical time when the read/write operation happens.\n+\n+Percolator is a multi-version storage, and a data item's version is represented by the timestamp when the transaction was committed.\n+\n+For example,\n+\n+| key | v:data | v:lock | v\"write |\n+|-----|--------|--------|---------|\n+|k1   |14:\"value2\"<br/>12:<br/>10:\"value1\"|14:primary<br/>12:<br/>10:|14:<br/>12:data@10<br/>10:|\n+\n+The table shows different versions of data for a single cell. The state shown in the table means that for key `k1`, value `\"value1\"` was committed at timestamp `12`. Then there is an uncommitted version whose value is `\"value2\"`, and it's uncommitted because there's a lock. You will understand why it is like this after understanding how transactions work.\n+\n+The remaining columns, `c:notify` and `c:ack_O`, are used for Percolator's incremental processing. After a modification, `c:notify` column is used to mark the modified cell to be dirty. Users can add some *observers* to Percolator which can do user-specified operations when they find data of their observed columns has changed. To find whether data is changed, the observers continuously scan the `notify` columns to find dirty cells. `c:ack_O` is the \"acknowledgment\" column of observer `O`, which is used to prevent a row from being incorrectly notified twice. It saves the timestamp of the observer's last execution.\n+\n+### Writing\n+\n+Percolator's transactions are committed by a 2-phase commit (2PC) algorithm. Its two phases are `Prewrite` and `Commit`.\n+\n+In `Prewrite` phase:\n+1. Get a timestamp from the timestamp oracle, and we call the timestamp `start_ts` of the transaction.\n+2. For each row involved in the transaction, put a lock in the `lock` column. At the same time, write the value to the `data` column with the timestamp `start_ts`. One of these locks will be chosen as the *primary* lock, while others are *secondary* locks. Each lock contains the transaction's `start_ts`. Each secondary lock, in addition, contains the location of the primary lock.\n+    * If there's already a lock or newer version than `start_ts`, the current transaction will be rolled back.\n+\n+And then, in the`Commit` phase:\n+1. Get another timestamp, namely `commit_ts`.\n+2. Remove the primary lock, and at the same time write a record to the `write` column with timestamp `commit_ts`, whose value records the transaction's `start_ts`. If the primary lock is missing, the commit fails.\n+3. Repeat the process above for all secondary locks.\n+\n+Once step 2 (committing the primary) is done, the whole transaction is done. It doesn't matter if the process of committing the secondary locks failed.\n+\n+Let's see the example from the paper of Percolator. Assume we are writing two rows in a single transaction. At first, the data looks like this:\n+\n+| key | bal:data     | bal:lock  | bal:write       |\n+|-----|--------------|-----------|-----------------|\n+| Bob | 6:<br/>5:$10 | 6:<br/>5: | 6:data@5<br/>5: |\n+| Joe | 6:<br/>5:$2  | 6:<br/>5: | 6:data@5<br/>5: |\n+\n+This table shows Bob and Joe's balance. Now Bob wants to transfer his $7 to Joe's account. The first step is `Prewrite`:\n+\n+1. Get the `start_ts` of the transaction. In our example, it's `7`.\n+2. For each row involved in this transaction, put a lock in the `lock` column, and write the data to the `data` column. One of the locks will be chosen as the primary lock.\n+\n+After `Prewrite`, our data looks like this:\n+\n+| key | bal:data | bal:lock | bal:write |\n+|-----|----------|----------|-----------|\n+| Bob | 7:$3<br/>6:<br>5:$10 | 7:primary<br/>6:<br/>5:         | 7:<br/>6:data@5<br/>5: |\n+| Joe | 7:$9<br/>6:<br/>5:$2 | 7:primary@Bob.bal<br/>6:<br/>5: | 7:<br/>6:data@5<br/>5: |\n+\n+Then `Commit`:\n+\n+1. Get the `commit_ts`, in our case, `8`.\n+2. Commit the primary: Remove the primary lock and write the commit record to the `write` column.\n+\n+| key | bal:data | bal:lock | bal:write |\n+|-----|----------|----------|-----------|\n+| Bob | 8:<br/>7:$3<br/>6:<br>5:$10 | 8:<br/>7:<br/>6:<br/>5: | 8:data@7<br/>7:<br/>6:data@5<br/>5: |\n+| Joe | 7:$9<br/>6:<br/>5:$2 | 7:primary@Bob.bal<br/>6:<br/>5: | 7:<br/>6:data@5<br/>5: |\n+\n+3. Commit all secondary locks to complete the writing process.\n+\n+| key | bal:data | bal:lock | bal:write |\n+|-----|----------|----------|-----------|\n+| Bob | 8:<br/>7:$3<br/>6:<br>5:$10 | 8:<br/>7:<br/>6:<br/>5: | 8:data@7<br/>7:<br/>6:data@5<br/>5: |\n+| Joe | 8:<br/>7:$9<br/>6:<br/>5:$2 | 8:<br/>7:<br/>6:<br/>5: | 8:data@7<br/>7:<br/>6:data@5<br/>5: |\n+\n+### Reading\n+\n+Reading from Percolator also requires a timestamp. The procedure to perform a read operation is as follows:\n+\n+1. Get a timestamp, `ts`.\n+2. Check if the row we are going to read is locked with a timestamp in the range `[0, ts]`;\n+    * If there is a timestamp in range `[0, ts]`, it means the row is locked by an earlier-started transaction. Then we are not sure whether that transaction will be committed before or after `ts`.","path":"src/distributed-transaction/percolator.md","position":89,"original_position":89,"commit_id":"266c29fca5f72dcf524d32ae9b0d8088227f4b33","original_commit_id":"266c29fca5f72dcf524d32ae9b0d8088227f4b33","user":{"login":"rleungx","id":35896542,"node_id":"MDQ6VXNlcjM1ODk2NTQy","avatar_url":"https://avatars3.githubusercontent.com/u/35896542?v=4","gravatar_id":"","url":"https://api.github.com/users/rleungx","html_url":"https://github.com/rleungx","followers_url":"https://api.github.com/users/rleungx/followers","following_url":"https://api.github.com/users/rleungx/following{/other_user}","gists_url":"https://api.github.com/users/rleungx/gists{/gist_id}","starred_url":"https://api.github.com/users/rleungx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rleungx/subscriptions","organizations_url":"https://api.github.com/users/rleungx/orgs","repos_url":"https://api.github.com/users/rleungx/repos","events_url":"https://api.github.com/users/rleungx/events{/privacy}","received_events_url":"https://api.github.com/users/rleungx/received_events","type":"User","site_admin":false},"body":"Do we need to mention how to deal with this situation? e.g. back off or clean up the lock? ","created_at":"2019-03-18T03:02:18Z","updated_at":"2019-03-18T03:16:23Z","html_url":"https://github.com/tikv/deep-dive-tikv/pull/24#discussion_r266282778","pull_request_url":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/24","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/comments/266282778"},"html":{"href":"https://github.com/tikv/deep-dive-tikv/pull/24#discussion_r266282778"},"pull_request":{"href":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/24"}}},"pull_request":{"url":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/24","id":244393933,"node_id":"MDExOlB1bGxSZXF1ZXN0MjQ0MzkzOTMz","html_url":"https://github.com/tikv/deep-dive-tikv/pull/24","diff_url":"https://github.com/tikv/deep-dive-tikv/pull/24.diff","patch_url":"https://github.com/tikv/deep-dive-tikv/pull/24.patch","issue_url":"https://api.github.com/repos/tikv/deep-dive-tikv/issues/24","number":24,"state":"open","locked":false,"title":"Add Percolator section","user":{"login":"MyonKeminta","id":9948422,"node_id":"MDQ6VXNlcjk5NDg0MjI=","avatar_url":"https://avatars1.githubusercontent.com/u/9948422?v=4","gravatar_id":"","url":"https://api.github.com/users/MyonKeminta","html_url":"https://github.com/MyonKeminta","followers_url":"https://api.github.com/users/MyonKeminta/followers","following_url":"https://api.github.com/users/MyonKeminta/following{/other_user}","gists_url":"https://api.github.com/users/MyonKeminta/gists{/gist_id}","starred_url":"https://api.github.com/users/MyonKeminta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MyonKeminta/subscriptions","organizations_url":"https://api.github.com/users/MyonKeminta/orgs","repos_url":"https://api.github.com/users/MyonKeminta/repos","events_url":"https://api.github.com/users/MyonKeminta/events{/privacy}","received_events_url":"https://api.github.com/users/MyonKeminta/received_events","type":"User","site_admin":false},"body":"Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>\r\n\r\nThis PR adds the Percolator chapter.\r\n\r\n~~It was difficult for me to express my mind in English and organize the structure of my text...~~","created_at":"2019-01-14T10:22:57Z","updated_at":"2019-03-18T03:16:23Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c60627080eb4f147cca3850d8bf7a6e1841da667","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/24/commits","review_comments_url":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/24/comments","review_comment_url":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/comments{/number}","comments_url":"https://api.github.com/repos/tikv/deep-dive-tikv/issues/24/comments","statuses_url":"https://api.github.com/repos/tikv/deep-dive-tikv/statuses/266c29fca5f72dcf524d32ae9b0d8088227f4b33","head":{"label":"MyonKeminta:misono/percolator","ref":"misono/percolator","sha":"266c29fca5f72dcf524d32ae9b0d8088227f4b33","user":{"login":"MyonKeminta","id":9948422,"node_id":"MDQ6VXNlcjk5NDg0MjI=","avatar_url":"https://avatars1.githubusercontent.com/u/9948422?v=4","gravatar_id":"","url":"https://api.github.com/users/MyonKeminta","html_url":"https://github.com/MyonKeminta","followers_url":"https://api.github.com/users/MyonKeminta/followers","following_url":"https://api.github.com/users/MyonKeminta/following{/other_user}","gists_url":"https://api.github.com/users/MyonKeminta/gists{/gist_id}","starred_url":"https://api.github.com/users/MyonKeminta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MyonKeminta/subscriptions","organizations_url":"https://api.github.com/users/MyonKeminta/orgs","repos_url":"https://api.github.com/users/MyonKeminta/repos","events_url":"https://api.github.com/users/MyonKeminta/events{/privacy}","received_events_url":"https://api.github.com/users/MyonKeminta/received_events","type":"User","site_admin":false},"repo":{"id":155051496,"node_id":"MDEwOlJlcG9zaXRvcnkxNTUwNTE0OTY=","name":"deep-dive-tikv","full_name":"MyonKeminta/deep-dive-tikv","private":false,"owner":{"login":"MyonKeminta","id":9948422,"node_id":"MDQ6VXNlcjk5NDg0MjI=","avatar_url":"https://avatars1.githubusercontent.com/u/9948422?v=4","gravatar_id":"","url":"https://api.github.com/users/MyonKeminta","html_url":"https://github.com/MyonKeminta","followers_url":"https://api.github.com/users/MyonKeminta/followers","following_url":"https://api.github.com/users/MyonKeminta/following{/other_user}","gists_url":"https://api.github.com/users/MyonKeminta/gists{/gist_id}","starred_url":"https://api.github.com/users/MyonKeminta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MyonKeminta/subscriptions","organizations_url":"https://api.github.com/users/MyonKeminta/orgs","repos_url":"https://api.github.com/users/MyonKeminta/repos","events_url":"https://api.github.com/users/MyonKeminta/events{/privacy}","received_events_url":"https://api.github.com/users/MyonKeminta/received_events","type":"User","site_admin":false},"html_url":"https://github.com/MyonKeminta/deep-dive-tikv","description":"How do we build a distributed, transactional key-value database - TiKV?","fork":true,"url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv","forks_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/forks","keys_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/teams","hooks_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/hooks","issue_events_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/issues/events{/number}","events_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/events","assignees_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/assignees{/user}","branches_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/branches{/branch}","tags_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/tags","blobs_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/git/refs{/sha}","trees_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/statuses/{sha}","languages_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/languages","stargazers_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/stargazers","contributors_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/contributors","subscribers_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/subscribers","subscription_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/subscription","commits_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/commits{/sha}","git_commits_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/git/commits{/sha}","comments_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/comments{/number}","issue_comment_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/issues/comments{/number}","contents_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/contents/{+path}","compare_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/merges","archive_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/downloads","issues_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/issues{/number}","pulls_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/pulls{/number}","milestones_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/milestones{/number}","notifications_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/labels{/name}","releases_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/releases{/id}","deployments_url":"https://api.github.com/repos/MyonKeminta/deep-dive-tikv/deployments","created_at":"2018-10-28T08:48:58Z","updated_at":"2018-10-28T08:49:00Z","pushed_at":"2019-03-06T06:18:52Z","git_url":"git://github.com/MyonKeminta/deep-dive-tikv.git","ssh_url":"git@github.com:MyonKeminta/deep-dive-tikv.git","clone_url":"https://github.com/MyonKeminta/deep-dive-tikv.git","svn_url":"https://github.com/MyonKeminta/deep-dive-tikv","homepage":null,"size":1039,"stargazers_count":0,"watchers_count":0,"language":"HTML","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"tikv:master","ref":"master","sha":"825aff46d431ea9ceb3e7e8be5642658072d692c","user":{"login":"tikv","id":41004122,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQxMDA0MTIy","avatar_url":"https://avatars2.githubusercontent.com/u/41004122?v=4","gravatar_id":"","url":"https://api.github.com/users/tikv","html_url":"https://github.com/tikv","followers_url":"https://api.github.com/users/tikv/followers","following_url":"https://api.github.com/users/tikv/following{/other_user}","gists_url":"https://api.github.com/users/tikv/gists{/gist_id}","starred_url":"https://api.github.com/users/tikv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tikv/subscriptions","organizations_url":"https://api.github.com/users/tikv/orgs","repos_url":"https://api.github.com/users/tikv/repos","events_url":"https://api.github.com/users/tikv/events{/privacy}","received_events_url":"https://api.github.com/users/tikv/received_events","type":"Organization","site_admin":false},"repo":{"id":146400837,"node_id":"MDEwOlJlcG9zaXRvcnkxNDY0MDA4Mzc=","name":"deep-dive-tikv","full_name":"tikv/deep-dive-tikv","private":false,"owner":{"login":"tikv","id":41004122,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQxMDA0MTIy","avatar_url":"https://avatars2.githubusercontent.com/u/41004122?v=4","gravatar_id":"","url":"https://api.github.com/users/tikv","html_url":"https://github.com/tikv","followers_url":"https://api.github.com/users/tikv/followers","following_url":"https://api.github.com/users/tikv/following{/other_user}","gists_url":"https://api.github.com/users/tikv/gists{/gist_id}","starred_url":"https://api.github.com/users/tikv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tikv/subscriptions","organizations_url":"https://api.github.com/users/tikv/orgs","repos_url":"https://api.github.com/users/tikv/repos","events_url":"https://api.github.com/users/tikv/events{/privacy}","received_events_url":"https://api.github.com/users/tikv/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/tikv/deep-dive-tikv","description":"How do we build a distributed, transactional key-value database - TiKV?","fork":false,"url":"https://api.github.com/repos/tikv/deep-dive-tikv","forks_url":"https://api.github.com/repos/tikv/deep-dive-tikv/forks","keys_url":"https://api.github.com/repos/tikv/deep-dive-tikv/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tikv/deep-dive-tikv/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tikv/deep-dive-tikv/teams","hooks_url":"https://api.github.com/repos/tikv/deep-dive-tikv/hooks","issue_events_url":"https://api.github.com/repos/tikv/deep-dive-tikv/issues/events{/number}","events_url":"https://api.github.com/repos/tikv/deep-dive-tikv/events","assignees_url":"https://api.github.com/repos/tikv/deep-dive-tikv/assignees{/user}","branches_url":"https://api.github.com/repos/tikv/deep-dive-tikv/branches{/branch}","tags_url":"https://api.github.com/repos/tikv/deep-dive-tikv/tags","blobs_url":"https://api.github.com/repos/tikv/deep-dive-tikv/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tikv/deep-dive-tikv/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tikv/deep-dive-tikv/git/refs{/sha}","trees_url":"https://api.github.com/repos/tikv/deep-dive-tikv/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tikv/deep-dive-tikv/statuses/{sha}","languages_url":"https://api.github.com/repos/tikv/deep-dive-tikv/languages","stargazers_url":"https://api.github.com/repos/tikv/deep-dive-tikv/stargazers","contributors_url":"https://api.github.com/repos/tikv/deep-dive-tikv/contributors","subscribers_url":"https://api.github.com/repos/tikv/deep-dive-tikv/subscribers","subscription_url":"https://api.github.com/repos/tikv/deep-dive-tikv/subscription","commits_url":"https://api.github.com/repos/tikv/deep-dive-tikv/commits{/sha}","git_commits_url":"https://api.github.com/repos/tikv/deep-dive-tikv/git/commits{/sha}","comments_url":"https://api.github.com/repos/tikv/deep-dive-tikv/comments{/number}","issue_comment_url":"https://api.github.com/repos/tikv/deep-dive-tikv/issues/comments{/number}","contents_url":"https://api.github.com/repos/tikv/deep-dive-tikv/contents/{+path}","compare_url":"https://api.github.com/repos/tikv/deep-dive-tikv/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tikv/deep-dive-tikv/merges","archive_url":"https://api.github.com/repos/tikv/deep-dive-tikv/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tikv/deep-dive-tikv/downloads","issues_url":"https://api.github.com/repos/tikv/deep-dive-tikv/issues{/number}","pulls_url":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls{/number}","milestones_url":"https://api.github.com/repos/tikv/deep-dive-tikv/milestones{/number}","notifications_url":"https://api.github.com/repos/tikv/deep-dive-tikv/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tikv/deep-dive-tikv/labels{/name}","releases_url":"https://api.github.com/repos/tikv/deep-dive-tikv/releases{/id}","deployments_url":"https://api.github.com/repos/tikv/deep-dive-tikv/deployments","created_at":"2018-08-28T06:18:56Z","updated_at":"2019-03-17T10:17:30Z","pushed_at":"2019-03-14T13:41:11Z","git_url":"git://github.com/tikv/deep-dive-tikv.git","ssh_url":"git@github.com:tikv/deep-dive-tikv.git","clone_url":"https://github.com/tikv/deep-dive-tikv.git","svn_url":"https://github.com/tikv/deep-dive-tikv","homepage":"https://tikv.github.io/deep-dive-tikv","size":1424,"stargazers_count":71,"watchers_count":71,"language":"HTML","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":10,"mirror_url":null,"archived":false,"open_issues_count":8,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":10,"open_issues":8,"watchers":71,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/24"},"html":{"href":"https://github.com/tikv/deep-dive-tikv/pull/24"},"issue":{"href":"https://api.github.com/repos/tikv/deep-dive-tikv/issues/24"},"comments":{"href":"https://api.github.com/repos/tikv/deep-dive-tikv/issues/24/comments"},"review_comments":{"href":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/24/comments"},"review_comment":{"href":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/tikv/deep-dive-tikv/pulls/24/commits"},"statuses":{"href":"https://api.github.com/repos/tikv/deep-dive-tikv/statuses/266c29fca5f72dcf524d32ae9b0d8088227f4b33"}},"author_association":"NONE"}}
other: {"actor":{"display_login":"rleungx"}}