{"action":"created","comment":{"url":"https://api.github.com/repos/broadinstitute/hail/pulls/comments/75534391","id":75534391,"diff_hunk":"@@ -0,0 +1,159 @@\n+package org.apache.spark.rdd\n+\n+import org.apache.spark._\n+import org.broadinstitute.hail.Utils._\n+\n+import scala.collection.mutable\n+import scala.collection.mutable.ArrayBuffer\n+import scala.reflect.ClassTag\n+import scala.util.hashing._\n+\n+object OrderedRDD {\n+\n+\n+  def apply[T, K, V](rdd: RDD[(K, V)], reducedRDD: Option[RDD[K]] = None)\n+    (implicit ev: (K) => T, tOrd: Ordering[T], kOrd: Ordering[K], tct: ClassTag[T], kct: ClassTag[K]): OrderedRDD[T, K, V] = {\n+\n+    def fromPartitionSummaries(arr: Array[(Int, Boolean, T, T)]): Option[OrderedRDD[T, K, V]] = {\n+      val allKSorted = arr.forall(_._2)\n+\n+      val minMax = arr.map(x => (x._3, x._4))\n+      val sortedBetweenPartitions = minMax.tail.map(_._1).zip(minMax.map(_._2))\n+        .forall { case (nextMin, lastMax) => tOrd.gt(nextMin, lastMax) }\n+\n+      if (sortedBetweenPartitions) {\n+        val ab = mutable.ArrayBuilder.make[T]()\n+        minMax.take(minMax.length - 1).foreach { case (_, max) => ab += max }\n+\n+        val partitioner = OrderedPartitioner[T, K](ab.result())\n+        assert(partitioner.numPartitions == rdd.partitions.length)\n+\n+        if (allKSorted) {\n+          info(\"Coerced key-sorted RDD\")\n+          Some(new OrderedRDD[T, K, V](rdd, partitioner))\n+        } else {\n+          val sortedRDD = rdd.mapPartitionsWithIndex { case (i, it) =>\n+            if (arr(i)._2)\n+              it\n+            else it.localKeySort[T]\n+          }\n+          info(\"Coerced partition-key-sorted RDD\")\n+          Some(new OrderedRDD(sortedRDD, partitioner))\n+        }\n+      }\n+      else None\n+    }\n+\n+    def verifySortedness(i: Int, it: Iterator[K]): Iterator[Option[(Int, Boolean, T, T)]] = {\n+      if (it.isEmpty)\n+        Iterator(None)\n+      else {\n+        var sortedT = true\n+        var sortedK = true\n+        var continue = true\n+        val firstK = it.next()\n+        var lastK = firstK\n+        var lastT = ev(firstK)\n+\n+        while (it.hasNext && continue) {\n+          val k = it.next()\n+          val t = ev(k)\n+          if (tOrd.lt(t, lastT)) {\n+            sortedT = false\n+            continue = false\n+          } else if (kOrd.lt(k, lastK))\n+            sortedK = false\n+\n+          lastK = k\n+          lastT = t\n+        }\n+        if (!sortedT)\n+          Iterator(None)\n+        else Iterator(Some((i, sortedK, ev(firstK), ev(lastK))))\n+      }\n+    }\n+\n+    def fromShuffle(): OrderedRDD[T, K, V] = {\n+      info(\"ordering with network shuffle\")\n+      val ranges: Array[T] = calculateKeyRanges[T](reducedRDD.map(_.map(k => ev(k)))\n+        .getOrElse(rdd.map { case (k, _) => ev(k) }))\n+      val partitioner = OrderedPartitioner[T, K](ranges)\n+      new OrderedRDD[T, K, V](new ShuffledRDD[K, V, V](rdd, partitioner).setKeyOrdering(kOrd), partitioner)\n+    }\n+\n+    rdd match {\n+      case _: OrderedRDD[T, K, V] =>\n+        rdd.asInstanceOf[OrderedRDD[T, K, V]]\n+      case _: EmptyRDD[(K, V)] => new OrderedRDD(rdd, OrderedPartitioner(Array.empty[T]))\n+      case _ =>\n+        rdd.partitioner match {\n+          case Some(p: OrderedPartitioner[T, K]) =>\n+            new OrderedRDD(rdd, p)\n+          case _ =>\n+            val result = reducedRDD.getOrElse(rdd.map(_._1))\n+              .mapPartitionsWithIndex(verifySortedness).collect()\n+\n+            anyFailAllFail[Array, (Int, Boolean, T, T)](result)\n+              .map(_.sortBy(_._1))\n+              .flatMap(fromPartitionSummaries)\n+              .getOrElse(fromShuffle())\n+        }\n+    }\n+  }\n+\n+  /**\n+    * Lifted from org.apache.spark.RangePartitioner.scala in org.apache.spark\n+    */\n+  def calculateKeyRanges[T](rdd: RDD[T])(implicit ord: Ordering[T], tct: ClassTag[T]): Array[T] = {\n+    // This is the sample size we need to have roughly balanced output partitions, capped at 1M.\n+    val sampleSize = math.min(20.0 * rdd.partitions.length, 1e6)\n+    // Assume the input partitions are roughly balanced and over-sample a little bit.\n+    val sampleSizePerPartition = math.ceil(3.0 * sampleSize / rdd.partitions.length).toInt\n+    val (numItems, sketched) = RangePartitioner.sketch(rdd, sampleSizePerPartition)\n+    if (numItems == 0L) {\n+      Array.empty\n+    } else {\n+      // If a partition contains much more than the average number of items, we re-sample from it\n+      // to ensure that enough items are collected from that partition.\n+      val fraction = math.min(sampleSize / math.max(numItems, 1L), 1.0)\n+      val candidates = ArrayBuffer.empty[(T, Float)]\n+      val imbalancedPartitions = mutable.Set.empty[Int]\n+      sketched.foreach {\n+        case (idx, n, sample) =>\n+          if (fraction * n > sampleSizePerPartition) {\n+            imbalancedPartitions += idx\n+          } else {\n+            // The weight is 1 over the sampling probability.\n+            val weight = (n.toDouble / sample.length).toFloat\n+            for (key <- sample) {\n+              candidates += ((key, weight))\n+            }\n+          }\n+      }\n+      if (imbalancedPartitions.nonEmpty) {\n+        // Re-sample imbalanced partitions with the desired sampling probability.\n+        val imbalanced = new PartitionPruningRDD(rdd, imbalancedPartitions.contains)\n+        val seed = byteswap32(-rdd.id - 1)\n+        val reSampled = imbalanced.sample(withReplacement = false, fraction, seed).collect()\n+        val weight = (1.0 / fraction).toFloat\n+        candidates ++= reSampled.map(x => (x, weight))\n+      }\n+      RangePartitioner.determineBounds(candidates, rdd.partitions.length)\n+    }\n+  }\n+\n+}\n+\n+class OrderedRDD[T, K, V](rdd: RDD[(K, V)], p: OrderedPartitioner[T, K])\n+  (implicit ev: (K) => T, tOrd: Ordering[T], kOrd: Ordering[K], tct: ClassTag[T], kct: ClassTag[K]) extends RDD[(K, V)](rdd) {\n+\n+  def orderedPartitioner = p","path":"src/main/scala/org/apache/spark/rdd/OrderedRDD.scala","position":150,"original_position":150,"commit_id":"a033bc2b03020455e792abb857a1a5b4c96d486a","original_commit_id":"a033bc2b03020455e792abb857a1a5b4c96d486a","user":{"login":"cseed","id":1244990,"avatar_url":"https://avatars.githubusercontent.com/u/1244990?v=3","gravatar_id":"","url":"https://api.github.com/users/cseed","html_url":"https://github.com/cseed","followers_url":"https://api.github.com/users/cseed/followers","following_url":"https://api.github.com/users/cseed/following{/other_user}","gists_url":"https://api.github.com/users/cseed/gists{/gist_id}","starred_url":"https://api.github.com/users/cseed/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cseed/subscriptions","organizations_url":"https://api.github.com/users/cseed/orgs","repos_url":"https://api.github.com/users/cseed/repos","events_url":"https://api.github.com/users/cseed/events{/privacy}","received_events_url":"https://api.github.com/users/cseed/received_events","type":"User","site_admin":false},"body":"This can just be `val orderedPartitioner: OrderedPartitioner[T, K]` in the constructor.","created_at":"2016-08-19T18:55:09Z","updated_at":"2016-08-19T18:55:09Z","html_url":"https://github.com/broadinstitute/hail/pull/555#discussion_r75534391","pull_request_url":"https://api.github.com/repos/broadinstitute/hail/pulls/555","_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/hail/pulls/comments/75534391"},"html":{"href":"https://github.com/broadinstitute/hail/pull/555#discussion_r75534391"},"pull_request":{"href":"https://api.github.com/repos/broadinstitute/hail/pulls/555"}}},"pull_request":{"url":"https://api.github.com/repos/broadinstitute/hail/pulls/555","id":80381732,"html_url":"https://github.com/broadinstitute/hail/pull/555","diff_url":"https://github.com/broadinstitute/hail/pull/555.diff","patch_url":"https://github.com/broadinstitute/hail/pull/555.patch","issue_url":"https://api.github.com/repos/broadinstitute/hail/issues/555","number":555,"state":"open","locked":false,"title":"Impose sorted partitioning on RDDs for huge performance gains","user":{"login":"tpoterba","id":10562794,"avatar_url":"https://avatars.githubusercontent.com/u/10562794?v=3","gravatar_id":"","url":"https://api.github.com/users/tpoterba","html_url":"https://github.com/tpoterba","followers_url":"https://api.github.com/users/tpoterba/followers","following_url":"https://api.github.com/users/tpoterba/following{/other_user}","gists_url":"https://api.github.com/users/tpoterba/gists{/gist_id}","starred_url":"https://api.github.com/users/tpoterba/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tpoterba/subscriptions","organizations_url":"https://api.github.com/users/tpoterba/orgs","repos_url":"https://api.github.com/users/tpoterba/repos","events_url":"https://api.github.com/users/tpoterba/events{/privacy}","received_events_url":"https://api.github.com/users/tpoterba/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-08-07T23:45:16Z","updated_at":"2016-08-19T18:55:09Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e7f59d3ebbb9bdc1ec0e57b1596bbe93ad32178f","assignee":{"login":"danking","id":106194,"avatar_url":"https://avatars.githubusercontent.com/u/106194?v=3","gravatar_id":"","url":"https://api.github.com/users/danking","html_url":"https://github.com/danking","followers_url":"https://api.github.com/users/danking/followers","following_url":"https://api.github.com/users/danking/following{/other_user}","gists_url":"https://api.github.com/users/danking/gists{/gist_id}","starred_url":"https://api.github.com/users/danking/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danking/subscriptions","organizations_url":"https://api.github.com/users/danking/orgs","repos_url":"https://api.github.com/users/danking/repos","events_url":"https://api.github.com/users/danking/events{/privacy}","received_events_url":"https://api.github.com/users/danking/received_events","type":"User","site_admin":false},"assignees":[{"login":"danking","id":106194,"avatar_url":"https://avatars.githubusercontent.com/u/106194?v=3","gravatar_id":"","url":"https://api.github.com/users/danking","html_url":"https://github.com/danking","followers_url":"https://api.github.com/users/danking/followers","following_url":"https://api.github.com/users/danking/following{/other_user}","gists_url":"https://api.github.com/users/danking/gists{/gist_id}","starred_url":"https://api.github.com/users/danking/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danking/subscriptions","organizations_url":"https://api.github.com/users/danking/orgs","repos_url":"https://api.github.com/users/danking/repos","events_url":"https://api.github.com/users/danking/events{/privacy}","received_events_url":"https://api.github.com/users/danking/received_events","type":"User","site_admin":false},{"login":"cseed","id":1244990,"avatar_url":"https://avatars.githubusercontent.com/u/1244990?v=3","gravatar_id":"","url":"https://api.github.com/users/cseed","html_url":"https://github.com/cseed","followers_url":"https://api.github.com/users/cseed/followers","following_url":"https://api.github.com/users/cseed/following{/other_user}","gists_url":"https://api.github.com/users/cseed/gists{/gist_id}","starred_url":"https://api.github.com/users/cseed/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cseed/subscriptions","organizations_url":"https://api.github.com/users/cseed/orgs","repos_url":"https://api.github.com/users/cseed/repos","events_url":"https://api.github.com/users/cseed/events{/privacy}","received_events_url":"https://api.github.com/users/cseed/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/broadinstitute/hail/pulls/555/commits","review_comments_url":"https://api.github.com/repos/broadinstitute/hail/pulls/555/comments","review_comment_url":"https://api.github.com/repos/broadinstitute/hail/pulls/comments{/number}","comments_url":"https://api.github.com/repos/broadinstitute/hail/issues/555/comments","statuses_url":"https://api.github.com/repos/broadinstitute/hail/statuses/a033bc2b03020455e792abb857a1a5b4c96d486a","head":{"label":"tpoterba:tp_partitioning_2","ref":"tp_partitioning_2","sha":"a033bc2b03020455e792abb857a1a5b4c96d486a","user":{"login":"tpoterba","id":10562794,"avatar_url":"https://avatars.githubusercontent.com/u/10562794?v=3","gravatar_id":"","url":"https://api.github.com/users/tpoterba","html_url":"https://github.com/tpoterba","followers_url":"https://api.github.com/users/tpoterba/followers","following_url":"https://api.github.com/users/tpoterba/following{/other_user}","gists_url":"https://api.github.com/users/tpoterba/gists{/gist_id}","starred_url":"https://api.github.com/users/tpoterba/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tpoterba/subscriptions","organizations_url":"https://api.github.com/users/tpoterba/orgs","repos_url":"https://api.github.com/users/tpoterba/repos","events_url":"https://api.github.com/users/tpoterba/events{/privacy}","received_events_url":"https://api.github.com/users/tpoterba/received_events","type":"User","site_admin":false},"repo":{"id":64860564,"name":"hail","full_name":"tpoterba/hail","owner":{"login":"tpoterba","id":10562794,"avatar_url":"https://avatars.githubusercontent.com/u/10562794?v=3","gravatar_id":"","url":"https://api.github.com/users/tpoterba","html_url":"https://github.com/tpoterba","followers_url":"https://api.github.com/users/tpoterba/followers","following_url":"https://api.github.com/users/tpoterba/following{/other_user}","gists_url":"https://api.github.com/users/tpoterba/gists{/gist_id}","starred_url":"https://api.github.com/users/tpoterba/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tpoterba/subscriptions","organizations_url":"https://api.github.com/users/tpoterba/orgs","repos_url":"https://api.github.com/users/tpoterba/repos","events_url":"https://api.github.com/users/tpoterba/events{/privacy}","received_events_url":"https://api.github.com/users/tpoterba/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tpoterba/hail","description":"Hail, a framework for scalable genetic data analysis","fork":true,"url":"https://api.github.com/repos/tpoterba/hail","forks_url":"https://api.github.com/repos/tpoterba/hail/forks","keys_url":"https://api.github.com/repos/tpoterba/hail/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tpoterba/hail/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tpoterba/hail/teams","hooks_url":"https://api.github.com/repos/tpoterba/hail/hooks","issue_events_url":"https://api.github.com/repos/tpoterba/hail/issues/events{/number}","events_url":"https://api.github.com/repos/tpoterba/hail/events","assignees_url":"https://api.github.com/repos/tpoterba/hail/assignees{/user}","branches_url":"https://api.github.com/repos/tpoterba/hail/branches{/branch}","tags_url":"https://api.github.com/repos/tpoterba/hail/tags","blobs_url":"https://api.github.com/repos/tpoterba/hail/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tpoterba/hail/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tpoterba/hail/git/refs{/sha}","trees_url":"https://api.github.com/repos/tpoterba/hail/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tpoterba/hail/statuses/{sha}","languages_url":"https://api.github.com/repos/tpoterba/hail/languages","stargazers_url":"https://api.github.com/repos/tpoterba/hail/stargazers","contributors_url":"https://api.github.com/repos/tpoterba/hail/contributors","subscribers_url":"https://api.github.com/repos/tpoterba/hail/subscribers","subscription_url":"https://api.github.com/repos/tpoterba/hail/subscription","commits_url":"https://api.github.com/repos/tpoterba/hail/commits{/sha}","git_commits_url":"https://api.github.com/repos/tpoterba/hail/git/commits{/sha}","comments_url":"https://api.github.com/repos/tpoterba/hail/comments{/number}","issue_comment_url":"https://api.github.com/repos/tpoterba/hail/issues/comments{/number}","contents_url":"https://api.github.com/repos/tpoterba/hail/contents/{+path}","compare_url":"https://api.github.com/repos/tpoterba/hail/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tpoterba/hail/merges","archive_url":"https://api.github.com/repos/tpoterba/hail/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tpoterba/hail/downloads","issues_url":"https://api.github.com/repos/tpoterba/hail/issues{/number}","pulls_url":"https://api.github.com/repos/tpoterba/hail/pulls{/number}","milestones_url":"https://api.github.com/repos/tpoterba/hail/milestones{/number}","notifications_url":"https://api.github.com/repos/tpoterba/hail/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tpoterba/hail/labels{/name}","releases_url":"https://api.github.com/repos/tpoterba/hail/releases{/id}","deployments_url":"https://api.github.com/repos/tpoterba/hail/deployments","created_at":"2016-08-03T16:15:03Z","updated_at":"2016-08-03T16:15:05Z","pushed_at":"2016-08-18T22:41:21Z","git_url":"git://github.com/tpoterba/hail.git","ssh_url":"git@github.com:tpoterba/hail.git","clone_url":"https://github.com/tpoterba/hail.git","svn_url":"https://github.com/tpoterba/hail","homepage":"","size":5757,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"broadinstitute:master","ref":"master","sha":"10a4d1cc01ff90d3b1c7f0370bf26d0240acee98","user":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"repo":{"id":45069467,"name":"hail","full_name":"broadinstitute/hail","owner":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/broadinstitute/hail","description":"scalable genetic data analysis https://hail.is","fork":false,"url":"https://api.github.com/repos/broadinstitute/hail","forks_url":"https://api.github.com/repos/broadinstitute/hail/forks","keys_url":"https://api.github.com/repos/broadinstitute/hail/keys{/key_id}","collaborators_url":"https://api.github.com/repos/broadinstitute/hail/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/broadinstitute/hail/teams","hooks_url":"https://api.github.com/repos/broadinstitute/hail/hooks","issue_events_url":"https://api.github.com/repos/broadinstitute/hail/issues/events{/number}","events_url":"https://api.github.com/repos/broadinstitute/hail/events","assignees_url":"https://api.github.com/repos/broadinstitute/hail/assignees{/user}","branches_url":"https://api.github.com/repos/broadinstitute/hail/branches{/branch}","tags_url":"https://api.github.com/repos/broadinstitute/hail/tags","blobs_url":"https://api.github.com/repos/broadinstitute/hail/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/broadinstitute/hail/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/broadinstitute/hail/git/refs{/sha}","trees_url":"https://api.github.com/repos/broadinstitute/hail/git/trees{/sha}","statuses_url":"https://api.github.com/repos/broadinstitute/hail/statuses/{sha}","languages_url":"https://api.github.com/repos/broadinstitute/hail/languages","stargazers_url":"https://api.github.com/repos/broadinstitute/hail/stargazers","contributors_url":"https://api.github.com/repos/broadinstitute/hail/contributors","subscribers_url":"https://api.github.com/repos/broadinstitute/hail/subscribers","subscription_url":"https://api.github.com/repos/broadinstitute/hail/subscription","commits_url":"https://api.github.com/repos/broadinstitute/hail/commits{/sha}","git_commits_url":"https://api.github.com/repos/broadinstitute/hail/git/commits{/sha}","comments_url":"https://api.github.com/repos/broadinstitute/hail/comments{/number}","issue_comment_url":"https://api.github.com/repos/broadinstitute/hail/issues/comments{/number}","contents_url":"https://api.github.com/repos/broadinstitute/hail/contents/{+path}","compare_url":"https://api.github.com/repos/broadinstitute/hail/compare/{base}...{head}","merges_url":"https://api.github.com/repos/broadinstitute/hail/merges","archive_url":"https://api.github.com/repos/broadinstitute/hail/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/broadinstitute/hail/downloads","issues_url":"https://api.github.com/repos/broadinstitute/hail/issues{/number}","pulls_url":"https://api.github.com/repos/broadinstitute/hail/pulls{/number}","milestones_url":"https://api.github.com/repos/broadinstitute/hail/milestones{/number}","notifications_url":"https://api.github.com/repos/broadinstitute/hail/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/broadinstitute/hail/labels{/name}","releases_url":"https://api.github.com/repos/broadinstitute/hail/releases{/id}","deployments_url":"https://api.github.com/repos/broadinstitute/hail/deployments","created_at":"2015-10-27T20:55:42Z","updated_at":"2016-08-18T17:29:36Z","pushed_at":"2016-08-19T18:08:34Z","git_url":"git://github.com/broadinstitute/hail.git","ssh_url":"git@github.com:broadinstitute/hail.git","clone_url":"https://github.com/broadinstitute/hail.git","svn_url":"https://github.com/broadinstitute/hail","homepage":"","size":6697,"stargazers_count":44,"watchers_count":44,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":19,"mirror_url":null,"open_issues_count":180,"forks":19,"open_issues":180,"watchers":44,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/hail/pulls/555"},"html":{"href":"https://github.com/broadinstitute/hail/pull/555"},"issue":{"href":"https://api.github.com/repos/broadinstitute/hail/issues/555"},"comments":{"href":"https://api.github.com/repos/broadinstitute/hail/issues/555/comments"},"review_comments":{"href":"https://api.github.com/repos/broadinstitute/hail/pulls/555/comments"},"review_comment":{"href":"https://api.github.com/repos/broadinstitute/hail/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/broadinstitute/hail/pulls/555/commits"},"statuses":{"href":"https://api.github.com/repos/broadinstitute/hail/statuses/a033bc2b03020455e792abb857a1a5b4c96d486a"}}}}
{"actor":{"display_login":"cseed"}}