{"action":"created","comment":{"url":"https://api.github.com/repos/amplab/tachyon/pulls/comments/34276195","id":34276195,"diff_hunk":"@@ -0,0 +1,197 @@\n+/*\n+ * Licensed to the University of California, Berkeley under one or more contributor license\n+ * agreements. See the NOTICE file distributed with this work for additional information regarding\n+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the\n+ * \"License\"); you may not use this file except in compliance with the License. You may obtain a\n+ * 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 distributed under the License\n+ * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n+ * or implied. See the License for the specific language governing permissions and limitations under\n+ * the License.\n+ */\n+\n+package tachyon.worker.block.evictor;\n+\n+import java.io.File;\n+import java.io.IOException;\n+import java.util.ArrayList;\n+import java.util.Collection;\n+import java.util.List;\n+\n+import org.junit.Assert;\n+import org.junit.Before;\n+import org.junit.Rule;\n+import org.junit.Test;\n+import org.junit.rules.TemporaryFolder;\n+import org.junit.runner.RunWith;\n+import org.junit.runners.Parameterized;\n+\n+import tachyon.worker.block.BlockMetadataManager;\n+import tachyon.worker.block.BlockStoreLocation;\n+import tachyon.worker.block.meta.StorageDir;\n+import tachyon.worker.block.meta.StorageTier;\n+\n+/**\n+ * This is a parameterized unit test for all types of {@link Evictor} defined in {@link EvictorType}\n+ *\n+ * It tests general evictor behavior like not evicting any space when space request is already\n+ * available, evicting enough space when eviction is needed, having a null eviction plan when the\n+ * requested space can not be satisfied anyway and so on.\n+ *\n+ * Behavior for a specific type of evictor will be tested in other classes, e.x. tests to ensure\n+ * that blocks evicted by LRUEvictor are in the right order should be in LRUEvictorTest.\n+ */\n+@RunWith(Parameterized.class)\n+public class EvictorTest {\n+  private static final int USER_ID = 2;\n+  private static final long BLOCK_ID = 10;\n+  private static final int TEST_TIER = 0;\n+  private static final int TEST_DIR = 0;\n+\n+  private StorageDir mTestDir;\n+  private BlockMetadataManager mMetaManager;\n+  private EvictorType mEvictorType;\n+  private Evictor mEvictor;\n+\n+  @Parameterized.Parameters\n+  public static Collection<Object[]> data() {\n+    // Run this test against all types of Evictors\n+    List<Object[]> list = new ArrayList<Object[]>();\n+    for (EvictorType type : EvictorType.values()) {\n+      if (type != EvictorType.DEFAULT) {\n+        list.add(new Object[] {type});\n+      }\n+    }\n+    return list;\n+  }\n+\n+  public EvictorTest(EvictorType evictorType) {\n+    mEvictorType = evictorType;\n+  }\n+\n+  @Rule\n+  public TemporaryFolder mTestFolder = new TemporaryFolder();\n+\n+  @Before\n+  public final void before() throws IOException {\n+    File tempFolder = mTestFolder.newFolder();\n+    mMetaManager = EvictorTestUtils.defaultMetadataManager(tempFolder.getAbsolutePath());\n+    List<StorageTier> tiers = mMetaManager.getTiers();\n+    mTestDir = tiers.get(TEST_TIER).getDir(TEST_DIR);\n+    mEvictor = EvictorFactory.create(mEvictorType, mMetaManager);\n+  }\n+\n+  @Test\n+  public void noNeedToEvictTest1() throws IOException {\n+    // metadata manager is just created, no cached block in Evictor, so when trying to make sure\n+    // each dir has free space of its capacity, the eviction plan should be empty.\n+    for (StorageTier tier : mMetaManager.getTiers()) {\n+      for (StorageDir dir : tier.getStorageDirs()) {\n+        Assert.assertTrue(mEvictor.freeSpace(dir.getCapacityBytes(), dir.toBlockStoreLocation())\n+            .isEmpty());\n+      }\n+    }\n+  }\n+\n+  @Test\n+  public void noNeedToEvictTest2() throws IOException {\n+    // cache some data in a dir, then request the remaining space from the dir, the eviction plan\n+    // should be empty.\n+    StorageDir dir = mTestDir;\n+    long capacity = dir.getCapacityBytes();\n+    long cachedBytes = capacity / 2 + 1;\n+    EvictorTestUtils.cache(USER_ID, BLOCK_ID, cachedBytes, dir, mMetaManager, mEvictor);\n+    Assert.assertTrue(mEvictor.freeSpace(capacity - cachedBytes, dir.toBlockStoreLocation())\n+        .isEmpty());\n+  }\n+\n+  @Test\n+  public void noNeedToEvictTest3() throws IOException {\n+    // fill in all dirs except for one directory, then request the capacity of\n+    // the directory with anyDirInTier\n+    StorageDir dirLeft = mTestDir;\n+    long blockId = BLOCK_ID; // start from BLOCK_ID\n+    for (StorageTier tier : mMetaManager.getTiers()) {\n+      for (StorageDir dir : tier.getStorageDirs()) {\n+        if (dir != dirLeft) {\n+          EvictorTestUtils.cache(USER_ID, blockId, dir.getCapacityBytes(), dir, mMetaManager,\n+              mEvictor);\n+          blockId ++;\n+        }\n+      }\n+    }\n+    Assert.assertTrue(mEvictor.freeSpace(dirLeft.getCapacityBytes(),\n+        BlockStoreLocation.anyDirInTier(dirLeft.getParentTier().getTierAlias())).isEmpty());\n+  }\n+\n+  @Test\n+  public void needToEvictTest() throws IOException {\n+    // fill in a dir and request the capacity of the dir, all cached data in the dir should be\n+    // evicted.\n+    StorageDir dir = mTestDir;\n+    long capacityBytes = dir.getCapacityBytes();\n+    EvictorTestUtils.cache(USER_ID, BLOCK_ID, capacityBytes, dir, mMetaManager, mEvictor);\n+\n+    EvictionPlan plan = mEvictor.freeSpace(capacityBytes, dir.toBlockStoreLocation());\n+    EvictorTestUtils.assertLegalPlan(capacityBytes, plan, mMetaManager);\n+  }\n+\n+  @Test\n+  public void needToEvictAnyDirInTierTest() throws IOException {\n+    // cache data with size of \"(capacity - 1)\" in each dir in a tier, request size of \"capacity\" of\n+    // the last dir(whose capacity is largest) in this tier from anyDirInTier(tier), all blocks\n+    // cached in the last dir should be in the eviction plan.\n+    StorageTier tier = mMetaManager.getTiers().get(0);\n+    long blockId = BLOCK_ID;\n+    List<StorageDir> dirs = tier.getStorageDirs();\n+    for (StorageDir dir : dirs) {\n+      EvictorTestUtils.cache(USER_ID, blockId, dir.getCapacityBytes() - 1, dir, mMetaManager,\n+          mEvictor);\n+      blockId ++;\n+    }\n+\n+    long requestBytes = dirs.get(dirs.size() - 1).getCapacityBytes();\n+    EvictionPlan plan =\n+        mEvictor.freeSpace(requestBytes, BlockStoreLocation.anyDirInTier(tier.getTierAlias()));\n+    EvictorTestUtils.assertLegalPlan(requestBytes, plan, mMetaManager);\n+  }\n+\n+  @Test\n+  public void needToEvictAnyTierTest() throws IOException {\n+    // cache data with size of \"(capacity - 1)\" in each dir in all tiers, request size of minimum\n+    // \"capacity\" of all dirs from anyTier\n+    long minCapacity = Long.MAX_VALUE;\n+    long blockId = BLOCK_ID;\n+    for (StorageTier tier : mMetaManager.getTiers()) {\n+      for (StorageDir dir : tier.getStorageDirs()) {\n+        long capacity = dir.getCapacityBytes();\n+        minCapacity = Math.min(minCapacity, capacity);\n+        EvictorTestUtils.cache(USER_ID, blockId, capacity - 1, dir, mMetaManager, mEvictor);\n+        blockId ++;\n+      }\n+    }\n+\n+    EvictionPlan plan = mEvictor.freeSpace(minCapacity, BlockStoreLocation.anyTier());\n+    EvictorTestUtils.assertLegalPlan(minCapacity, plan, mMetaManager);\n+  }\n+\n+  @Test\n+  public void requestSpaceLargerThanCapacityTest() throws IOException {\n+    // cache data in a dir\n+    long totalCapacity = mMetaManager.getAvailableBytes(BlockStoreLocation.anyTier());\n+    StorageDir dir = mTestDir;\n+    BlockStoreLocation dirLocation = dir.toBlockStoreLocation();\n+    long dirCapacity = mMetaManager.getAvailableBytes(dirLocation);\n+\n+    EvictorTestUtils.cache(USER_ID, BLOCK_ID, dirCapacity, dir, mMetaManager, mEvictor);\n+\n+    // request space larger than total capacity, no eviction plan should be available\n+    Assert.assertNull(mEvictor.freeSpace(totalCapacity + 1, BlockStoreLocation.anyTier()));\n+    // request space larger than capacity for the random directory, no eviction plan should be","path":"servers/src/test/java/tachyon/worker/block/evictor/EvictorTest.java","position":193,"original_position":193,"commit_id":"b4887102b748261f2583fe36a082a8445642e97c","original_commit_id":"b4887102b748261f2583fe36a082a8445642e97c","user":{"login":"apc999","id":1413748,"avatar_url":"https://avatars.githubusercontent.com/u/1413748?v=3","gravatar_id":"","url":"https://api.github.com/users/apc999","html_url":"https://github.com/apc999","followers_url":"https://api.github.com/users/apc999/followers","following_url":"https://api.github.com/users/apc999/following{/other_user}","gists_url":"https://api.github.com/users/apc999/gists{/gist_id}","starred_url":"https://api.github.com/users/apc999/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apc999/subscriptions","organizations_url":"https://api.github.com/users/apc999/orgs","repos_url":"https://api.github.com/users/apc999/repos","events_url":"https://api.github.com/users/apc999/events{/privacy}","received_events_url":"https://api.github.com/users/apc999/received_events","type":"User","site_admin":false},"body":"not random any more :)","created_at":"2015-07-09T16:49:32Z","updated_at":"2015-07-09T16:49:32Z","html_url":"https://github.com/amplab/tachyon/pull/1042#discussion_r34276195","pull_request_url":"https://api.github.com/repos/amplab/tachyon/pulls/1042","_links":{"self":{"href":"https://api.github.com/repos/amplab/tachyon/pulls/comments/34276195"},"html":{"href":"https://github.com/amplab/tachyon/pull/1042#discussion_r34276195"},"pull_request":{"href":"https://api.github.com/repos/amplab/tachyon/pulls/1042"}}},"pull_request":{"url":"https://api.github.com/repos/amplab/tachyon/pulls/1042","id":39238403,"html_url":"https://github.com/amplab/tachyon/pull/1042","diff_url":"https://github.com/amplab/tachyon/pull/1042.diff","patch_url":"https://github.com/amplab/tachyon/pull/1042.patch","issue_url":"https://api.github.com/repos/amplab/tachyon/issues/1042","number":1042,"state":"open","locked":false,"title":"[TACHYON-542] Evictor Test Framework","user":{"login":"uronce-cc","id":3663941,"avatar_url":"https://avatars.githubusercontent.com/u/3663941?v=3","gravatar_id":"","url":"https://api.github.com/users/uronce-cc","html_url":"https://github.com/uronce-cc","followers_url":"https://api.github.com/users/uronce-cc/followers","following_url":"https://api.github.com/users/uronce-cc/following{/other_user}","gists_url":"https://api.github.com/users/uronce-cc/gists{/gist_id}","starred_url":"https://api.github.com/users/uronce-cc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uronce-cc/subscriptions","organizations_url":"https://api.github.com/users/uronce-cc/orgs","repos_url":"https://api.github.com/users/uronce-cc/repos","events_url":"https://api.github.com/users/uronce-cc/events{/privacy}","received_events_url":"https://api.github.com/users/uronce-cc/received_events","type":"User","site_admin":false},"body":"reopen https://github.com/amplab/tachyon/pull/1033 to master branch. ","created_at":"2015-07-06T06:11:12Z","updated_at":"2015-07-09T16:49:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"995fdf43fc5e34cd2131ce020daee7576b1a453e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/amplab/tachyon/pulls/1042/commits","review_comments_url":"https://api.github.com/repos/amplab/tachyon/pulls/1042/comments","review_comment_url":"https://api.github.com/repos/amplab/tachyon/pulls/comments{/number}","comments_url":"https://api.github.com/repos/amplab/tachyon/issues/1042/comments","statuses_url":"https://api.github.com/repos/amplab/tachyon/statuses/b4887102b748261f2583fe36a082a8445642e97c","head":{"label":"uronce-cc:rebased_worker_wip_evictor_test","ref":"rebased_worker_wip_evictor_test","sha":"b4887102b748261f2583fe36a082a8445642e97c","user":{"login":"uronce-cc","id":3663941,"avatar_url":"https://avatars.githubusercontent.com/u/3663941?v=3","gravatar_id":"","url":"https://api.github.com/users/uronce-cc","html_url":"https://github.com/uronce-cc","followers_url":"https://api.github.com/users/uronce-cc/followers","following_url":"https://api.github.com/users/uronce-cc/following{/other_user}","gists_url":"https://api.github.com/users/uronce-cc/gists{/gist_id}","starred_url":"https://api.github.com/users/uronce-cc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uronce-cc/subscriptions","organizations_url":"https://api.github.com/users/uronce-cc/orgs","repos_url":"https://api.github.com/users/uronce-cc/repos","events_url":"https://api.github.com/users/uronce-cc/events{/privacy}","received_events_url":"https://api.github.com/users/uronce-cc/received_events","type":"User","site_admin":false},"repo":{"id":21723448,"name":"tachyon","full_name":"uronce-cc/tachyon","owner":{"login":"uronce-cc","id":3663941,"avatar_url":"https://avatars.githubusercontent.com/u/3663941?v=3","gravatar_id":"","url":"https://api.github.com/users/uronce-cc","html_url":"https://github.com/uronce-cc","followers_url":"https://api.github.com/users/uronce-cc/followers","following_url":"https://api.github.com/users/uronce-cc/following{/other_user}","gists_url":"https://api.github.com/users/uronce-cc/gists{/gist_id}","starred_url":"https://api.github.com/users/uronce-cc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uronce-cc/subscriptions","organizations_url":"https://api.github.com/users/uronce-cc/orgs","repos_url":"https://api.github.com/users/uronce-cc/repos","events_url":"https://api.github.com/users/uronce-cc/events{/privacy}","received_events_url":"https://api.github.com/users/uronce-cc/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/uronce-cc/tachyon","description":"Memory-centric Storage System for Big Data Analytics","fork":true,"url":"https://api.github.com/repos/uronce-cc/tachyon","forks_url":"https://api.github.com/repos/uronce-cc/tachyon/forks","keys_url":"https://api.github.com/repos/uronce-cc/tachyon/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uronce-cc/tachyon/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uronce-cc/tachyon/teams","hooks_url":"https://api.github.com/repos/uronce-cc/tachyon/hooks","issue_events_url":"https://api.github.com/repos/uronce-cc/tachyon/issues/events{/number}","events_url":"https://api.github.com/repos/uronce-cc/tachyon/events","assignees_url":"https://api.github.com/repos/uronce-cc/tachyon/assignees{/user}","branches_url":"https://api.github.com/repos/uronce-cc/tachyon/branches{/branch}","tags_url":"https://api.github.com/repos/uronce-cc/tachyon/tags","blobs_url":"https://api.github.com/repos/uronce-cc/tachyon/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uronce-cc/tachyon/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uronce-cc/tachyon/git/refs{/sha}","trees_url":"https://api.github.com/repos/uronce-cc/tachyon/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uronce-cc/tachyon/statuses/{sha}","languages_url":"https://api.github.com/repos/uronce-cc/tachyon/languages","stargazers_url":"https://api.github.com/repos/uronce-cc/tachyon/stargazers","contributors_url":"https://api.github.com/repos/uronce-cc/tachyon/contributors","subscribers_url":"https://api.github.com/repos/uronce-cc/tachyon/subscribers","subscription_url":"https://api.github.com/repos/uronce-cc/tachyon/subscription","commits_url":"https://api.github.com/repos/uronce-cc/tachyon/commits{/sha}","git_commits_url":"https://api.github.com/repos/uronce-cc/tachyon/git/commits{/sha}","comments_url":"https://api.github.com/repos/uronce-cc/tachyon/comments{/number}","issue_comment_url":"https://api.github.com/repos/uronce-cc/tachyon/issues/comments{/number}","contents_url":"https://api.github.com/repos/uronce-cc/tachyon/contents/{+path}","compare_url":"https://api.github.com/repos/uronce-cc/tachyon/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uronce-cc/tachyon/merges","archive_url":"https://api.github.com/repos/uronce-cc/tachyon/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uronce-cc/tachyon/downloads","issues_url":"https://api.github.com/repos/uronce-cc/tachyon/issues{/number}","pulls_url":"https://api.github.com/repos/uronce-cc/tachyon/pulls{/number}","milestones_url":"https://api.github.com/repos/uronce-cc/tachyon/milestones{/number}","notifications_url":"https://api.github.com/repos/uronce-cc/tachyon/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uronce-cc/tachyon/labels{/name}","releases_url":"https://api.github.com/repos/uronce-cc/tachyon/releases{/id}","created_at":"2014-07-11T05:40:12Z","updated_at":"2015-03-24T23:33:22Z","pushed_at":"2015-07-09T15:39:17Z","git_url":"git://github.com/uronce-cc/tachyon.git","ssh_url":"git@github.com:uronce-cc/tachyon.git","clone_url":"https://github.com/uronce-cc/tachyon.git","svn_url":"https://github.com/uronce-cc/tachyon","homepage":"http://tachyon-project.org","size":15272,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"amplab:master","ref":"master","sha":"821f1573b2839bb87e77c316f12b606986b3c80f","user":{"login":"amplab","id":1438454,"avatar_url":"https://avatars.githubusercontent.com/u/1438454?v=3","gravatar_id":"","url":"https://api.github.com/users/amplab","html_url":"https://github.com/amplab","followers_url":"https://api.github.com/users/amplab/followers","following_url":"https://api.github.com/users/amplab/following{/other_user}","gists_url":"https://api.github.com/users/amplab/gists{/gist_id}","starred_url":"https://api.github.com/users/amplab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amplab/subscriptions","organizations_url":"https://api.github.com/users/amplab/orgs","repos_url":"https://api.github.com/users/amplab/repos","events_url":"https://api.github.com/users/amplab/events{/privacy}","received_events_url":"https://api.github.com/users/amplab/received_events","type":"Organization","site_admin":false},"repo":{"id":7276954,"name":"tachyon","full_name":"amplab/tachyon","owner":{"login":"amplab","id":1438454,"avatar_url":"https://avatars.githubusercontent.com/u/1438454?v=3","gravatar_id":"","url":"https://api.github.com/users/amplab","html_url":"https://github.com/amplab","followers_url":"https://api.github.com/users/amplab/followers","following_url":"https://api.github.com/users/amplab/following{/other_user}","gists_url":"https://api.github.com/users/amplab/gists{/gist_id}","starred_url":"https://api.github.com/users/amplab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amplab/subscriptions","organizations_url":"https://api.github.com/users/amplab/orgs","repos_url":"https://api.github.com/users/amplab/repos","events_url":"https://api.github.com/users/amplab/events{/privacy}","received_events_url":"https://api.github.com/users/amplab/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/amplab/tachyon","description":" A Reliable Memory Centric Distributed Storage System","fork":false,"url":"https://api.github.com/repos/amplab/tachyon","forks_url":"https://api.github.com/repos/amplab/tachyon/forks","keys_url":"https://api.github.com/repos/amplab/tachyon/keys{/key_id}","collaborators_url":"https://api.github.com/repos/amplab/tachyon/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/amplab/tachyon/teams","hooks_url":"https://api.github.com/repos/amplab/tachyon/hooks","issue_events_url":"https://api.github.com/repos/amplab/tachyon/issues/events{/number}","events_url":"https://api.github.com/repos/amplab/tachyon/events","assignees_url":"https://api.github.com/repos/amplab/tachyon/assignees{/user}","branches_url":"https://api.github.com/repos/amplab/tachyon/branches{/branch}","tags_url":"https://api.github.com/repos/amplab/tachyon/tags","blobs_url":"https://api.github.com/repos/amplab/tachyon/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/amplab/tachyon/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/amplab/tachyon/git/refs{/sha}","trees_url":"https://api.github.com/repos/amplab/tachyon/git/trees{/sha}","statuses_url":"https://api.github.com/repos/amplab/tachyon/statuses/{sha}","languages_url":"https://api.github.com/repos/amplab/tachyon/languages","stargazers_url":"https://api.github.com/repos/amplab/tachyon/stargazers","contributors_url":"https://api.github.com/repos/amplab/tachyon/contributors","subscribers_url":"https://api.github.com/repos/amplab/tachyon/subscribers","subscription_url":"https://api.github.com/repos/amplab/tachyon/subscription","commits_url":"https://api.github.com/repos/amplab/tachyon/commits{/sha}","git_commits_url":"https://api.github.com/repos/amplab/tachyon/git/commits{/sha}","comments_url":"https://api.github.com/repos/amplab/tachyon/comments{/number}","issue_comment_url":"https://api.github.com/repos/amplab/tachyon/issues/comments{/number}","contents_url":"https://api.github.com/repos/amplab/tachyon/contents/{+path}","compare_url":"https://api.github.com/repos/amplab/tachyon/compare/{base}...{head}","merges_url":"https://api.github.com/repos/amplab/tachyon/merges","archive_url":"https://api.github.com/repos/amplab/tachyon/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/amplab/tachyon/downloads","issues_url":"https://api.github.com/repos/amplab/tachyon/issues{/number}","pulls_url":"https://api.github.com/repos/amplab/tachyon/pulls{/number}","milestones_url":"https://api.github.com/repos/amplab/tachyon/milestones{/number}","notifications_url":"https://api.github.com/repos/amplab/tachyon/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/amplab/tachyon/labels{/name}","releases_url":"https://api.github.com/repos/amplab/tachyon/releases{/id}","created_at":"2012-12-21T17:43:46Z","updated_at":"2015-07-09T07:32:06Z","pushed_at":"2015-07-09T16:12:45Z","git_url":"git://github.com/amplab/tachyon.git","ssh_url":"git@github.com:amplab/tachyon.git","clone_url":"https://github.com/amplab/tachyon.git","svn_url":"https://github.com/amplab/tachyon","homepage":"http://tachyon-project.org","size":34878,"stargazers_count":1471,"watchers_count":1471,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":546,"mirror_url":null,"open_issues_count":26,"forks":546,"open_issues":26,"watchers":1471,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/amplab/tachyon/pulls/1042"},"html":{"href":"https://github.com/amplab/tachyon/pull/1042"},"issue":{"href":"https://api.github.com/repos/amplab/tachyon/issues/1042"},"comments":{"href":"https://api.github.com/repos/amplab/tachyon/issues/1042/comments"},"review_comments":{"href":"https://api.github.com/repos/amplab/tachyon/pulls/1042/comments"},"review_comment":{"href":"https://api.github.com/repos/amplab/tachyon/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/amplab/tachyon/pulls/1042/commits"},"statuses":{"href":"https://api.github.com/repos/amplab/tachyon/statuses/b4887102b748261f2583fe36a082a8445642e97c"}}}}