{"action":"created","comment":{"url":"https://api.github.com/repos/cockroachdb/cockroach/pulls/comments/32065888","id":32065888,"diff_hunk":"@@ -0,0 +1,426 @@\n+// Copyright 2015 The Cockroach Authors.\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+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n+// implied. See the License for the specific language governing\n+// permissions and limitations under the License. See the AUTHORS file\n+// for names of contributors.\n+//\n+// Author: Peter Mattis (peter@cockroachlabs.com)\n+\n+package client\n+\n+import (\n+\t\"fmt\"\n+\n+\t\"github.com/cockroachdb/cockroach/proto\"\n+\tgogoproto \"github.com/gogo/protobuf/proto\"\n+)\n+\n+// Batch provides for the parallel execution of a number of database\n+// operations. Operations are added to the Batch and then the Batch is executed\n+// via either DB.Run, Txn.Run or Txn.Commit.\n+//\n+// TODO(pmattis): Allow a timestamp to be specified which is applied to all\n+// operations within the batch.\n+type Batch struct {\n+\t// Results contains an entry for each operation added to the batch. The order\n+\t// of the results matches the order the operations were added to the\n+\t// batch. For example:\n+\t//\n+\t//   b := client.B().Put(\"a\", \"1\").Put(\"b\", \"2\")\n+\t//   _ = db.Run(b)\n+\t//   // string(b.Results[0].Rows[0].Key) == \"a\"\n+\t//   // string(b.Results[1].Rows[0].Key) == \"b\"\n+\tResults    []Result\n+\tcalls      []Call\n+\tresultsBuf [8]Result\n+\trowsBuf    [8]KeyValue\n+\trowsIdx    int\n+}\n+\n+// B creates a new empty batch:\n+//\n+//   err := db.Run(client.B().Put(\"a\", \"1\").Put(\"b\", \"2\"))\n+func B() *Batch {\n+\treturn &Batch{}\n+}\n+\n+func (b *Batch) prepare() error {\n+\tfor _, r := range b.Results {\n+\t\tif err := r.Err; err != nil {\n+\t\t\treturn err\n+\t\t}\n+\t}\n+\treturn nil\n+}\n+\n+func (b *Batch) ensureNotNil() *Batch {\n+\tif b != nil {\n+\t\treturn b\n+\t}\n+\treturn &Batch{}\n+}\n+\n+func (b *Batch) initResult(calls, numRows int, err error) {\n+\tr := Result{calls: calls, Err: err}\n+\tif numRows > 0 {\n+\t\tif b.rowsIdx+numRows <= len(b.rowsBuf) {\n+\t\t\tr.Rows = b.rowsBuf[b.rowsIdx : b.rowsIdx+numRows]\n+\t\t\tb.rowsIdx += numRows\n+\t\t} else {\n+\t\t\tr.Rows = make([]KeyValue, numRows)\n+\t\t}\n+\t}\n+\tif b.Results == nil {\n+\t\tb.Results = b.resultsBuf[0:0]\n+\t}\n+\tb.Results = append(b.Results, r)\n+}\n+\n+func (b *Batch) fillResults() error {\n+\toffset := 0\n+\tfor i := range b.Results {\n+\t\tresult := &b.Results[i]\n+\n+\t\tfor k := 0; k < result.calls; k++ {\n+\t\t\tcall := b.calls[offset+k]\n+\n+\t\t\tif result.Err == nil {\n+\t\t\t\tresult.Err = call.Reply.Header().GoError()\n+\t\t\t}\n+\n+\t\t\tswitch t := call.Reply.(type) {\n+\t\t\tcase *proto.GetResponse:\n+\t\t\t\trow := &result.Rows[k]\n+\t\t\t\trow.Key = []byte(call.Args.(*proto.GetRequest).Key)\n+\t\t\t\tif result.Err == nil {\n+\t\t\t\t\trow.setValue(t.Value)\n+\t\t\t\t}\n+\t\t\tcase *proto.PutResponse:\n+\t\t\t\treq := call.Args.(*proto.PutRequest)\n+\t\t\t\trow := &result.Rows[k]\n+\t\t\t\trow.Key = []byte(req.Key)\n+\t\t\t\tif result.Err == nil {\n+\t\t\t\t\trow.setValue(&req.Value)\n+\t\t\t\t\trow.setTimestamp(t.Timestamp)\n+\t\t\t\t}\n+\t\t\tcase *proto.ConditionalPutResponse:\n+\t\t\t\treq := call.Args.(*proto.ConditionalPutRequest)\n+\t\t\t\trow := &result.Rows[k]\n+\t\t\t\trow.Key = []byte(req.Key)\n+\t\t\t\tif result.Err == nil {\n+\t\t\t\t\trow.setValue(&req.Value)\n+\t\t\t\t\trow.setTimestamp(t.Timestamp)\n+\t\t\t\t}\n+\t\t\tcase *proto.IncrementResponse:\n+\t\t\t\trow := &result.Rows[k]\n+\t\t\t\trow.Key = []byte(call.Args.(*proto.IncrementRequest).Key)\n+\t\t\t\tif result.Err == nil {\n+\t\t\t\t\t// TODO(pmattis): Should IncrementResponse contain a\n+\t\t\t\t\t// proto.Value so that the timestamp can be returned?\n+\t\t\t\t\trow.Value = &t.NewValue\n+\t\t\t\t}\n+\t\t\tcase *proto.ScanResponse:\n+\t\t\t\tresult.Rows = make([]KeyValue, len(t.Rows))\n+\t\t\t\tfor j, kv := range t.Rows {\n+\t\t\t\t\trow := &result.Rows[j]\n+\t\t\t\t\trow.Key = kv.Key\n+\t\t\t\t\trow.setValue(&kv.Value)\n+\t\t\t\t}\n+\t\t\tcase *proto.DeleteResponse:\n+\t\t\t\trow := &result.Rows[k]\n+\t\t\t\trow.Key = []byte(call.Args.(*proto.DeleteRequest).Key)\n+\n+\t\t\tcase *proto.AdminMergeResponse:\n+\t\t\tcase *proto.AdminSplitResponse:\n+\t\t\tcase *proto.DeleteRangeResponse:\n+\t\t\tcase *proto.EndTransactionResponse:\n+\t\t\tcase *proto.InternalBatchResponse:\n+\t\t\tcase *proto.InternalGCResponse:\n+\t\t\tcase *proto.InternalMergeResponse:\n+\t\t\tcase *proto.InternalPushTxnResponse:\n+\t\t\tcase *proto.InternalRangeLookupResponse:\n+\t\t\tcase *proto.InternalResolveIntentResponse:\n+\t\t\tcase *proto.InternalResolveIntentRangeResponse:\n+\t\t\t\t// Nothing to do for these methods as they do not generate any\n+\t\t\t\t// rows. For the proto.Internal* responses the caller will have hold of\n+\t\t\t\t// the response object itself.\n+\n+\t\t\tdefault:\n+\t\t\t\tif result.Err == nil {\n+\t\t\t\t\tresult.Err = fmt.Errorf(\"unsupported reply: %T\", call.Reply)\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t\toffset += result.calls\n+\t}\n+\n+\tfor i := range b.Results {\n+\t\tresult := &b.Results[i]\n+\t\tif result.Err != nil {\n+\t\t\treturn result.Err\n+\t\t}\n+\t}\n+\treturn nil\n+}\n+\n+// InternalAddCall adds the specified call to the batch. It is intended for\n+// internal use only.\n+func (b *Batch) InternalAddCall(call Call) {\n+\tb = b.ensureNotNil()\n+\n+\tnumRows := 0\n+\tswitch call.Args.(type) {\n+\tcase *proto.GetRequest,\n+\t\t*proto.PutRequest,\n+\t\t*proto.ConditionalPutRequest,\n+\t\t*proto.IncrementRequest,\n+\t\t*proto.DeleteRequest:\n+\t\tnumRows = 1\n+\t}\n+\tb.calls = append(b.calls, call)\n+\tb.initResult(1 /* calls */, numRows, nil)\n+}\n+\n+// Get retrieves the value for a key. A new result will be appended to the\n+// batch which will contain a single row.\n+//\n+//   r, err := db.Get(\"a\")\n+//   // string(r.Rows[0].Key) == \"a\"\n+//\n+// key can be either a byte slice, a string, a fmt.Stringer or an\n+// encoding.BinaryMarshaler.\n+func (b *Batch) Get(key interface{}) *Batch {\n+\tb = b.ensureNotNil()\n+\n+\tk, err := marshalKey(key)\n+\tif err != nil {\n+\t\tb.initResult(0, 1, err)\n+\t\treturn b\n+\t}\n+\tb.calls = append(b.calls, Get(proto.Key(k)))\n+\tb.initResult(1, 1, nil)\n+\treturn b\n+}\n+\n+// GetProto retrieves the value for a key and decodes the result as a proto\n+// message. A new result will be appended to the batch which will contain a\n+// single row. Note that the proto will not be decoded until after the batch is\n+// executed using DB.Run or Txn.Run.\n+//\n+// key can be either a byte slice, a string, a fmt.Stringer or an\n+// encoding.BinaryMarshaler.\n+func (b *Batch) GetProto(key interface{}, msg gogoproto.Message) *Batch {\n+\tb = b.ensureNotNil()\n+\n+\tk, err := marshalKey(key)\n+\tif err != nil {\n+\t\tb.initResult(0, 1, err)\n+\t\treturn b\n+\t}\n+\tb.calls = append(b.calls, GetProto(proto.Key(k), msg))\n+\tb.initResult(1, 1, nil)\n+\treturn b\n+}\n+\n+// Put sets the value for a key.\n+//\n+// A new result will be appended to the batch which will contain a single row\n+// and Result.Err will indicate success or failure.\n+//\n+// key can be either a byte slice, a string, a fmt.Stringer or an\n+// encoding.BinaryMarshaler. value can be any key type or a proto.Message.\n+func (b *Batch) Put(key, value interface{}) *Batch {\n+\tb = b.ensureNotNil()\n+\n+\tk, err := marshalKey(key)\n+\tif err != nil {\n+\t\tb.initResult(0, 1, err)\n+\t\treturn b\n+\t}\n+\tv, err := marshalValue(value)\n+\tif err != nil {\n+\t\tb.initResult(0, 1, err)\n+\t\treturn b\n+\t}\n+\tb.calls = append(b.calls, Put(proto.Key(k), v))\n+\tb.initResult(1, 1, nil)\n+\treturn b\n+}\n+\n+// CPut conditionally sets the value for a key if the existing value is equal\n+// to expValue. To conditionally set a value only if there is no existing entry\n+// pass nil for expValue.\n+//\n+// A new result will be appended to the batch which will contain a single row\n+// and Result.Err will indicate success or failure.\n+//\n+// key can be either a byte slice, a string, a fmt.Stringer or an\n+// encoding.BinaryMarshaler. value can be any key type or a proto.Message.\n+func (b *Batch) CPut(key, value, expValue interface{}) *Batch {\n+\tb = b.ensureNotNil()\n+\n+\tk, err := marshalKey(key)\n+\tif err != nil {\n+\t\tb.initResult(0, 1, err)\n+\t\treturn b\n+\t}\n+\tv, err := marshalValue(value)\n+\tif err != nil {\n+\t\tb.initResult(0, 1, err)\n+\t\treturn b\n+\t}\n+\tev, err := marshalValue(expValue)\n+\tif err != nil {\n+\t\tb.initResult(0, 1, err)\n+\t\treturn b\n+\t}\n+\tb.calls = append(b.calls, ConditionalPut(proto.Key(k), v, ev))\n+\tb.initResult(1, 1, nil)\n+\treturn b\n+}\n+\n+// Inc increments the integer value at key. If the key does not exist it will\n+// be created with an initial value of 0 which will then be incremented. If the\n+// key exists but was set using Put or CPut an error will be returned.\n+//\n+// A new result will be appended to the batch which will contain a single row\n+// and Result.Err will indicate success or failure.\n+//\n+// key can be either a byte slice, a string, a fmt.Stringer or an\n+// encoding.BinaryMarshaler.\n+func (b *Batch) Inc(key interface{}, value int64) *Batch {\n+\tb = b.ensureNotNil()\n+\n+\tk, err := marshalKey(key)\n+\tif err != nil {\n+\t\tb.initResult(0, 1, err)\n+\t\treturn b\n+\t}\n+\tb.calls = append(b.calls, Increment(proto.Key(k), value))\n+\tb.initResult(1, 1, nil)\n+\treturn b\n+}\n+\n+// Scan retrieves the rows between begin (inclusive) and end (exclusive).\n+//\n+// A new result will be appended to the batch which will contain up to maxRows\n+// rows and Result.Err will indicate success or failure.\n+//\n+// key can be either a byte slice, a string, a fmt.Stringer or an\n+// encoding.BinaryMarshaler.\n+func (b *Batch) Scan(s, e interface{}, maxRows int64) *Batch {\n+\tbegin, err := marshalKey(s)\n+\tif err != nil {\n+\t\tb.initResult(0, 0, err)\n+\t\treturn b\n+\t}\n+\tend, err := marshalKey(e)\n+\tif err != nil {\n+\t\tb.initResult(0, 0, err)\n+\t\treturn b\n+\t}\n+\tb.calls = append(b.calls, Scan(proto.Key(begin), proto.Key(end), maxRows))\n+\tb.initResult(1, 0, nil)\n+\treturn b\n+}\n+\n+// Del deletes one or more keys.\n+//\n+// A new result will be appended to the batch and each key will have a\n+// corresponding row in the returned Result.\n+//\n+// key can be either a byte slice, a string, a fmt.Stringer or an\n+// encoding.BinaryMarshaler.\n+func (b *Batch) Del(keys ...interface{}) *Batch {\n+\tb = b.ensureNotNil()\n+\n+\tvar calls []Call\n+\tfor _, key := range keys {\n+\t\tk, err := marshalKey(key)\n+\t\tif err != nil {\n+\t\t\tb.initResult(0, len(keys), err)\n+\t\t\treturn b\n+\t\t}\n+\t\tcalls = append(calls, Delete(proto.Key(k)))\n+\t}\n+\tb.calls = append(b.calls, calls...)\n+\tb.initResult(len(calls), len(calls), nil)\n+\treturn b\n+}\n+\n+// DelRange deletes the rows between begin (inclusive) and end (exclusive).\n+//\n+// A new result will be appended to the batch which will contain 0 rows and\n+// Result.Err will indicate success or failure.\n+//\n+// key can be either a byte slice, a string, a fmt.Stringer or an\n+// encoding.BinaryMarshaler.\n+func (b *Batch) DelRange(s, e interface{}) *Batch {","path":"client/batch.go","position":346,"original_position":367,"commit_id":"89538830de6233f99ef3a35d6aee5563d2b21225","original_commit_id":"b3ec0ccaad9f0122612667be9b47adb263378da0","user":{"login":"tamird","id":1535036,"avatar_url":"https://avatars.githubusercontent.com/u/1535036?v=3","gravatar_id":"","url":"https://api.github.com/users/tamird","html_url":"https://github.com/tamird","followers_url":"https://api.github.com/users/tamird/followers","following_url":"https://api.github.com/users/tamird/following{/other_user}","gists_url":"https://api.github.com/users/tamird/gists{/gist_id}","starred_url":"https://api.github.com/users/tamird/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tamird/subscriptions","organizations_url":"https://api.github.com/users/tamird/orgs","repos_url":"https://api.github.com/users/tamird/repos","events_url":"https://api.github.com/users/tamird/events{/privacy}","received_events_url":"https://api.github.com/users/tamird/received_events","type":"User","site_admin":false},"body":"But then they return the same pointer, too. Seems this would work with values, but perhaps this is an optimization.","created_at":"2015-06-09T21:23:28Z","updated_at":"2015-06-09T21:23:28Z","html_url":"https://github.com/cockroachdb/cockroach/pull/1318#discussion_r32065888","pull_request_url":"https://api.github.com/repos/cockroachdb/cockroach/pulls/1318","_links":{"self":{"href":"https://api.github.com/repos/cockroachdb/cockroach/pulls/comments/32065888"},"html":{"href":"https://github.com/cockroachdb/cockroach/pull/1318#discussion_r32065888"},"pull_request":{"href":"https://api.github.com/repos/cockroachdb/cockroach/pulls/1318"}}},"pull_request":{"url":"https://api.github.com/repos/cockroachdb/cockroach/pulls/1318","id":37294101,"html_url":"https://github.com/cockroachdb/cockroach/pull/1318","diff_url":"https://github.com/cockroachdb/cockroach/pull/1318.diff","patch_url":"https://github.com/cockroachdb/cockroach/pull/1318.patch","issue_url":"https://api.github.com/repos/cockroachdb/cockroach/issues/1318","number":1318,"state":"open","locked":false,"title":"Move client.Batch to its own file.","user":{"login":"petermattis","id":6201335,"avatar_url":"https://avatars.githubusercontent.com/u/6201335?v=3","gravatar_id":"","url":"https://api.github.com/users/petermattis","html_url":"https://github.com/petermattis","followers_url":"https://api.github.com/users/petermattis/followers","following_url":"https://api.github.com/users/petermattis/following{/other_user}","gists_url":"https://api.github.com/users/petermattis/gists{/gist_id}","starred_url":"https://api.github.com/users/petermattis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/petermattis/subscriptions","organizations_url":"https://api.github.com/users/petermattis/orgs","repos_url":"https://api.github.com/users/petermattis/repos","events_url":"https://api.github.com/users/petermattis/events{/privacy}","received_events_url":"https://api.github.com/users/petermattis/received_events","type":"User","site_admin":false},"body":"Replaced client.batcher with client.B() which plays nicer with godoc and\r\nremoves any confusion as to whether the Batch created is specific to a\r\nDB or Txn.\r\n\r\nFixes #1254.","created_at":"2015-06-09T20:08:40Z","updated_at":"2015-06-09T21:23:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"64d7e94f2f064b10694a90088eade9c4b34400aa","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/cockroachdb/cockroach/pulls/1318/commits","review_comments_url":"https://api.github.com/repos/cockroachdb/cockroach/pulls/1318/comments","review_comment_url":"https://api.github.com/repos/cockroachdb/cockroach/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cockroachdb/cockroach/issues/1318/comments","statuses_url":"https://api.github.com/repos/cockroachdb/cockroach/statuses/89538830de6233f99ef3a35d6aee5563d2b21225","head":{"label":"cockroachdb:pmattis/client-batch","ref":"pmattis/client-batch","sha":"89538830de6233f99ef3a35d6aee5563d2b21225","user":{"login":"cockroachdb","id":6748139,"avatar_url":"https://avatars.githubusercontent.com/u/6748139?v=3","gravatar_id":"","url":"https://api.github.com/users/cockroachdb","html_url":"https://github.com/cockroachdb","followers_url":"https://api.github.com/users/cockroachdb/followers","following_url":"https://api.github.com/users/cockroachdb/following{/other_user}","gists_url":"https://api.github.com/users/cockroachdb/gists{/gist_id}","starred_url":"https://api.github.com/users/cockroachdb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cockroachdb/subscriptions","organizations_url":"https://api.github.com/users/cockroachdb/orgs","repos_url":"https://api.github.com/users/cockroachdb/repos","events_url":"https://api.github.com/users/cockroachdb/events{/privacy}","received_events_url":"https://api.github.com/users/cockroachdb/received_events","type":"Organization","site_admin":false},"repo":{"id":16563587,"name":"cockroach","full_name":"cockroachdb/cockroach","owner":{"login":"cockroachdb","id":6748139,"avatar_url":"https://avatars.githubusercontent.com/u/6748139?v=3","gravatar_id":"","url":"https://api.github.com/users/cockroachdb","html_url":"https://github.com/cockroachdb","followers_url":"https://api.github.com/users/cockroachdb/followers","following_url":"https://api.github.com/users/cockroachdb/following{/other_user}","gists_url":"https://api.github.com/users/cockroachdb/gists{/gist_id}","starred_url":"https://api.github.com/users/cockroachdb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cockroachdb/subscriptions","organizations_url":"https://api.github.com/users/cockroachdb/orgs","repos_url":"https://api.github.com/users/cockroachdb/repos","events_url":"https://api.github.com/users/cockroachdb/events{/privacy}","received_events_url":"https://api.github.com/users/cockroachdb/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cockroachdb/cockroach","description":"A Scalable, Geo-Replicated, Transactional Datastore","fork":false,"url":"https://api.github.com/repos/cockroachdb/cockroach","forks_url":"https://api.github.com/repos/cockroachdb/cockroach/forks","keys_url":"https://api.github.com/repos/cockroachdb/cockroach/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cockroachdb/cockroach/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cockroachdb/cockroach/teams","hooks_url":"https://api.github.com/repos/cockroachdb/cockroach/hooks","issue_events_url":"https://api.github.com/repos/cockroachdb/cockroach/issues/events{/number}","events_url":"https://api.github.com/repos/cockroachdb/cockroach/events","assignees_url":"https://api.github.com/repos/cockroachdb/cockroach/assignees{/user}","branches_url":"https://api.github.com/repos/cockroachdb/cockroach/branches{/branch}","tags_url":"https://api.github.com/repos/cockroachdb/cockroach/tags","blobs_url":"https://api.github.com/repos/cockroachdb/cockroach/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cockroachdb/cockroach/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cockroachdb/cockroach/git/refs{/sha}","trees_url":"https://api.github.com/repos/cockroachdb/cockroach/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cockroachdb/cockroach/statuses/{sha}","languages_url":"https://api.github.com/repos/cockroachdb/cockroach/languages","stargazers_url":"https://api.github.com/repos/cockroachdb/cockroach/stargazers","contributors_url":"https://api.github.com/repos/cockroachdb/cockroach/contributors","subscribers_url":"https://api.github.com/repos/cockroachdb/cockroach/subscribers","subscription_url":"https://api.github.com/repos/cockroachdb/cockroach/subscription","commits_url":"https://api.github.com/repos/cockroachdb/cockroach/commits{/sha}","git_commits_url":"https://api.github.com/repos/cockroachdb/cockroach/git/commits{/sha}","comments_url":"https://api.github.com/repos/cockroachdb/cockroach/comments{/number}","issue_comment_url":"https://api.github.com/repos/cockroachdb/cockroach/issues/comments{/number}","contents_url":"https://api.github.com/repos/cockroachdb/cockroach/contents/{+path}","compare_url":"https://api.github.com/repos/cockroachdb/cockroach/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cockroachdb/cockroach/merges","archive_url":"https://api.github.com/repos/cockroachdb/cockroach/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cockroachdb/cockroach/downloads","issues_url":"https://api.github.com/repos/cockroachdb/cockroach/issues{/number}","pulls_url":"https://api.github.com/repos/cockroachdb/cockroach/pulls{/number}","milestones_url":"https://api.github.com/repos/cockroachdb/cockroach/milestones{/number}","notifications_url":"https://api.github.com/repos/cockroachdb/cockroach/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cockroachdb/cockroach/labels{/name}","releases_url":"https://api.github.com/repos/cockroachdb/cockroach/releases{/id}","created_at":"2014-02-06T00:18:47Z","updated_at":"2015-06-09T21:20:07Z","pushed_at":"2015-06-09T21:22:01Z","git_url":"git://github.com/cockroachdb/cockroach.git","ssh_url":"git@github.com:cockroachdb/cockroach.git","clone_url":"https://github.com/cockroachdb/cockroach.git","svn_url":"https://github.com/cockroachdb/cockroach","homepage":null,"size":35585,"stargazers_count":4486,"watchers_count":4486,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":324,"mirror_url":null,"open_issues_count":88,"forks":324,"open_issues":88,"watchers":4486,"default_branch":"master"}},"base":{"label":"cockroachdb:master","ref":"master","sha":"a2b0a20d4fe9e05399f2f751000bd991432d7585","user":{"login":"cockroachdb","id":6748139,"avatar_url":"https://avatars.githubusercontent.com/u/6748139?v=3","gravatar_id":"","url":"https://api.github.com/users/cockroachdb","html_url":"https://github.com/cockroachdb","followers_url":"https://api.github.com/users/cockroachdb/followers","following_url":"https://api.github.com/users/cockroachdb/following{/other_user}","gists_url":"https://api.github.com/users/cockroachdb/gists{/gist_id}","starred_url":"https://api.github.com/users/cockroachdb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cockroachdb/subscriptions","organizations_url":"https://api.github.com/users/cockroachdb/orgs","repos_url":"https://api.github.com/users/cockroachdb/repos","events_url":"https://api.github.com/users/cockroachdb/events{/privacy}","received_events_url":"https://api.github.com/users/cockroachdb/received_events","type":"Organization","site_admin":false},"repo":{"id":16563587,"name":"cockroach","full_name":"cockroachdb/cockroach","owner":{"login":"cockroachdb","id":6748139,"avatar_url":"https://avatars.githubusercontent.com/u/6748139?v=3","gravatar_id":"","url":"https://api.github.com/users/cockroachdb","html_url":"https://github.com/cockroachdb","followers_url":"https://api.github.com/users/cockroachdb/followers","following_url":"https://api.github.com/users/cockroachdb/following{/other_user}","gists_url":"https://api.github.com/users/cockroachdb/gists{/gist_id}","starred_url":"https://api.github.com/users/cockroachdb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cockroachdb/subscriptions","organizations_url":"https://api.github.com/users/cockroachdb/orgs","repos_url":"https://api.github.com/users/cockroachdb/repos","events_url":"https://api.github.com/users/cockroachdb/events{/privacy}","received_events_url":"https://api.github.com/users/cockroachdb/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cockroachdb/cockroach","description":"A Scalable, Geo-Replicated, Transactional Datastore","fork":false,"url":"https://api.github.com/repos/cockroachdb/cockroach","forks_url":"https://api.github.com/repos/cockroachdb/cockroach/forks","keys_url":"https://api.github.com/repos/cockroachdb/cockroach/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cockroachdb/cockroach/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cockroachdb/cockroach/teams","hooks_url":"https://api.github.com/repos/cockroachdb/cockroach/hooks","issue_events_url":"https://api.github.com/repos/cockroachdb/cockroach/issues/events{/number}","events_url":"https://api.github.com/repos/cockroachdb/cockroach/events","assignees_url":"https://api.github.com/repos/cockroachdb/cockroach/assignees{/user}","branches_url":"https://api.github.com/repos/cockroachdb/cockroach/branches{/branch}","tags_url":"https://api.github.com/repos/cockroachdb/cockroach/tags","blobs_url":"https://api.github.com/repos/cockroachdb/cockroach/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cockroachdb/cockroach/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cockroachdb/cockroach/git/refs{/sha}","trees_url":"https://api.github.com/repos/cockroachdb/cockroach/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cockroachdb/cockroach/statuses/{sha}","languages_url":"https://api.github.com/repos/cockroachdb/cockroach/languages","stargazers_url":"https://api.github.com/repos/cockroachdb/cockroach/stargazers","contributors_url":"https://api.github.com/repos/cockroachdb/cockroach/contributors","subscribers_url":"https://api.github.com/repos/cockroachdb/cockroach/subscribers","subscription_url":"https://api.github.com/repos/cockroachdb/cockroach/subscription","commits_url":"https://api.github.com/repos/cockroachdb/cockroach/commits{/sha}","git_commits_url":"https://api.github.com/repos/cockroachdb/cockroach/git/commits{/sha}","comments_url":"https://api.github.com/repos/cockroachdb/cockroach/comments{/number}","issue_comment_url":"https://api.github.com/repos/cockroachdb/cockroach/issues/comments{/number}","contents_url":"https://api.github.com/repos/cockroachdb/cockroach/contents/{+path}","compare_url":"https://api.github.com/repos/cockroachdb/cockroach/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cockroachdb/cockroach/merges","archive_url":"https://api.github.com/repos/cockroachdb/cockroach/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cockroachdb/cockroach/downloads","issues_url":"https://api.github.com/repos/cockroachdb/cockroach/issues{/number}","pulls_url":"https://api.github.com/repos/cockroachdb/cockroach/pulls{/number}","milestones_url":"https://api.github.com/repos/cockroachdb/cockroach/milestones{/number}","notifications_url":"https://api.github.com/repos/cockroachdb/cockroach/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cockroachdb/cockroach/labels{/name}","releases_url":"https://api.github.com/repos/cockroachdb/cockroach/releases{/id}","created_at":"2014-02-06T00:18:47Z","updated_at":"2015-06-09T21:20:07Z","pushed_at":"2015-06-09T21:22:01Z","git_url":"git://github.com/cockroachdb/cockroach.git","ssh_url":"git@github.com:cockroachdb/cockroach.git","clone_url":"https://github.com/cockroachdb/cockroach.git","svn_url":"https://github.com/cockroachdb/cockroach","homepage":null,"size":35585,"stargazers_count":4486,"watchers_count":4486,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":324,"mirror_url":null,"open_issues_count":88,"forks":324,"open_issues":88,"watchers":4486,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cockroachdb/cockroach/pulls/1318"},"html":{"href":"https://github.com/cockroachdb/cockroach/pull/1318"},"issue":{"href":"https://api.github.com/repos/cockroachdb/cockroach/issues/1318"},"comments":{"href":"https://api.github.com/repos/cockroachdb/cockroach/issues/1318/comments"},"review_comments":{"href":"https://api.github.com/repos/cockroachdb/cockroach/pulls/1318/comments"},"review_comment":{"href":"https://api.github.com/repos/cockroachdb/cockroach/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cockroachdb/cockroach/pulls/1318/commits"},"statuses":{"href":"https://api.github.com/repos/cockroachdb/cockroach/statuses/89538830de6233f99ef3a35d6aee5563d2b21225"}}}}