{"action":"created","comment":{"url":"https://api.github.com/repos/dmlc/xgboost/pulls/comments/221450849","pull_request_review_id":160105966,"id":221450849,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyMTQ1MDg0OQ==","diff_hunk":"@@ -12,261 +12,91 @@\n #if DMLC_ENABLE_STD_THREAD\n #include \"./sparse_page_dmatrix.h\"\n #include \"../common/random.h\"\n-#include \"../common/common.h\"\n-#include \"../common/group_data.h\"\n \n namespace xgboost {\n namespace data {\n \n-SparsePageDMatrix::ColPageIter::ColPageIter(\n-    std::vector<std::unique_ptr<dmlc::SeekStream> >&& files)\n-    : page_(nullptr), clock_ptr_(0), files_(std::move(files)) {\n-  load_all_ = false;\n-  formats_.resize(files_.size());\n-  prefetchers_.resize(files_.size());\n-\n-  for (size_t i = 0; i < files_.size(); ++i) {\n-    dmlc::SeekStream* fi = files_[i].get();\n-    std::string format;\n-    CHECK(fi->Read(&format)) << \"Invalid page format\";\n-    formats_[i].reset(SparsePageFormat::Create(format));\n-    SparsePageFormat* fmt = formats_[i].get();\n-    size_t fbegin = fi->Tell();\n-    prefetchers_[i].reset(new dmlc::ThreadedIter<SparsePage>(4));\n-    prefetchers_[i]->Init([this, fi, fmt] (SparsePage** dptr) {\n-        if (*dptr == nullptr) {\n-          *dptr = new SparsePage();\n-        }\n-        if (load_all_) {\n-          return fmt->Read(*dptr, fi);\n-        } else {\n-          return fmt->Read(*dptr, fi, index_set_);\n-        }\n-      },  [this, fi, fbegin] () {\n-        fi->Seek(fbegin);\n-        index_set_ = set_index_set_;\n-        load_all_ = set_load_all_;\n-      });\n-  }\n-}\n-\n-SparsePageDMatrix::ColPageIter::~ColPageIter() {\n-  delete page_;\n+MetaInfo& SparsePageDMatrix::Info() {\n+  return row_source_->info;\n }\n \n-bool SparsePageDMatrix::ColPageIter::Next() {\n-  // doing clock rotation over shards.\n-  if (page_ != nullptr) {\n-    size_t n = prefetchers_.size();\n-    prefetchers_[(clock_ptr_ + n - 1) % n]->Recycle(&page_);\n-  }\n-  if (prefetchers_[clock_ptr_]->Next(&page_)) {\n-    // advance clock\n-    clock_ptr_ = (clock_ptr_ + 1) % prefetchers_.size();\n-    return true;\n-  } else {\n-    return false;\n-  }\n+const MetaInfo& SparsePageDMatrix::Info() const {\n+  return row_source_->info;\n }\n \n-void SparsePageDMatrix::ColPageIter::BeforeFirst() {\n-  clock_ptr_ = 0;\n-  for (auto& p : prefetchers_) {\n-    p->BeforeFirst();\n+class SparseBatchIteratorImpl : public BatchIteratorImpl {\n+ public:\n+  explicit SparseBatchIteratorImpl(SparsePageSource* source)\n+      : source_(source) {}\n+  const SparsePage& operator*() const override { return source_->Value(); }\n+  void operator++() override { at_end_ = !source_->Next(); }\n+  bool AtEnd() const override { return at_end_; }\n+  SparseBatchIteratorImpl* Clone() override {\n+    return new SparseBatchIteratorImpl(*this);\n   }\n-}\n-\n-void SparsePageDMatrix::ColPageIter::Init(\n-    const std::vector<bst_uint>& index_set) {\n-  set_index_set_ = index_set;\n-  set_load_all_ = true;\n-  std::sort(set_index_set_.begin(), set_index_set_.end());\n-  this->BeforeFirst();\n-}\n \n-  dmlc::DataIter<SparsePage>* SparsePageDMatrix::ColIterator() {\n-  CHECK(col_iter_ != nullptr);\n-  std::vector<bst_uint> col_index;\n-  std::iota(col_index.begin(), col_index.end(), bst_uint(0));\n-  col_iter_->Init(col_index);\n-  return col_iter_.get();\n+ private:\n+  SparsePageSource* source_{nullptr};\n+  bool at_end_{ false };\n+};\n+\n+BatchSet SparsePageDMatrix::GetRowBatches() {\n+  auto cast = dynamic_cast<SparsePageSource*>(row_source_.get());\n+  cast->BeforeFirst();\n+  cast->Next();\n+  auto begin_iter = BatchIterator(new SparseBatchIteratorImpl(cast));\n+  return BatchSet(begin_iter);\n }\n \n-bool SparsePageDMatrix::TryInitColData(bool sorted) {\n-  // load meta data.\n-  std::vector<std::string> cache_shards = common::Split(cache_info_, ':');\n-  {\n-    std::string col_meta_name = cache_shards[0] + \".col.meta\";\n-    std::unique_ptr<dmlc::Stream> fmeta(\n-        dmlc::Stream::Create(col_meta_name.c_str(), \"r\", true));\n-    if (fmeta == nullptr) return false;\n-    CHECK(fmeta->Read(&buffered_rowset_)) << \"invalid col.meta file\";\n-    CHECK(fmeta->Read(&col_size_)) << \"invalid col.meta file\";\n-  }\n-  // load real data\n-  std::vector<std::unique_ptr<dmlc::SeekStream> > files;\n-  for (const std::string& prefix : cache_shards) {\n-    std::string col_data_name = prefix + \".col.page\";\n-    std::unique_ptr<dmlc::SeekStream> fdata(\n-        dmlc::SeekStream::CreateForRead(col_data_name.c_str(), true));\n-    if (fdata == nullptr) return false;\n-    files.push_back(std::move(fdata));\n+BatchSet SparsePageDMatrix::GetSortedColumnBatches() {\n+  // Lazily instantiate\n+  if (!sorted_column_source_) {\n+    SparsePageSource::CreateColumnPage(this, cache_info_, true);\n+    sorted_column_source_.reset(\n+        new SparsePageSource(cache_info_, \".sorted.col.page\"));","path":"src/data/sparse_page_dmatrix.cc","position":132,"original_position":132,"commit_id":"7078d360db6c9222be69429e43af196066e5a2a4","original_commit_id":"7a8ce17be644ae603c31a62b14172bc734393eef","user":{"login":"RAMitchell","id":7307640,"node_id":"MDQ6VXNlcjczMDc2NDA=","avatar_url":"https://avatars2.githubusercontent.com/u/7307640?v=4","gravatar_id":"","url":"https://api.github.com/users/RAMitchell","html_url":"https://github.com/RAMitchell","followers_url":"https://api.github.com/users/RAMitchell/followers","following_url":"https://api.github.com/users/RAMitchell/following{/other_user}","gists_url":"https://api.github.com/users/RAMitchell/gists{/gist_id}","starred_url":"https://api.github.com/users/RAMitchell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RAMitchell/subscriptions","organizations_url":"https://api.github.com/users/RAMitchell/orgs","repos_url":"https://api.github.com/users/RAMitchell/repos","events_url":"https://api.github.com/users/RAMitchell/events{/privacy}","received_events_url":"https://api.github.com/users/RAMitchell/received_events","type":"User","site_admin":false},"body":"Done.","created_at":"2018-09-30T08:00:44Z","updated_at":"2018-09-30T08:00:44Z","html_url":"https://github.com/dmlc/xgboost/pull/3395#discussion_r221450849","pull_request_url":"https://api.github.com/repos/dmlc/xgboost/pulls/3395","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/dmlc/xgboost/pulls/comments/221450849"},"html":{"href":"https://github.com/dmlc/xgboost/pull/3395#discussion_r221450849"},"pull_request":{"href":"https://api.github.com/repos/dmlc/xgboost/pulls/3395"}},"in_reply_to_id":221145823},"pull_request":{"url":"https://api.github.com/repos/dmlc/xgboost/pulls/3395","id":196019304,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk2MDE5MzA0","html_url":"https://github.com/dmlc/xgboost/pull/3395","diff_url":"https://github.com/dmlc/xgboost/pull/3395.diff","patch_url":"https://github.com/dmlc/xgboost/pull/3395.patch","issue_url":"https://api.github.com/repos/dmlc/xgboost/issues/3395","number":3395,"state":"open","locked":false,"title":"Dmatrix refactor stage 2","user":{"login":"RAMitchell","id":7307640,"node_id":"MDQ6VXNlcjczMDc2NDA=","avatar_url":"https://avatars2.githubusercontent.com/u/7307640?v=4","gravatar_id":"","url":"https://api.github.com/users/RAMitchell","html_url":"https://github.com/RAMitchell","followers_url":"https://api.github.com/users/RAMitchell/followers","following_url":"https://api.github.com/users/RAMitchell/following{/other_user}","gists_url":"https://api.github.com/users/RAMitchell/gists{/gist_id}","starred_url":"https://api.github.com/users/RAMitchell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RAMitchell/subscriptions","organizations_url":"https://api.github.com/users/RAMitchell/orgs","repos_url":"https://api.github.com/users/RAMitchell/repos","events_url":"https://api.github.com/users/RAMitchell/events{/privacy}","received_events_url":"https://api.github.com/users/RAMitchell/received_events","type":"User","site_admin":false},"body":"- Remove buffered rowset usage where possible\r\n- Transition to c++11 style iterators for row access\r\n\r\nTo do:\r\n- Transition column iterators to C++ 11\r\n- Consider removal of DataSource class. SimpleCSRSource and SparsePageSource are so tightly coupled to their respective dmatrix types that it makes no sense for them to be separate classes. Removing these classes would significantly reduce the complexity of dmatrix. ","created_at":"2018-06-20T04:30:32Z","updated_at":"2018-09-30T08:00:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"dd8005c2e27ae12a9230d9bc0e8f6e84b36c8ed9","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/dmlc/xgboost/pulls/3395/commits","review_comments_url":"https://api.github.com/repos/dmlc/xgboost/pulls/3395/comments","review_comment_url":"https://api.github.com/repos/dmlc/xgboost/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dmlc/xgboost/issues/3395/comments","statuses_url":"https://api.github.com/repos/dmlc/xgboost/statuses/7078d360db6c9222be69429e43af196066e5a2a4","head":{"label":"RAMitchell:dmatrix-refactor","ref":"dmatrix-refactor","sha":"7078d360db6c9222be69429e43af196066e5a2a4","user":{"login":"RAMitchell","id":7307640,"node_id":"MDQ6VXNlcjczMDc2NDA=","avatar_url":"https://avatars2.githubusercontent.com/u/7307640?v=4","gravatar_id":"","url":"https://api.github.com/users/RAMitchell","html_url":"https://github.com/RAMitchell","followers_url":"https://api.github.com/users/RAMitchell/followers","following_url":"https://api.github.com/users/RAMitchell/following{/other_user}","gists_url":"https://api.github.com/users/RAMitchell/gists{/gist_id}","starred_url":"https://api.github.com/users/RAMitchell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RAMitchell/subscriptions","organizations_url":"https://api.github.com/users/RAMitchell/orgs","repos_url":"https://api.github.com/users/RAMitchell/repos","events_url":"https://api.github.com/users/RAMitchell/events{/privacy}","received_events_url":"https://api.github.com/users/RAMitchell/received_events","type":"User","site_admin":false},"repo":{"id":61005359,"node_id":"MDEwOlJlcG9zaXRvcnk2MTAwNTM1OQ==","name":"xgboost","full_name":"RAMitchell/xgboost","private":false,"owner":{"login":"RAMitchell","id":7307640,"node_id":"MDQ6VXNlcjczMDc2NDA=","avatar_url":"https://avatars2.githubusercontent.com/u/7307640?v=4","gravatar_id":"","url":"https://api.github.com/users/RAMitchell","html_url":"https://github.com/RAMitchell","followers_url":"https://api.github.com/users/RAMitchell/followers","following_url":"https://api.github.com/users/RAMitchell/following{/other_user}","gists_url":"https://api.github.com/users/RAMitchell/gists{/gist_id}","starred_url":"https://api.github.com/users/RAMitchell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RAMitchell/subscriptions","organizations_url":"https://api.github.com/users/RAMitchell/orgs","repos_url":"https://api.github.com/users/RAMitchell/repos","events_url":"https://api.github.com/users/RAMitchell/events{/privacy}","received_events_url":"https://api.github.com/users/RAMitchell/received_events","type":"User","site_admin":false},"html_url":"https://github.com/RAMitchell/xgboost","description":"Scalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library,  for Python, R, Java, Scala, C++ and more. Runs on single machine, Hadoop, Spark, Flink and DataFlow","fork":true,"url":"https://api.github.com/repos/RAMitchell/xgboost","forks_url":"https://api.github.com/repos/RAMitchell/xgboost/forks","keys_url":"https://api.github.com/repos/RAMitchell/xgboost/keys{/key_id}","collaborators_url":"https://api.github.com/repos/RAMitchell/xgboost/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/RAMitchell/xgboost/teams","hooks_url":"https://api.github.com/repos/RAMitchell/xgboost/hooks","issue_events_url":"https://api.github.com/repos/RAMitchell/xgboost/issues/events{/number}","events_url":"https://api.github.com/repos/RAMitchell/xgboost/events","assignees_url":"https://api.github.com/repos/RAMitchell/xgboost/assignees{/user}","branches_url":"https://api.github.com/repos/RAMitchell/xgboost/branches{/branch}","tags_url":"https://api.github.com/repos/RAMitchell/xgboost/tags","blobs_url":"https://api.github.com/repos/RAMitchell/xgboost/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/RAMitchell/xgboost/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/RAMitchell/xgboost/git/refs{/sha}","trees_url":"https://api.github.com/repos/RAMitchell/xgboost/git/trees{/sha}","statuses_url":"https://api.github.com/repos/RAMitchell/xgboost/statuses/{sha}","languages_url":"https://api.github.com/repos/RAMitchell/xgboost/languages","stargazers_url":"https://api.github.com/repos/RAMitchell/xgboost/stargazers","contributors_url":"https://api.github.com/repos/RAMitchell/xgboost/contributors","subscribers_url":"https://api.github.com/repos/RAMitchell/xgboost/subscribers","subscription_url":"https://api.github.com/repos/RAMitchell/xgboost/subscription","commits_url":"https://api.github.com/repos/RAMitchell/xgboost/commits{/sha}","git_commits_url":"https://api.github.com/repos/RAMitchell/xgboost/git/commits{/sha}","comments_url":"https://api.github.com/repos/RAMitchell/xgboost/comments{/number}","issue_comment_url":"https://api.github.com/repos/RAMitchell/xgboost/issues/comments{/number}","contents_url":"https://api.github.com/repos/RAMitchell/xgboost/contents/{+path}","compare_url":"https://api.github.com/repos/RAMitchell/xgboost/compare/{base}...{head}","merges_url":"https://api.github.com/repos/RAMitchell/xgboost/merges","archive_url":"https://api.github.com/repos/RAMitchell/xgboost/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/RAMitchell/xgboost/downloads","issues_url":"https://api.github.com/repos/RAMitchell/xgboost/issues{/number}","pulls_url":"https://api.github.com/repos/RAMitchell/xgboost/pulls{/number}","milestones_url":"https://api.github.com/repos/RAMitchell/xgboost/milestones{/number}","notifications_url":"https://api.github.com/repos/RAMitchell/xgboost/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/RAMitchell/xgboost/labels{/name}","releases_url":"https://api.github.com/repos/RAMitchell/xgboost/releases{/id}","deployments_url":"https://api.github.com/repos/RAMitchell/xgboost/deployments","created_at":"2016-06-13T03:50:02Z","updated_at":"2018-07-16T06:34:00Z","pushed_at":"2018-09-29T04:49:24Z","git_url":"git://github.com/RAMitchell/xgboost.git","ssh_url":"git@github.com:RAMitchell/xgboost.git","clone_url":"https://github.com/RAMitchell/xgboost.git","svn_url":"https://github.com/RAMitchell/xgboost","homepage":"","size":9896,"stargazers_count":1,"watchers_count":1,"language":"C++","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":"other","name":"NOASSERTION","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"dmlc:master","ref":"master","sha":"baef5741dfeec121dbeca9802e6b00a75ed72d03","user":{"login":"dmlc","id":11508361,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExNTA4MzYx","avatar_url":"https://avatars2.githubusercontent.com/u/11508361?v=4","gravatar_id":"","url":"https://api.github.com/users/dmlc","html_url":"https://github.com/dmlc","followers_url":"https://api.github.com/users/dmlc/followers","following_url":"https://api.github.com/users/dmlc/following{/other_user}","gists_url":"https://api.github.com/users/dmlc/gists{/gist_id}","starred_url":"https://api.github.com/users/dmlc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmlc/subscriptions","organizations_url":"https://api.github.com/users/dmlc/orgs","repos_url":"https://api.github.com/users/dmlc/repos","events_url":"https://api.github.com/users/dmlc/events{/privacy}","received_events_url":"https://api.github.com/users/dmlc/received_events","type":"Organization","site_admin":false},"repo":{"id":16587283,"node_id":"MDEwOlJlcG9zaXRvcnkxNjU4NzI4Mw==","name":"xgboost","full_name":"dmlc/xgboost","private":false,"owner":{"login":"dmlc","id":11508361,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExNTA4MzYx","avatar_url":"https://avatars2.githubusercontent.com/u/11508361?v=4","gravatar_id":"","url":"https://api.github.com/users/dmlc","html_url":"https://github.com/dmlc","followers_url":"https://api.github.com/users/dmlc/followers","following_url":"https://api.github.com/users/dmlc/following{/other_user}","gists_url":"https://api.github.com/users/dmlc/gists{/gist_id}","starred_url":"https://api.github.com/users/dmlc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmlc/subscriptions","organizations_url":"https://api.github.com/users/dmlc/orgs","repos_url":"https://api.github.com/users/dmlc/repos","events_url":"https://api.github.com/users/dmlc/events{/privacy}","received_events_url":"https://api.github.com/users/dmlc/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/dmlc/xgboost","description":"Scalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library,  for Python, R, Java, Scala, C++ and more. Runs on single machine, Hadoop, Spark, Flink and DataFlow","fork":false,"url":"https://api.github.com/repos/dmlc/xgboost","forks_url":"https://api.github.com/repos/dmlc/xgboost/forks","keys_url":"https://api.github.com/repos/dmlc/xgboost/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dmlc/xgboost/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dmlc/xgboost/teams","hooks_url":"https://api.github.com/repos/dmlc/xgboost/hooks","issue_events_url":"https://api.github.com/repos/dmlc/xgboost/issues/events{/number}","events_url":"https://api.github.com/repos/dmlc/xgboost/events","assignees_url":"https://api.github.com/repos/dmlc/xgboost/assignees{/user}","branches_url":"https://api.github.com/repos/dmlc/xgboost/branches{/branch}","tags_url":"https://api.github.com/repos/dmlc/xgboost/tags","blobs_url":"https://api.github.com/repos/dmlc/xgboost/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dmlc/xgboost/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dmlc/xgboost/git/refs{/sha}","trees_url":"https://api.github.com/repos/dmlc/xgboost/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dmlc/xgboost/statuses/{sha}","languages_url":"https://api.github.com/repos/dmlc/xgboost/languages","stargazers_url":"https://api.github.com/repos/dmlc/xgboost/stargazers","contributors_url":"https://api.github.com/repos/dmlc/xgboost/contributors","subscribers_url":"https://api.github.com/repos/dmlc/xgboost/subscribers","subscription_url":"https://api.github.com/repos/dmlc/xgboost/subscription","commits_url":"https://api.github.com/repos/dmlc/xgboost/commits{/sha}","git_commits_url":"https://api.github.com/repos/dmlc/xgboost/git/commits{/sha}","comments_url":"https://api.github.com/repos/dmlc/xgboost/comments{/number}","issue_comment_url":"https://api.github.com/repos/dmlc/xgboost/issues/comments{/number}","contents_url":"https://api.github.com/repos/dmlc/xgboost/contents/{+path}","compare_url":"https://api.github.com/repos/dmlc/xgboost/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dmlc/xgboost/merges","archive_url":"https://api.github.com/repos/dmlc/xgboost/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dmlc/xgboost/downloads","issues_url":"https://api.github.com/repos/dmlc/xgboost/issues{/number}","pulls_url":"https://api.github.com/repos/dmlc/xgboost/pulls{/number}","milestones_url":"https://api.github.com/repos/dmlc/xgboost/milestones{/number}","notifications_url":"https://api.github.com/repos/dmlc/xgboost/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dmlc/xgboost/labels{/name}","releases_url":"https://api.github.com/repos/dmlc/xgboost/releases{/id}","deployments_url":"https://api.github.com/repos/dmlc/xgboost/deployments","created_at":"2014-02-06T17:28:03Z","updated_at":"2018-09-30T07:46:39Z","pushed_at":"2018-09-30T07:49:45Z","git_url":"git://github.com/dmlc/xgboost.git","ssh_url":"git@github.com:dmlc/xgboost.git","clone_url":"https://github.com/dmlc/xgboost.git","svn_url":"https://github.com/dmlc/xgboost","homepage":"https://xgboost.ai/","size":9687,"stargazers_count":13594,"watchers_count":13594,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5956,"mirror_url":null,"archived":false,"open_issues_count":60,"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":5956,"open_issues":60,"watchers":13594,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dmlc/xgboost/pulls/3395"},"html":{"href":"https://github.com/dmlc/xgboost/pull/3395"},"issue":{"href":"https://api.github.com/repos/dmlc/xgboost/issues/3395"},"comments":{"href":"https://api.github.com/repos/dmlc/xgboost/issues/3395/comments"},"review_comments":{"href":"https://api.github.com/repos/dmlc/xgboost/pulls/3395/comments"},"review_comment":{"href":"https://api.github.com/repos/dmlc/xgboost/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dmlc/xgboost/pulls/3395/commits"},"statuses":{"href":"https://api.github.com/repos/dmlc/xgboost/statuses/7078d360db6c9222be69429e43af196066e5a2a4"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"RAMitchell"}}