{"action":"created","comment":{"url":"https://api.github.com/repos/scala-js/scala-js/pulls/comments/29833013","id":29833013,"diff_hunk":"@@ -0,0 +1,138 @@\n+package java.util.concurrent\n+\n+import scala.collection.JavaConversions.{ setAsJavaSet, asScalaSet, asJavaCollection, asJavaEnumeration }\n+\n+trait ConcurrentMap[K, V] extends java.util.Map[K, V] {\n+\n+  def putIfAbsent(key: K, value: V): V =\n+    if (!containsKey(key))\n+      put(key, value)\n+    else\n+      get(key)\n+\n+  def remove(key: Any, value: Any): Boolean =\n+    if (containsKey(key) && get(key).equals(value)) {\n+      remove(key)\n+      true\n+    } else false\n+\n+  def replace(key: K, value: V): V =\n+    if (containsKey(key)) {\n+      put(key, value)\n+    } else get(key)\n+\n+  def replace(key: K, oldValue: V, newValue: V): Boolean =\n+    if (containsKey(key) && get(key).equals(oldValue)) {\n+      put(key, newValue)\n+      true\n+    } else false\n+\n+}\n+\n+class ConcurrentHashMap[K >: Null, V >: Null](initialCapacity: Int = 16,\n+  loadFactor: Float = 0.75F,\n+  concurrencyLevel: Int = 16)\n+    extends java.util.AbstractMap[K, V]\n+    with java.util.concurrent.ConcurrentMap[K, V]\n+    with java.io.Serializable {\n+\n+  private lazy val inner = new scala.collection.mutable.HashMap[K, V]()\n+\n+  override def clear(): Unit =\n+    inner.clear\n+\n+  override def containsKey(key: Any): Boolean =\n+    try {\n+      inner.contains(key.asInstanceOf[K])\n+    } catch {\n+      case e: Throwable => false\n+    }\n+\n+  override def containsValue(value: Any): Boolean =\n+    try {\n+      inner.exists { case (ik, iv) => value.equals(iv) }\n+    } catch {\n+      case e: Throwable => false\n+    }\n+\n+  def elements(): java.util.Enumeration[V] =\n+    asJavaEnumeration(inner.values.iterator)\n+\n+  def entrySet(): java.util.Set[java.util.Map.Entry[K, V]] =\n+    setAsJavaSet(\n+      inner.map { case (k, v) => new java.util.AbstractMap.SimpleImmutableEntry(k, v) }.toSet\n+    )\n+\n+  override def get(key: Any): V =\n+    inner.get(key.asInstanceOf[K]).getOrElse(null)\n+\n+  override def isEmpty(): Boolean = inner.isEmpty\n+\n+  def keys(): java.util.Enumeration[K] =\n+    asJavaEnumeration(inner.keys.iterator)\n+\n+  // This will not work if used with JDK 8\n+  //override def keySet(): java.util.Set[K] =\n+  //\tsetAsJavaSet(inner.keys.toSet)\n+\n+  override def put(key: K, value: V): V =\n+    try {\n+      inner.put(key, value)\n+      value\n+    } catch {\n+      case _: Throwable => null\n+    }\n+\n+  override def putAll[K1 <: K, V1 <: V](m: java.util.Map[K1, V1]): Unit =\n+    for {\n+      e <- asScalaSet(m.entrySet())\n+    } yield {\n+      put(e.getKey, e.getValue)\n+    }\n+\n+  override def putIfAbsent(key: K, value: V): V =\n+    inner.get(key) match {\n+      case Some(actual) => actual\n+      case _ => inner.put(key, value); value\n+    }\n+\n+  override def remove(key: Any): V =\n+    inner.remove(key.asInstanceOf[K]).get\n+\n+  override def remove(key: Any, value: Any): Boolean =\n+    try {\n+      val old = inner(key.asInstanceOf[K])\n+      if (value.equals(old)) {\n+        inner.remove(key.asInstanceOf[K]).isDefined\n+      } else false\n+    } catch {\n+      case _: Throwable => false\n+    }\n+\n+  override def replace(key: K, value: V): V =\n+    try {\n+      inner(key)\n+      put(key, value)\n+      value\n+    } catch {\n+      case err: Throwable => null\n+    }\n+\n+  override def replace(key: K, oldValue: V, newValue: V): Boolean =\n+    try {\n+      val old = inner(key)\n+      assert(oldValue.equals(old))\n+      put(key, newValue)\n+      true\n+    } catch {\n+      case err: Throwable => false\n+    }\n+\n+  override def size() = {\n+    inner.size\n+  }","path":"javalib/src/main/scala/java/util/concurrent/ConcurrentHashMap.scala","position":133,"original_position":133,"commit_id":"f554bd615373e649bb0bb9c99b05d179e59f74ce","original_commit_id":"f554bd615373e649bb0bb9c99b05d179e59f74ce","user":{"login":"andreaTP","id":5792097,"avatar_url":"https://avatars.githubusercontent.com/u/5792097?v=3","gravatar_id":"","url":"https://api.github.com/users/andreaTP","html_url":"https://github.com/andreaTP","followers_url":"https://api.github.com/users/andreaTP/followers","following_url":"https://api.github.com/users/andreaTP/following{/other_user}","gists_url":"https://api.github.com/users/andreaTP/gists{/gist_id}","starred_url":"https://api.github.com/users/andreaTP/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreaTP/subscriptions","organizations_url":"https://api.github.com/users/andreaTP/orgs","repos_url":"https://api.github.com/users/andreaTP/repos","events_url":"https://api.github.com/users/andreaTP/events{/privacy}","received_events_url":"https://api.github.com/users/andreaTP/received_events","type":"User","site_admin":false},"body":"ok","created_at":"2015-05-07T08:29:57Z","updated_at":"2015-05-07T08:29:57Z","html_url":"https://github.com/scala-js/scala-js/pull/1636#discussion_r29833013","pull_request_url":"https://api.github.com/repos/scala-js/scala-js/pulls/1636","_links":{"self":{"href":"https://api.github.com/repos/scala-js/scala-js/pulls/comments/29833013"},"html":{"href":"https://github.com/scala-js/scala-js/pull/1636#discussion_r29833013"},"pull_request":{"href":"https://api.github.com/repos/scala-js/scala-js/pulls/1636"}}},"pull_request":{"url":"https://api.github.com/repos/scala-js/scala-js/pulls/1636","id":34717020,"html_url":"https://github.com/scala-js/scala-js/pull/1636","diff_url":"https://github.com/scala-js/scala-js/pull/1636.diff","patch_url":"https://github.com/scala-js/scala-js/pull/1636.patch","issue_url":"https://api.github.com/repos/scala-js/scala-js/issues/1636","number":1636,"state":"open","locked":false,"title":"Issue: #1487 Added ConcurrentHashMap implementation","user":{"login":"andreaTP","id":5792097,"avatar_url":"https://avatars.githubusercontent.com/u/5792097?v=3","gravatar_id":"","url":"https://api.github.com/users/andreaTP","html_url":"https://github.com/andreaTP","followers_url":"https://api.github.com/users/andreaTP/followers","following_url":"https://api.github.com/users/andreaTP/following{/other_user}","gists_url":"https://api.github.com/users/andreaTP/gists{/gist_id}","starred_url":"https://api.github.com/users/andreaTP/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreaTP/subscriptions","organizations_url":"https://api.github.com/users/andreaTP/orgs","repos_url":"https://api.github.com/users/andreaTP/repos","events_url":"https://api.github.com/users/andreaTP/events{/privacy}","received_events_url":"https://api.github.com/users/andreaTP/received_events","type":"User","site_admin":false},"body":"This is an implementation of ConcurrentHashMap in java.util.concurrent.\r\nTo keep it working nicely I had to stub a bit of the java.util.Collection related interfaces, please consider them just a stub to let scala.collection.JavaConversions works, I will ask for some discussion and/or review about the actual implementation.\r\n\r\nAnother issue is about the keySet method, unfortunately, the signature of this method changed in Java 8, I wait for suggestions on how to manage that.","created_at":"2015-05-05T11:55:06Z","updated_at":"2015-05-07T08:29:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"95c0f649af847aaf5d278459f255e20c935301ec","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/scala-js/scala-js/pulls/1636/commits","review_comments_url":"https://api.github.com/repos/scala-js/scala-js/pulls/1636/comments","review_comment_url":"https://api.github.com/repos/scala-js/scala-js/pulls/comments{/number}","comments_url":"https://api.github.com/repos/scala-js/scala-js/issues/1636/comments","statuses_url":"https://api.github.com/repos/scala-js/scala-js/statuses/f554bd615373e649bb0bb9c99b05d179e59f74ce","head":{"label":"andreaTP:master","ref":"master","sha":"f554bd615373e649bb0bb9c99b05d179e59f74ce","user":{"login":"andreaTP","id":5792097,"avatar_url":"https://avatars.githubusercontent.com/u/5792097?v=3","gravatar_id":"","url":"https://api.github.com/users/andreaTP","html_url":"https://github.com/andreaTP","followers_url":"https://api.github.com/users/andreaTP/followers","following_url":"https://api.github.com/users/andreaTP/following{/other_user}","gists_url":"https://api.github.com/users/andreaTP/gists{/gist_id}","starred_url":"https://api.github.com/users/andreaTP/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreaTP/subscriptions","organizations_url":"https://api.github.com/users/andreaTP/orgs","repos_url":"https://api.github.com/users/andreaTP/repos","events_url":"https://api.github.com/users/andreaTP/events{/privacy}","received_events_url":"https://api.github.com/users/andreaTP/received_events","type":"User","site_admin":false},"repo":{"id":34802802,"name":"scala-js","full_name":"andreaTP/scala-js","owner":{"login":"andreaTP","id":5792097,"avatar_url":"https://avatars.githubusercontent.com/u/5792097?v=3","gravatar_id":"","url":"https://api.github.com/users/andreaTP","html_url":"https://github.com/andreaTP","followers_url":"https://api.github.com/users/andreaTP/followers","following_url":"https://api.github.com/users/andreaTP/following{/other_user}","gists_url":"https://api.github.com/users/andreaTP/gists{/gist_id}","starred_url":"https://api.github.com/users/andreaTP/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreaTP/subscriptions","organizations_url":"https://api.github.com/users/andreaTP/orgs","repos_url":"https://api.github.com/users/andreaTP/repos","events_url":"https://api.github.com/users/andreaTP/events{/privacy}","received_events_url":"https://api.github.com/users/andreaTP/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/andreaTP/scala-js","description":"Scala.js, the Scala to JavaScript compiler","fork":true,"url":"https://api.github.com/repos/andreaTP/scala-js","forks_url":"https://api.github.com/repos/andreaTP/scala-js/forks","keys_url":"https://api.github.com/repos/andreaTP/scala-js/keys{/key_id}","collaborators_url":"https://api.github.com/repos/andreaTP/scala-js/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/andreaTP/scala-js/teams","hooks_url":"https://api.github.com/repos/andreaTP/scala-js/hooks","issue_events_url":"https://api.github.com/repos/andreaTP/scala-js/issues/events{/number}","events_url":"https://api.github.com/repos/andreaTP/scala-js/events","assignees_url":"https://api.github.com/repos/andreaTP/scala-js/assignees{/user}","branches_url":"https://api.github.com/repos/andreaTP/scala-js/branches{/branch}","tags_url":"https://api.github.com/repos/andreaTP/scala-js/tags","blobs_url":"https://api.github.com/repos/andreaTP/scala-js/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/andreaTP/scala-js/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/andreaTP/scala-js/git/refs{/sha}","trees_url":"https://api.github.com/repos/andreaTP/scala-js/git/trees{/sha}","statuses_url":"https://api.github.com/repos/andreaTP/scala-js/statuses/{sha}","languages_url":"https://api.github.com/repos/andreaTP/scala-js/languages","stargazers_url":"https://api.github.com/repos/andreaTP/scala-js/stargazers","contributors_url":"https://api.github.com/repos/andreaTP/scala-js/contributors","subscribers_url":"https://api.github.com/repos/andreaTP/scala-js/subscribers","subscription_url":"https://api.github.com/repos/andreaTP/scala-js/subscription","commits_url":"https://api.github.com/repos/andreaTP/scala-js/commits{/sha}","git_commits_url":"https://api.github.com/repos/andreaTP/scala-js/git/commits{/sha}","comments_url":"https://api.github.com/repos/andreaTP/scala-js/comments{/number}","issue_comment_url":"https://api.github.com/repos/andreaTP/scala-js/issues/comments{/number}","contents_url":"https://api.github.com/repos/andreaTP/scala-js/contents/{+path}","compare_url":"https://api.github.com/repos/andreaTP/scala-js/compare/{base}...{head}","merges_url":"https://api.github.com/repos/andreaTP/scala-js/merges","archive_url":"https://api.github.com/repos/andreaTP/scala-js/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/andreaTP/scala-js/downloads","issues_url":"https://api.github.com/repos/andreaTP/scala-js/issues{/number}","pulls_url":"https://api.github.com/repos/andreaTP/scala-js/pulls{/number}","milestones_url":"https://api.github.com/repos/andreaTP/scala-js/milestones{/number}","notifications_url":"https://api.github.com/repos/andreaTP/scala-js/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/andreaTP/scala-js/labels{/name}","releases_url":"https://api.github.com/repos/andreaTP/scala-js/releases{/id}","created_at":"2015-04-29T15:44:28Z","updated_at":"2015-05-06T08:45:37Z","pushed_at":"2015-05-06T08:52:24Z","git_url":"git://github.com/andreaTP/scala-js.git","ssh_url":"git@github.com:andreaTP/scala-js.git","clone_url":"https://github.com/andreaTP/scala-js.git","svn_url":"https://github.com/andreaTP/scala-js","homepage":"http://www.scala-js.org/","size":7925,"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":"scala-js:master","ref":"master","sha":"6dbab2c3ebb665efe0c1eee2af33202d6edc42e2","user":{"login":"scala-js","id":6039724,"avatar_url":"https://avatars.githubusercontent.com/u/6039724?v=3","gravatar_id":"","url":"https://api.github.com/users/scala-js","html_url":"https://github.com/scala-js","followers_url":"https://api.github.com/users/scala-js/followers","following_url":"https://api.github.com/users/scala-js/following{/other_user}","gists_url":"https://api.github.com/users/scala-js/gists{/gist_id}","starred_url":"https://api.github.com/users/scala-js/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scala-js/subscriptions","organizations_url":"https://api.github.com/users/scala-js/orgs","repos_url":"https://api.github.com/users/scala-js/repos","events_url":"https://api.github.com/users/scala-js/events{/privacy}","received_events_url":"https://api.github.com/users/scala-js/received_events","type":"Organization","site_admin":false},"repo":{"id":8272315,"name":"scala-js","full_name":"scala-js/scala-js","owner":{"login":"scala-js","id":6039724,"avatar_url":"https://avatars.githubusercontent.com/u/6039724?v=3","gravatar_id":"","url":"https://api.github.com/users/scala-js","html_url":"https://github.com/scala-js","followers_url":"https://api.github.com/users/scala-js/followers","following_url":"https://api.github.com/users/scala-js/following{/other_user}","gists_url":"https://api.github.com/users/scala-js/gists{/gist_id}","starred_url":"https://api.github.com/users/scala-js/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scala-js/subscriptions","organizations_url":"https://api.github.com/users/scala-js/orgs","repos_url":"https://api.github.com/users/scala-js/repos","events_url":"https://api.github.com/users/scala-js/events{/privacy}","received_events_url":"https://api.github.com/users/scala-js/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scala-js/scala-js","description":"Scala.js, the Scala to JavaScript compiler","fork":false,"url":"https://api.github.com/repos/scala-js/scala-js","forks_url":"https://api.github.com/repos/scala-js/scala-js/forks","keys_url":"https://api.github.com/repos/scala-js/scala-js/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scala-js/scala-js/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scala-js/scala-js/teams","hooks_url":"https://api.github.com/repos/scala-js/scala-js/hooks","issue_events_url":"https://api.github.com/repos/scala-js/scala-js/issues/events{/number}","events_url":"https://api.github.com/repos/scala-js/scala-js/events","assignees_url":"https://api.github.com/repos/scala-js/scala-js/assignees{/user}","branches_url":"https://api.github.com/repos/scala-js/scala-js/branches{/branch}","tags_url":"https://api.github.com/repos/scala-js/scala-js/tags","blobs_url":"https://api.github.com/repos/scala-js/scala-js/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scala-js/scala-js/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scala-js/scala-js/git/refs{/sha}","trees_url":"https://api.github.com/repos/scala-js/scala-js/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scala-js/scala-js/statuses/{sha}","languages_url":"https://api.github.com/repos/scala-js/scala-js/languages","stargazers_url":"https://api.github.com/repos/scala-js/scala-js/stargazers","contributors_url":"https://api.github.com/repos/scala-js/scala-js/contributors","subscribers_url":"https://api.github.com/repos/scala-js/scala-js/subscribers","subscription_url":"https://api.github.com/repos/scala-js/scala-js/subscription","commits_url":"https://api.github.com/repos/scala-js/scala-js/commits{/sha}","git_commits_url":"https://api.github.com/repos/scala-js/scala-js/git/commits{/sha}","comments_url":"https://api.github.com/repos/scala-js/scala-js/comments{/number}","issue_comment_url":"https://api.github.com/repos/scala-js/scala-js/issues/comments{/number}","contents_url":"https://api.github.com/repos/scala-js/scala-js/contents/{+path}","compare_url":"https://api.github.com/repos/scala-js/scala-js/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scala-js/scala-js/merges","archive_url":"https://api.github.com/repos/scala-js/scala-js/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scala-js/scala-js/downloads","issues_url":"https://api.github.com/repos/scala-js/scala-js/issues{/number}","pulls_url":"https://api.github.com/repos/scala-js/scala-js/pulls{/number}","milestones_url":"https://api.github.com/repos/scala-js/scala-js/milestones{/number}","notifications_url":"https://api.github.com/repos/scala-js/scala-js/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scala-js/scala-js/labels{/name}","releases_url":"https://api.github.com/repos/scala-js/scala-js/releases{/id}","created_at":"2013-02-18T16:33:55Z","updated_at":"2015-05-07T00:54:36Z","pushed_at":"2015-05-06T16:34:02Z","git_url":"git://github.com/scala-js/scala-js.git","ssh_url":"git@github.com:scala-js/scala-js.git","clone_url":"https://github.com/scala-js/scala-js.git","svn_url":"https://github.com/scala-js/scala-js","homepage":"http://www.scala-js.org/","size":16103,"stargazers_count":1651,"watchers_count":1651,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":137,"mirror_url":null,"open_issues_count":48,"forks":137,"open_issues":48,"watchers":1651,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/scala-js/scala-js/pulls/1636"},"html":{"href":"https://github.com/scala-js/scala-js/pull/1636"},"issue":{"href":"https://api.github.com/repos/scala-js/scala-js/issues/1636"},"comments":{"href":"https://api.github.com/repos/scala-js/scala-js/issues/1636/comments"},"review_comments":{"href":"https://api.github.com/repos/scala-js/scala-js/pulls/1636/comments"},"review_comment":{"href":"https://api.github.com/repos/scala-js/scala-js/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/scala-js/scala-js/pulls/1636/commits"},"statuses":{"href":"https://api.github.com/repos/scala-js/scala-js/statuses/f554bd615373e649bb0bb9c99b05d179e59f74ce"}}}}