{"action":"created","comment":{"url":"https://api.github.com/repos/twitter/scalding/pulls/comments/26520153","id":26520153,"diff_hunk":"@@ -0,0 +1,540 @@\n+/*\n+Copyright 2012 Twitter, Inc.\n+\n+Licensed under the Apache License, Version 2.0 (the \"License\");\n+you may not use this file except in compliance with the License.\n+You may obtain a copy of the License at\n+\n+http://www.apache.org/licenses/LICENSE-2.0\n+\n+Unless required by applicable law or agreed to in writing, software\n+distributed under the License is distributed on an \"AS IS\" BASIS,\n+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+See the License for the specific language governing permissions and\n+limitations under the License.\n+*/\n+\n+package com.twitter.scalding.macros\n+\n+import org.scalatest.{ FunSuite, ShouldMatchers }\n+import org.scalatest.prop.Checkers\n+import org.scalatest.prop.PropertyChecks\n+import scala.language.experimental.macros\n+import com.twitter.scalding.serialization.{ OrderedSerialization, Law, Law1, Law2, Law3, Serialization }\n+import java.nio.ByteBuffer\n+import org.scalacheck.Arbitrary.{ arbitrary => arb }\n+import java.io.{ ByteArrayOutputStream, InputStream }\n+\n+import com.twitter.bijection.Bufferable\n+import org.scalacheck.{ Arbitrary, Gen, Prop }\n+import com.twitter.scalding.serialization.JavaStreamEnrichments\n+\n+import scala.collection.immutable.Queue\n+\n+trait LowerPriorityImplicit {\n+  implicit def primitiveOrderedBufferSupplier[T] = macro com.twitter.scalding.macros.impl.OrderedSerializationProviderImpl[T]\n+}\n+\n+object LawTester {\n+  def apply[T: Arbitrary](laws: Iterable[Law[T]]): Prop =\n+    apply(implicitly[Arbitrary[T]].arbitrary, laws)\n+\n+  def apply[T](g: Gen[T], laws: Iterable[Law[T]]): Prop =\n+    laws.foldLeft(true: Prop) {\n+      case (soFar, Law1(name, fn)) => soFar && Prop.forAll(g)(fn).label(name)\n+      case (soFar, Law2(name, fn)) => soFar && Prop.forAll(g, g)(fn).label(name)\n+      case (soFar, Law3(name, fn)) => soFar && Prop.forAll(g, g, g)(fn).label(name)\n+    }\n+}\n+\n+object ByteBufferArb {\n+  implicit def arbitraryTestTypes: Arbitrary[ByteBuffer] = Arbitrary {\n+    for {\n+      aBinary <- Gen.alphaStr.map(s => ByteBuffer.wrap(s.getBytes(\"UTF-8\")))\n+    } yield aBinary\n+  }\n+}\n+object TestCC {\n+  import ByteBufferArb._\n+  implicit def arbitraryTestCC: Arbitrary[TestCC] = Arbitrary {\n+    for {\n+      aInt <- arb[Int]\n+      aLong <- arb[Long]\n+      aDouble <- arb[Double]\n+      anOption <- arb[Option[Int]]\n+      anStrOption <- arb[Option[String]]\n+      anOptionOfAListOfStrings <- arb[Option[List[String]]]\n+      aBB <- arb[ByteBuffer]\n+    } yield TestCC(aInt, aLong, anOption, aDouble, anStrOption, anOptionOfAListOfStrings, aBB)\n+  }\n+}\n+case class TestCC(a: Int, b: Long, c: Option[Int], d: Double, e: Option[String], f: Option[List[String]], aBB: ByteBuffer)\n+\n+object MyData {\n+  implicit def arbitraryTestCC: Arbitrary[MyData] = Arbitrary {\n+    for {\n+      aInt <- arb[Int]\n+      anOption <- arb[Option[Long]]\n+    } yield new MyData(aInt, anOption)\n+  }\n+}\n+\n+class MyData(override val _1: Int, override val _2: Option[Long]) extends Product2[Int, Option[Long]] {\n+  override def canEqual(that: Any): Boolean = that match {\n+    case o: MyData => this._1 == o._1 && this._2 == o._2\n+    case _ => false\n+  }\n+}\n+\n+object MacroOpaqueContainer {\n+  import java.io._\n+  implicit val myContainerOrderedSerializer = new OrderedSerialization[MacroOpaqueContainer] {\n+    val intOrderedSerialization = _root_.com.twitter.scalding.macros.Macros.orderedBufferSupplier[Int]\n+\n+    override def hash(s: MacroOpaqueContainer) = intOrderedSerialization.hash(s.myField) ^ Int.MaxValue\n+    override def compare(a: MacroOpaqueContainer, b: MacroOpaqueContainer) = intOrderedSerialization.compare(a.myField, b.myField)\n+\n+    override def read(in: InputStream) = intOrderedSerialization.read(in).map(MacroOpaqueContainer(_))\n+\n+    override def write(b: OutputStream, s: MacroOpaqueContainer) = intOrderedSerialization.write(b, s.myField)\n+\n+    override def compareBinary(lhs: InputStream, rhs: InputStream) = intOrderedSerialization.compareBinary(lhs, rhs)\n+    override val staticSize = Some(4)\n+\n+    override def dynamicSize(i: MacroOpaqueContainer) = staticSize\n+  }\n+\n+  implicit def arbitraryMacroOpaqueContainer: Arbitrary[MacroOpaqueContainer] = Arbitrary {\n+    for {\n+      aInt <- arb[Int]\n+    } yield MacroOpaqueContainer(aInt)\n+  }\n+\n+  def apply(d: Int): MacroOpaqueContainer = new MacroOpaqueContainer(d)\n+}\n+\n+class MacroOpaqueContainer(val myField: Int) {\n+}\n+\n+object Container {\n+  implicit def arbitraryInnerCaseClass: Arbitrary[InnerCaseClass] = Arbitrary {\n+    for {\n+      anOption <- arb[Set[Double]]\n+    } yield InnerCaseClass(anOption)\n+  }\n+\n+  type SetAlias = Set[Double]\n+  case class InnerCaseClass(e: SetAlias)\n+}\n+class MacroOrderingProperties extends FunSuite with PropertyChecks with ShouldMatchers with LowerPriorityImplicit {\n+  type SetAlias = Set[Double]\n+\n+  import ByteBufferArb._\n+  import Container.arbitraryInnerCaseClass\n+\n+  import OrderedSerialization.{ compare => oBufCompare }\n+\n+  def gen[T: Arbitrary]: Gen[T] = implicitly[Arbitrary[T]].arbitrary\n+\n+  def arbMap[T: Arbitrary, U](fn: T => U): Arbitrary[U] = Arbitrary(gen[T].map(fn))\n+\n+  def collectionArb[C[_], T: Arbitrary](implicit cbf: collection.generic.CanBuildFrom[Nothing, T, C[T]]): Arbitrary[C[T]] = Arbitrary {\n+    gen[List[T]].map { l =>\n+      val builder = cbf()\n+      l.foreach { builder += _ }\n+      builder.result\n+    }\n+  }\n+\n+  def serialize[T](t: T)(implicit orderedBuffer: OrderedSerialization[T]): InputStream =\n+    serializeSeq(List(t))\n+\n+  def serializeSeq[T](t: Seq[T])(implicit orderedBuffer: OrderedSerialization[T]): InputStream = {\n+    import JavaStreamEnrichments._\n+\n+    val baos = new ByteArrayOutputStream\n+    t.foreach({ e =>\n+      orderedBuffer.write(baos, e)\n+    })\n+    baos.toInputStream\n+  }\n+\n+  def rt[T](t: T)(implicit orderedBuffer: OrderedSerialization[T]) = {\n+    val buf = serialize[T](t)\n+    orderedBuffer.read(buf).get\n+  }\n+\n+  def rawCompare[T](a: T, b: T)(implicit obuf: OrderedSerialization[T]): Int =\n+    obuf.compareBinary(serialize(a), serialize(b)).unsafeToInt\n+\n+  def checkManyExplicit[T](i: List[(T, T)])(implicit obuf: OrderedSerialization[T]) = {\n+    val serializedA = serializeSeq(i.map(_._1))\n+    val serializedB = serializeSeq(i.map(_._2))\n+    i.foreach {\n+      case (a, b) =>\n+        val compareBinary = obuf.compareBinary(serializedA, serializedB).unsafeToInt\n+        val compareMem = obuf.compare(a, b)\n+        if (compareBinary < 0) {\n+          assert(compareMem < 0, s\"Compare binary: $compareBinary, and compareMem : $compareMem must have the same sign\")\n+        } else if (compareBinary > 0) {\n+          assert(compareMem > 0, s\"Compare binary: $compareBinary, and compareMem : $compareMem must have the same sign\")\n+        }\n+    }\n+  }\n+\n+  def checkMany[T: Arbitrary](implicit obuf: OrderedSerialization[T]) = forAll { i: List[(T, T)] =>\n+    checkManyExplicit(i)\n+  }\n+\n+  def clamp(i: Int): Int =\n+    i match {\n+      case x if x < 0 => -1\n+      case x if x > 0 => 1\n+      case x => 0\n+    }\n+\n+  def checkWithInputs[T](a: T, b: T)(implicit obuf: OrderedSerialization[T]) {\n+    val rta = rt(a) // before we do anything ensure these don't throw\n+    val rtb = rt(b) // before we do anything ensure these don't throw\n+    val asize = Serialization.toBytes(a).length\n+    if (obuf.dynamicSize(a).isDefined) {\n+      assert(obuf.dynamicSize(a).get == asize, \"dynamic size matches the correct value\")\n+    }\n+    if (obuf.staticSize.isDefined) {\n+      assert(obuf.dynamicSize(a).get == asize, \"dynamic size matches the correct value\")\n+      assert(obuf.staticSize.get == asize, \"dynamic size matches the correct value\")\n+    }\n+    assert(oBufCompare(rta, a) === 0, s\"A should be equal to itself after an RT -- ${rt(a)}\")\n+    assert(oBufCompare(rtb, b) === 0, s\"B should be equal to itself after an RT-- ${rt(b)}\")\n+    assert(oBufCompare(a, b) + oBufCompare(b, a) === 0, \"In memory comparasons make sense\")","path":"scalding-macros/src/test/scala/com/twitter/scalding/macros/MacroOrderingProperties.scala","position":202,"original_position":209,"commit_id":"50a6b71fac29eb73f3b1dd28f1a4dba317c76342","original_commit_id":"6104de58a0c68c7f5d487abd5d40faf8b416f724","user":{"login":"isnotinvain","id":372969,"avatar_url":"https://avatars.githubusercontent.com/u/372969?v=3","gravatar_id":"","url":"https://api.github.com/users/isnotinvain","html_url":"https://github.com/isnotinvain","followers_url":"https://api.github.com/users/isnotinvain/followers","following_url":"https://api.github.com/users/isnotinvain/following{/other_user}","gists_url":"https://api.github.com/users/isnotinvain/gists{/gist_id}","starred_url":"https://api.github.com/users/isnotinvain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/isnotinvain/subscriptions","organizations_url":"https://api.github.com/users/isnotinvain/orgs","repos_url":"https://api.github.com/users/isnotinvain/repos","events_url":"https://api.github.com/users/isnotinvain/events{/privacy}","received_events_url":"https://api.github.com/users/isnotinvain/received_events","type":"User","site_admin":false},"body":"Yeah, so that was my point:\r\n`assert(oBufCompare(a, b) + oBufCompare(b, a) === 0`\r\nis too strict right?\r\nShould be:\r\n`assert(oBufCompare(a, b).signum + oBufCompare(b, a).signum === 0`\r\n\r\nunless these compare methods always wind up going through `unsafeToInt` ?","created_at":"2015-03-16T19:41:55Z","updated_at":"2015-03-16T19:41:55Z","html_url":"https://github.com/twitter/scalding/pull/1209#discussion_r26520153","pull_request_url":"https://api.github.com/repos/twitter/scalding/pulls/1209","_links":{"self":{"href":"https://api.github.com/repos/twitter/scalding/pulls/comments/26520153"},"html":{"href":"https://github.com/twitter/scalding/pull/1209#discussion_r26520153"},"pull_request":{"href":"https://api.github.com/repos/twitter/scalding/pulls/1209"}}},"pull_request":{"url":"https://api.github.com/repos/twitter/scalding/pulls/1209","id":30044035,"html_url":"https://github.com/twitter/scalding/pull/1209","diff_url":"https://github.com/twitter/scalding/pull/1209.diff","patch_url":"https://github.com/twitter/scalding/pull/1209.patch","issue_url":"https://api.github.com/repos/twitter/scalding/issues/1209","number":1209,"state":"open","locked":false,"title":"Macros for OrderedSerialization","user":{"login":"johnynek","id":67958,"avatar_url":"https://avatars.githubusercontent.com/u/67958?v=3","gravatar_id":"","url":"https://api.github.com/users/johnynek","html_url":"https://github.com/johnynek","followers_url":"https://api.github.com/users/johnynek/followers","following_url":"https://api.github.com/users/johnynek/following{/other_user}","gists_url":"https://api.github.com/users/johnynek/gists{/gist_id}","starred_url":"https://api.github.com/users/johnynek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johnynek/subscriptions","organizations_url":"https://api.github.com/users/johnynek/orgs","repos_url":"https://api.github.com/users/johnynek/repos","events_url":"https://api.github.com/users/johnynek/events{/privacy}","received_events_url":"https://api.github.com/users/johnynek/received_events","type":"User","site_admin":false},"body":"These are the macros on top of #1208.\r\n\r\nWe should only merge this after #1208 is merged and probably after we have deployed this and tested in detail at Twitter.","created_at":"2015-02-26T01:47:14Z","updated_at":"2015-03-16T19:41:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8253d36aed0b4f8f77fd4ed474bb542ab5d82bdf","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/twitter/scalding/pulls/1209/commits","review_comments_url":"https://api.github.com/repos/twitter/scalding/pulls/1209/comments","review_comment_url":"https://api.github.com/repos/twitter/scalding/pulls/comments{/number}","comments_url":"https://api.github.com/repos/twitter/scalding/issues/1209/comments","statuses_url":"https://api.github.com/repos/twitter/scalding/statuses/50a6b71fac29eb73f3b1dd28f1a4dba317c76342","head":{"label":"twitter:fbs-staging-macros","ref":"fbs-staging-macros","sha":"50a6b71fac29eb73f3b1dd28f1a4dba317c76342","user":{"login":"twitter","id":50278,"avatar_url":"https://avatars.githubusercontent.com/u/50278?v=3","gravatar_id":"","url":"https://api.github.com/users/twitter","html_url":"https://github.com/twitter","followers_url":"https://api.github.com/users/twitter/followers","following_url":"https://api.github.com/users/twitter/following{/other_user}","gists_url":"https://api.github.com/users/twitter/gists{/gist_id}","starred_url":"https://api.github.com/users/twitter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twitter/subscriptions","organizations_url":"https://api.github.com/users/twitter/orgs","repos_url":"https://api.github.com/users/twitter/repos","events_url":"https://api.github.com/users/twitter/events{/privacy}","received_events_url":"https://api.github.com/users/twitter/received_events","type":"Organization","site_admin":false},"repo":{"id":3146558,"name":"scalding","full_name":"twitter/scalding","owner":{"login":"twitter","id":50278,"avatar_url":"https://avatars.githubusercontent.com/u/50278?v=3","gravatar_id":"","url":"https://api.github.com/users/twitter","html_url":"https://github.com/twitter","followers_url":"https://api.github.com/users/twitter/followers","following_url":"https://api.github.com/users/twitter/following{/other_user}","gists_url":"https://api.github.com/users/twitter/gists{/gist_id}","starred_url":"https://api.github.com/users/twitter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twitter/subscriptions","organizations_url":"https://api.github.com/users/twitter/orgs","repos_url":"https://api.github.com/users/twitter/repos","events_url":"https://api.github.com/users/twitter/events{/privacy}","received_events_url":"https://api.github.com/users/twitter/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/twitter/scalding","description":"A Scala API for Cascading","fork":false,"url":"https://api.github.com/repos/twitter/scalding","forks_url":"https://api.github.com/repos/twitter/scalding/forks","keys_url":"https://api.github.com/repos/twitter/scalding/keys{/key_id}","collaborators_url":"https://api.github.com/repos/twitter/scalding/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/twitter/scalding/teams","hooks_url":"https://api.github.com/repos/twitter/scalding/hooks","issue_events_url":"https://api.github.com/repos/twitter/scalding/issues/events{/number}","events_url":"https://api.github.com/repos/twitter/scalding/events","assignees_url":"https://api.github.com/repos/twitter/scalding/assignees{/user}","branches_url":"https://api.github.com/repos/twitter/scalding/branches{/branch}","tags_url":"https://api.github.com/repos/twitter/scalding/tags","blobs_url":"https://api.github.com/repos/twitter/scalding/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/twitter/scalding/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/twitter/scalding/git/refs{/sha}","trees_url":"https://api.github.com/repos/twitter/scalding/git/trees{/sha}","statuses_url":"https://api.github.com/repos/twitter/scalding/statuses/{sha}","languages_url":"https://api.github.com/repos/twitter/scalding/languages","stargazers_url":"https://api.github.com/repos/twitter/scalding/stargazers","contributors_url":"https://api.github.com/repos/twitter/scalding/contributors","subscribers_url":"https://api.github.com/repos/twitter/scalding/subscribers","subscription_url":"https://api.github.com/repos/twitter/scalding/subscription","commits_url":"https://api.github.com/repos/twitter/scalding/commits{/sha}","git_commits_url":"https://api.github.com/repos/twitter/scalding/git/commits{/sha}","comments_url":"https://api.github.com/repos/twitter/scalding/comments{/number}","issue_comment_url":"https://api.github.com/repos/twitter/scalding/issues/comments{/number}","contents_url":"https://api.github.com/repos/twitter/scalding/contents/{+path}","compare_url":"https://api.github.com/repos/twitter/scalding/compare/{base}...{head}","merges_url":"https://api.github.com/repos/twitter/scalding/merges","archive_url":"https://api.github.com/repos/twitter/scalding/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/twitter/scalding/downloads","issues_url":"https://api.github.com/repos/twitter/scalding/issues{/number}","pulls_url":"https://api.github.com/repos/twitter/scalding/pulls{/number}","milestones_url":"https://api.github.com/repos/twitter/scalding/milestones{/number}","notifications_url":"https://api.github.com/repos/twitter/scalding/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/twitter/scalding/labels{/name}","releases_url":"https://api.github.com/repos/twitter/scalding/releases{/id}","created_at":"2012-01-10T16:22:08Z","updated_at":"2015-03-15T11:47:50Z","pushed_at":"2015-03-14T01:38:47Z","git_url":"git://github.com/twitter/scalding.git","ssh_url":"git@github.com:twitter/scalding.git","clone_url":"https://github.com/twitter/scalding.git","svn_url":"https://github.com/twitter/scalding","homepage":"http://twitter.com/scalding","size":21327,"stargazers_count":1986,"watchers_count":1986,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":445,"mirror_url":null,"open_issues_count":225,"forks":445,"open_issues":225,"watchers":1986,"default_branch":"develop"}},"base":{"label":"twitter:develop","ref":"develop","sha":"ff79f900e797767c727dd78d4ed9b50a80bae249","user":{"login":"twitter","id":50278,"avatar_url":"https://avatars.githubusercontent.com/u/50278?v=3","gravatar_id":"","url":"https://api.github.com/users/twitter","html_url":"https://github.com/twitter","followers_url":"https://api.github.com/users/twitter/followers","following_url":"https://api.github.com/users/twitter/following{/other_user}","gists_url":"https://api.github.com/users/twitter/gists{/gist_id}","starred_url":"https://api.github.com/users/twitter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twitter/subscriptions","organizations_url":"https://api.github.com/users/twitter/orgs","repos_url":"https://api.github.com/users/twitter/repos","events_url":"https://api.github.com/users/twitter/events{/privacy}","received_events_url":"https://api.github.com/users/twitter/received_events","type":"Organization","site_admin":false},"repo":{"id":3146558,"name":"scalding","full_name":"twitter/scalding","owner":{"login":"twitter","id":50278,"avatar_url":"https://avatars.githubusercontent.com/u/50278?v=3","gravatar_id":"","url":"https://api.github.com/users/twitter","html_url":"https://github.com/twitter","followers_url":"https://api.github.com/users/twitter/followers","following_url":"https://api.github.com/users/twitter/following{/other_user}","gists_url":"https://api.github.com/users/twitter/gists{/gist_id}","starred_url":"https://api.github.com/users/twitter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twitter/subscriptions","organizations_url":"https://api.github.com/users/twitter/orgs","repos_url":"https://api.github.com/users/twitter/repos","events_url":"https://api.github.com/users/twitter/events{/privacy}","received_events_url":"https://api.github.com/users/twitter/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/twitter/scalding","description":"A Scala API for Cascading","fork":false,"url":"https://api.github.com/repos/twitter/scalding","forks_url":"https://api.github.com/repos/twitter/scalding/forks","keys_url":"https://api.github.com/repos/twitter/scalding/keys{/key_id}","collaborators_url":"https://api.github.com/repos/twitter/scalding/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/twitter/scalding/teams","hooks_url":"https://api.github.com/repos/twitter/scalding/hooks","issue_events_url":"https://api.github.com/repos/twitter/scalding/issues/events{/number}","events_url":"https://api.github.com/repos/twitter/scalding/events","assignees_url":"https://api.github.com/repos/twitter/scalding/assignees{/user}","branches_url":"https://api.github.com/repos/twitter/scalding/branches{/branch}","tags_url":"https://api.github.com/repos/twitter/scalding/tags","blobs_url":"https://api.github.com/repos/twitter/scalding/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/twitter/scalding/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/twitter/scalding/git/refs{/sha}","trees_url":"https://api.github.com/repos/twitter/scalding/git/trees{/sha}","statuses_url":"https://api.github.com/repos/twitter/scalding/statuses/{sha}","languages_url":"https://api.github.com/repos/twitter/scalding/languages","stargazers_url":"https://api.github.com/repos/twitter/scalding/stargazers","contributors_url":"https://api.github.com/repos/twitter/scalding/contributors","subscribers_url":"https://api.github.com/repos/twitter/scalding/subscribers","subscription_url":"https://api.github.com/repos/twitter/scalding/subscription","commits_url":"https://api.github.com/repos/twitter/scalding/commits{/sha}","git_commits_url":"https://api.github.com/repos/twitter/scalding/git/commits{/sha}","comments_url":"https://api.github.com/repos/twitter/scalding/comments{/number}","issue_comment_url":"https://api.github.com/repos/twitter/scalding/issues/comments{/number}","contents_url":"https://api.github.com/repos/twitter/scalding/contents/{+path}","compare_url":"https://api.github.com/repos/twitter/scalding/compare/{base}...{head}","merges_url":"https://api.github.com/repos/twitter/scalding/merges","archive_url":"https://api.github.com/repos/twitter/scalding/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/twitter/scalding/downloads","issues_url":"https://api.github.com/repos/twitter/scalding/issues{/number}","pulls_url":"https://api.github.com/repos/twitter/scalding/pulls{/number}","milestones_url":"https://api.github.com/repos/twitter/scalding/milestones{/number}","notifications_url":"https://api.github.com/repos/twitter/scalding/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/twitter/scalding/labels{/name}","releases_url":"https://api.github.com/repos/twitter/scalding/releases{/id}","created_at":"2012-01-10T16:22:08Z","updated_at":"2015-03-15T11:47:50Z","pushed_at":"2015-03-14T01:38:47Z","git_url":"git://github.com/twitter/scalding.git","ssh_url":"git@github.com:twitter/scalding.git","clone_url":"https://github.com/twitter/scalding.git","svn_url":"https://github.com/twitter/scalding","homepage":"http://twitter.com/scalding","size":21327,"stargazers_count":1986,"watchers_count":1986,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":445,"mirror_url":null,"open_issues_count":225,"forks":445,"open_issues":225,"watchers":1986,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/twitter/scalding/pulls/1209"},"html":{"href":"https://github.com/twitter/scalding/pull/1209"},"issue":{"href":"https://api.github.com/repos/twitter/scalding/issues/1209"},"comments":{"href":"https://api.github.com/repos/twitter/scalding/issues/1209/comments"},"review_comments":{"href":"https://api.github.com/repos/twitter/scalding/pulls/1209/comments"},"review_comment":{"href":"https://api.github.com/repos/twitter/scalding/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/twitter/scalding/pulls/1209/commits"},"statuses":{"href":"https://api.github.com/repos/twitter/scalding/statuses/50a6b71fac29eb73f3b1dd28f1a4dba317c76342"}}}}