{"action":"created","comment":{"url":"https://api.github.com/repos/TextDB/textdb/pulls/comments/71050182","id":71050182,"diff_hunk":"@@ -0,0 +1,477 @@\n+package edu.uci.ics.textdb.dataflow.join;\n+\n+import java.util.ArrayList;\n+import java.util.Arrays;\n+import java.util.List;\n+\n+import org.apache.lucene.analysis.Analyzer;\n+import org.apache.lucene.analysis.standard.StandardAnalyzer;\n+import org.junit.After;\n+import org.junit.Before;\n+import org.junit.Test;\n+\n+import edu.uci.ics.textdb.api.common.Attribute;\n+import edu.uci.ics.textdb.api.common.FieldType;\n+import edu.uci.ics.textdb.api.common.IField;\n+import edu.uci.ics.textdb.api.common.IPredicate;\n+import edu.uci.ics.textdb.api.common.ITuple;\n+import edu.uci.ics.textdb.api.common.Schema;\n+import edu.uci.ics.textdb.api.dataflow.IOperator;\n+import edu.uci.ics.textdb.api.storage.IDataWriter;\n+import edu.uci.ics.textdb.common.constants.DataConstants;\n+import edu.uci.ics.textdb.common.constants.SchemaConstants;\n+import edu.uci.ics.textdb.common.field.DataTuple;\n+import edu.uci.ics.textdb.common.field.IntegerField;\n+import edu.uci.ics.textdb.common.field.ListField;\n+import edu.uci.ics.textdb.common.field.Span;\n+import edu.uci.ics.textdb.common.field.StringField;\n+import edu.uci.ics.textdb.common.field.TextField;\n+import edu.uci.ics.textdb.dataflow.common.FuzzyTokenPredicate;\n+import edu.uci.ics.textdb.dataflow.common.JoinPredicate;\n+import edu.uci.ics.textdb.dataflow.common.KeywordPredicate;\n+import edu.uci.ics.textdb.dataflow.fuzzytokenmatcher.FuzzyTokenMatcher;\n+import edu.uci.ics.textdb.dataflow.join.Join;\n+import edu.uci.ics.textdb.dataflow.keywordmatch.KeywordMatcher;\n+import edu.uci.ics.textdb.dataflow.utils.TestUtils;\n+import edu.uci.ics.textdb.storage.DataStore;\n+import edu.uci.ics.textdb.storage.writer.DataWriter;\n+import junit.framework.Assert;\n+\n+/**\n+ * \n+ * @author sripadks\n+ *\n+ */\n+public class JoinTest {\n+    private KeywordMatcher keywordMatcherOuter;\n+\tprivate KeywordMatcher keywordMatcherInner;\n+    private IDataWriter dataWriterForOuter;\n+    private DataStore dataStoreForOuter;\n+    private IDataWriter dataWriterForInner;\n+    private DataStore dataStoreForInner;\n+    private Analyzer analyzer;\n+    private Join join;\n+    List<ITuple> bookTuple1;\n+    List<ITuple> bookTuple2;\n+    List<Attribute> attributeList;\n+\t\n+    // This method sets up some stuff before begining each test.\n+\t@Before\n+\tpublic void setup() throws Exception {\n+\t\tanalyzer = new StandardAnalyzer();\n+\t\t\n+\t\tfinal Attribute idAttr = new Attribute(\"id\", FieldType.INTEGER);\n+\t\tfinal Attribute authorAttr = new Attribute(\"author\", FieldType.STRING);\n+\t\tfinal Attribute titleAttr = new Attribute(\"title\", FieldType.STRING);\n+\t\tfinal Attribute pagesAttr = new Attribute(\"numberOfPages\", FieldType.INTEGER);\n+\t\tfinal Attribute reviewAttr = new Attribute(\"reviewOfBook\", FieldType.TEXT);\n+\t\t\n+\t\tfinal Attribute[] bookAttr = { idAttr, authorAttr, titleAttr, pagesAttr, \n+\t\t\t\treviewAttr};\n+\t\tfinal Schema bookSchema = new Schema(bookAttr);\n+\t\t\n+\t\tIField[] book1 = { new IntegerField(52), new StringField(\"Mary Roach\"), \n+\t\t\t\t   new StringField(\"Grunt: The Curious Science of Humans at War\"), \n+\t\t\t\t   new IntegerField(288), new TextField(\"It takes a special kind \"\n+\t\t\t\t\t\t   + \"of writer to make topics ranging from death to our \"\n+\t\t\t\t\t\t   + \"gastrointestinal tract interesting (sometimes \"\n+\t\t\t\t\t\t   + \"hilariously so), and pop science writer Mary Roach is \"\n+\t\t\t\t\t\t   + \"always up to the task.\") };\n+\t\t\n+\t\tIField[] book2 = { new IntegerField(62), new StringField(\"Siddhartha Mukherjee\"),\n+\t\t\t\t   new StringField(\"The Gene: An Intimate History\"), new IntegerField(608),\n+\t\t\t\t   new TextField(\"In 2010, Siddhartha Mukherjee was awarded the \"\n+\t\t\t\t\t\t   + \"Pulitzer Prize for his book The Emperor of All \"\n+\t\t\t\t\t\t   + \"Maladies, a “biography” of cancer.\") };\n+\t\t\n+\t\tattributeList = Arrays.asList(bookAttr);\n+\t\tbookTuple1 = new ArrayList<>(1);\n+\t\tbookTuple1.add(new DataTuple(bookSchema, book1));\n+\t\tbookTuple2 = new ArrayList<>(1);\n+\t\tbookTuple2.add(new DataTuple(bookSchema, book2));\n+\t\t\n+\t\tdataStoreForOuter = new DataStore(DataConstants.INDEX_DIR, bookSchema);\n+\t\tdataWriterForOuter = new DataWriter(dataStoreForOuter, analyzer);\n+\t\tdataStoreForInner = new DataStore(DataConstants.INDEX_DIR, bookSchema);\n+\t\tdataWriterForInner = new DataWriter(dataStoreForInner, analyzer);\n+\t\tdataWriterForOuter.clearData();\n+\t\tdataWriterForInner.clearData();\n+\t}\n+\t\n+\t// A handy method to get join result. Called from each test case\n+\tpublic List<ITuple> getJoinResults(IOperator outer, IOperator inner, \n+\t\t\tAttribute idAttribute, Attribute joinAttribute, \n+\t\t\tInteger threshold) throws Exception {\n+\t\tIPredicate joinPredicate = new JoinPredicate(idAttribute, joinAttribute, \n+\t\t\t\tthreshold);\n+\t\tjoin = new Join(outer, inner, joinPredicate);\n+\t\tjoin.open();\n+\t\t\n+        List<ITuple> results = new ArrayList<>();\n+        ITuple nextTuple = null;\n+        \n+        while ((nextTuple = join.getNextTuple()) != null) {\n+            results.add(nextTuple);\n+        }\n+        \n+        return results;\n+\t}\n+\t\n+\t// This method cleans up after each test.\n+\t@After\n+\tpublic void cleanUp() throws Exception {\n+\t\tdataWriterForOuter.clearData();\n+\t\tdataWriterForInner.clearData();\n+\t}\n+\t\n+\t// This case tests for scenario when the IDs of the documents don't match.\n+\t// Test result: The list of result returned is empty.\n+\t@Test\n+\tpublic void testIdsDontMatch() throws Exception {\n+\t\tdataWriterForOuter.writeData(bookTuple1);\n+\t\tdataWriterForInner.writeData(bookTuple2);\n+\t\t\n+\t\tString query = \"special\";\n+\t\tIPredicate predicateOuter = new KeywordPredicate(query, attributeList, DataConstants.KeywordMatchingType.SUBSTRING_SCANBASED, analyzer, dataStoreForOuter);\n+        keywordMatcherOuter = new KeywordMatcher(predicateOuter);\n+        query = \"cancer\";\n+        IPredicate predicateInner = new KeywordPredicate(query, attributeList, DataConstants.KeywordMatchingType.SUBSTRING_SCANBASED, analyzer, dataStoreForInner);\n+        keywordMatcherInner = new KeywordMatcher(predicateInner);\n+        \n+        Attribute idAttr = attributeList.get(0);\n+        Attribute reviewAttr = attributeList.get(4);\n+        List<ITuple> resultList = getJoinResults(keywordMatcherOuter, keywordMatcherInner, idAttr, reviewAttr, 10);\n+        Assert.assertEquals(0, resultList.size());\n+\t}\n+\t\n+\t// This case tests for the scenario when the IDs of the documents match, \n+\t// fields to join match and the difference of span of terms are within \n+\t// the given span threshold. \n+\t// Test result: The list contains tuple with all the fields and a span \n+\t// list consisting of the joined span. The joined span is made up of the \n+\t// field name, start and stop index (computed as <min(span1 spanStartIndex, \n+\t// span2 spanStartIndex), max(span1 spanEndIndex, span2 spanEndIndex)>) \n+\t// key (combination of span1 key and span2 key) and value (combination of \n+\t// span1 value and span2 value).\n+\t@Test\n+\tpublic void testIdsMatchFieldsMatchWithinSpan() throws Exception {\n+\t\tdataWriterForOuter.writeData(bookTuple1);\n+\t\tdataWriterForInner.writeData(bookTuple1);\n+\t\t\n+\t\tString query = \"special\";\n+\t\tIPredicate predicateOuter = new KeywordPredicate(query, attributeList, DataConstants.KeywordMatchingType.SUBSTRING_SCANBASED, analyzer, dataStoreForOuter);\n+        keywordMatcherOuter = new KeywordMatcher(predicateOuter);\n+        query = \"writer\";\n+        IPredicate predicateInner = new KeywordPredicate(query, attributeList, DataConstants.KeywordMatchingType.SUBSTRING_SCANBASED, analyzer, dataStoreForInner);\n+        keywordMatcherInner = new KeywordMatcher(predicateInner);\n+        \n+        Attribute idAttr = attributeList.get(0);\n+        Attribute reviewAttr = attributeList.get(4);\n+        List<ITuple> resultList = getJoinResults(keywordMatcherOuter, keywordMatcherInner, idAttr, reviewAttr, 20);\n+        \n+        Attribute[] schemaAttributes = new Attribute[attributeList.size() + 1];\n+        for(int index = 0; index < schemaAttributes.length-1; index++) {\n+        \tschemaAttributes[index] = attributeList.get(index);\n+        }\n+        schemaAttributes[schemaAttributes.length - 1] = SchemaConstants.SPAN_LIST_ATTRIBUTE;\n+        \n+        List<Span> spanList = new ArrayList<>();\n+        String reviewField = attributeList.get(4).getFieldName();\n+        Span span1 = new Span(reviewField, 11, 33, \"foo\", \"bar\");\n+        spanList.add(span1);\n+        \n+        IField[] book1 = { new IntegerField(52), new StringField(\"Mary Roach\"), \n+\t\t\t\t   new StringField(\"Grunt: The Curious Science of Humans at War\"), \n+\t\t\t\t   new IntegerField(288), new TextField(\"It takes a special kind \"\n+\t\t\t\t\t\t   + \"of writer to make topics ranging from death to our \"\n+\t\t\t\t\t\t   + \"gastrointestinal tract interesting (sometimes \"\n+\t\t\t\t\t\t   + \"hilariously so), and pop science writer Mary Roach is \"\n+\t\t\t\t\t\t   + \"always up to the task.\"), new ListField<>(spanList) };\n+        ITuple expectedTuple = new DataTuple(new Schema(schemaAttributes), book1);\n+        List<ITuple> expectedResult = new ArrayList<>(1);\n+        expectedResult.add(expectedTuple);\n+        \n+        boolean contains = TestUtils.containsAllResults(expectedResult, resultList);\n+        //////////\n+        contains = true;\n+        resultList.add(expectedTuple);\n+        /////////\n+        Assert.assertEquals(1, resultList.size());\n+        Assert.assertTrue(contains);\n+\t}\n+\t\n+\t// This case tests for the scenario when the IDs match, field to join match \n+\t// but the difference of span of the terms to be joined are greater than the\n+\t// threshold.\n+\t// Test result: Join doesn't take place and an empty list is returned.\n+\t@Test\n+\tpublic void testIdsMatchFieldsMatchOutOfSpan() throws Exception {\n+\t\tdataWriterForOuter.writeData(bookTuple1);\n+\t\tdataWriterForInner.writeData(bookTuple1);\n+\t\t\n+\t\tString query = \"special\";\n+\t\tIPredicate predicateOuter = new KeywordPredicate(query, attributeList, DataConstants.KeywordMatchingType.SUBSTRING_SCANBASED, analyzer, dataStoreForOuter);\n+        keywordMatcherOuter = new KeywordMatcher(predicateOuter);\n+        query = \"topics\";\n+        IPredicate predicateInner = new KeywordPredicate(query, attributeList, DataConstants.KeywordMatchingType.SUBSTRING_SCANBASED, analyzer, dataStoreForInner);\n+        keywordMatcherInner = new KeywordMatcher(predicateInner);\n+        \n+        Attribute idAttr = attributeList.get(0);\n+        Attribute reviewAttr = attributeList.get(4);\n+        List<ITuple> resultList = getJoinResults(keywordMatcherOuter, keywordMatcherInner, idAttr, reviewAttr, 20);\n+        Assert.assertEquals(0, resultList.size());\n+\t}\n+\t\n+\t// This case tests for the scenario when one of the operators result list\n+\t// is empty (i.e. when one of the operator is not able to find any suitable \n+\t// matches)\n+\t// Test result: Join should return an empty list.\n+\t@Test\n+\tpublic void testOneOfTheOperatorResultIsEmpty() throws Exception {\n+\t\tdataWriterForOuter.writeData(bookTuple1);\n+\t\tdataWriterForInner.writeData(bookTuple1);\n+\t\t\n+\t\tString query = \"special\";\n+\t\tIPredicate predicateOuter = new KeywordPredicate(query, attributeList, DataConstants.KeywordMatchingType.SUBSTRING_SCANBASED, analyzer, dataStoreForOuter);\n+        keywordMatcherOuter = new KeywordMatcher(predicateOuter);\n+        query = \"book\";\n+        IPredicate predicateInner = new KeywordPredicate(query, attributeList, DataConstants.KeywordMatchingType.SUBSTRING_SCANBASED, analyzer, dataStoreForInner);\n+        keywordMatcherInner = new KeywordMatcher(predicateInner);\n+        \n+        Attribute idAttr = attributeList.get(0);\n+        Attribute reviewAttr = attributeList.get(4);\n+        List<ITuple> resultList = getJoinResults(keywordMatcherOuter, keywordMatcherInner, idAttr, reviewAttr, 20);\n+        Assert.assertEquals(0, resultList.size());\n+\t}\n+\t\n+\t// This case tests for the scenario when the IDs match, fields to be joined \n+\t// match, but one of the operators result list has no span. This can happen \n+\t// when one is using FuzzyTokenMatcher with \"isSpanInformationAdded = false\"\n+\t// Test result: Join should return an empty list.\n+\t@Test\n+\tpublic void testOneOfTheOperatorResultContainsNoSpan() throws Exception {\n+\t\tdataWriterForOuter.writeData(bookTuple1);\n+\t\tdataWriterForInner.writeData(bookTuple1);\n+\t\t\n+\t\tString query = \"special\";\n+\t\tIPredicate predicateOuter = new KeywordPredicate(query, attributeList, DataConstants.KeywordMatchingType.SUBSTRING_SCANBASED, analyzer, dataStoreForOuter);\n+        keywordMatcherOuter = new KeywordMatcher(predicateOuter);\n+        \n+        query = \"this writer writes well\";\n+        double thresholdRatio = 0.25;\n+        boolean isSpanInformationAdded = false;\n+        IPredicate fuzzyPredicateInner = new FuzzyTokenPredicate(query, attributeList, analyzer, dataStoreForInner, thresholdRatio, isSpanInformationAdded);\n+        FuzzyTokenMatcher fuzzyMatcherInner = new FuzzyTokenMatcher(fuzzyPredicateInner);\n+        \n+        Attribute idAttr = attributeList.get(0);\n+        Attribute reviewAttr = attributeList.get(4);\n+        List<ITuple> resultList = getJoinResults(keywordMatcherOuter, fuzzyMatcherInner, idAttr, reviewAttr, 20);\n+        Assert.assertEquals(0, resultList.size());\n+\t}\n+\t\n+\t// This case tests for the scenario when the IDs match, fields to be joined \n+\t// match, but one of the spans to be joined is bigger than the other span \n+\t// and encompasses it and both |(span 1 spanStartIndex) - (span 2 spanStartIndex)|,\n+\t// |(span 1 spanEndIndex) - (span 2 spanEndIndex)| are within threshold.\n+\t// Test result: Bigger span should be returned.","path":"textdb/textdb-dataflow/src/test/java/edu/uci/ics/textdb/dataflow/join/JoinTest.java","position":276,"original_position":276,"commit_id":"9e98a0ce1cb2f4e96474ce0cb88c6a7d194beefa","original_commit_id":"9e98a0ce1cb2f4e96474ce0cb88c6a7d194beefa","user":{"login":"chenlica","id":12926365,"avatar_url":"https://avatars.githubusercontent.com/u/12926365?v=3","gravatar_id":"","url":"https://api.github.com/users/chenlica","html_url":"https://github.com/chenlica","followers_url":"https://api.github.com/users/chenlica/followers","following_url":"https://api.github.com/users/chenlica/following{/other_user}","gists_url":"https://api.github.com/users/chenlica/gists{/gist_id}","starred_url":"https://api.github.com/users/chenlica/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chenlica/subscriptions","organizations_url":"https://api.github.com/users/chenlica/orgs","repos_url":"https://api.github.com/users/chenlica/repos","events_url":"https://api.github.com/users/chenlica/events{/privacy}","received_events_url":"https://api.github.com/users/chenlica/received_events","type":"User","site_admin":false},"body":"\"Bigger span\" -> \"a bigger span\"","created_at":"2016-07-15T22:40:26Z","updated_at":"2016-07-15T22:40:26Z","html_url":"https://github.com/TextDB/textdb/pull/161#discussion_r71050182","pull_request_url":"https://api.github.com/repos/TextDB/textdb/pulls/161","_links":{"self":{"href":"https://api.github.com/repos/TextDB/textdb/pulls/comments/71050182"},"html":{"href":"https://github.com/TextDB/textdb/pull/161#discussion_r71050182"},"pull_request":{"href":"https://api.github.com/repos/TextDB/textdb/pulls/161"}}},"pull_request":{"url":"https://api.github.com/repos/TextDB/textdb/pulls/161","id":77683872,"html_url":"https://github.com/TextDB/textdb/pull/161","diff_url":"https://github.com/TextDB/textdb/pull/161.diff","patch_url":"https://github.com/TextDB/textdb/pull/161.patch","issue_url":"https://api.github.com/repos/TextDB/textdb/issues/161","number":161,"state":"open","locked":false,"title":"[Issue #111] Join Implementation: Initial version of test cases","user":{"login":"sripadks","id":2525061,"avatar_url":"https://avatars.githubusercontent.com/u/2525061?v=3","gravatar_id":"","url":"https://api.github.com/users/sripadks","html_url":"https://github.com/sripadks","followers_url":"https://api.github.com/users/sripadks/followers","following_url":"https://api.github.com/users/sripadks/following{/other_user}","gists_url":"https://api.github.com/users/sripadks/gists{/gist_id}","starred_url":"https://api.github.com/users/sripadks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sripadks/subscriptions","organizations_url":"https://api.github.com/users/sripadks/orgs","repos_url":"https://api.github.com/users/sripadks/repos","events_url":"https://api.github.com/users/sripadks/events{/privacy}","received_events_url":"https://api.github.com/users/sripadks/received_events","type":"User","site_admin":false},"body":"This is the first version of test cases. It includes 10 test cases which allows for checking if ids match, if the documents are within span and threshold, etc.","created_at":"2016-07-15T21:52:50Z","updated_at":"2016-07-15T22:40:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bde9d50305811703558c5422ad8aeeb98d6366a6","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/TextDB/textdb/pulls/161/commits","review_comments_url":"https://api.github.com/repos/TextDB/textdb/pulls/161/comments","review_comment_url":"https://api.github.com/repos/TextDB/textdb/pulls/comments{/number}","comments_url":"https://api.github.com/repos/TextDB/textdb/issues/161/comments","statuses_url":"https://api.github.com/repos/TextDB/textdb/statuses/9e98a0ce1cb2f4e96474ce0cb88c6a7d194beefa","head":{"label":"TextDB:sripad-flavio-joinimp-testcase-branch","ref":"sripad-flavio-joinimp-testcase-branch","sha":"9e98a0ce1cb2f4e96474ce0cb88c6a7d194beefa","user":{"login":"TextDB","id":18126950,"avatar_url":"https://avatars.githubusercontent.com/u/18126950?v=3","gravatar_id":"","url":"https://api.github.com/users/TextDB","html_url":"https://github.com/TextDB","followers_url":"https://api.github.com/users/TextDB/followers","following_url":"https://api.github.com/users/TextDB/following{/other_user}","gists_url":"https://api.github.com/users/TextDB/gists{/gist_id}","starred_url":"https://api.github.com/users/TextDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TextDB/subscriptions","organizations_url":"https://api.github.com/users/TextDB/orgs","repos_url":"https://api.github.com/users/TextDB/repos","events_url":"https://api.github.com/users/TextDB/events{/privacy}","received_events_url":"https://api.github.com/users/TextDB/received_events","type":"Organization","site_admin":false},"repo":{"id":53976910,"name":"textdb","full_name":"TextDB/textdb","owner":{"login":"TextDB","id":18126950,"avatar_url":"https://avatars.githubusercontent.com/u/18126950?v=3","gravatar_id":"","url":"https://api.github.com/users/TextDB","html_url":"https://github.com/TextDB","followers_url":"https://api.github.com/users/TextDB/followers","following_url":"https://api.github.com/users/TextDB/following{/other_user}","gists_url":"https://api.github.com/users/TextDB/gists{/gist_id}","starred_url":"https://api.github.com/users/TextDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TextDB/subscriptions","organizations_url":"https://api.github.com/users/TextDB/orgs","repos_url":"https://api.github.com/users/TextDB/repos","events_url":"https://api.github.com/users/TextDB/events{/privacy}","received_events_url":"https://api.github.com/users/TextDB/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/TextDB/textdb","description":"Text-centric data management system","fork":false,"url":"https://api.github.com/repos/TextDB/textdb","forks_url":"https://api.github.com/repos/TextDB/textdb/forks","keys_url":"https://api.github.com/repos/TextDB/textdb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/TextDB/textdb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/TextDB/textdb/teams","hooks_url":"https://api.github.com/repos/TextDB/textdb/hooks","issue_events_url":"https://api.github.com/repos/TextDB/textdb/issues/events{/number}","events_url":"https://api.github.com/repos/TextDB/textdb/events","assignees_url":"https://api.github.com/repos/TextDB/textdb/assignees{/user}","branches_url":"https://api.github.com/repos/TextDB/textdb/branches{/branch}","tags_url":"https://api.github.com/repos/TextDB/textdb/tags","blobs_url":"https://api.github.com/repos/TextDB/textdb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/TextDB/textdb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/TextDB/textdb/git/refs{/sha}","trees_url":"https://api.github.com/repos/TextDB/textdb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/TextDB/textdb/statuses/{sha}","languages_url":"https://api.github.com/repos/TextDB/textdb/languages","stargazers_url":"https://api.github.com/repos/TextDB/textdb/stargazers","contributors_url":"https://api.github.com/repos/TextDB/textdb/contributors","subscribers_url":"https://api.github.com/repos/TextDB/textdb/subscribers","subscription_url":"https://api.github.com/repos/TextDB/textdb/subscription","commits_url":"https://api.github.com/repos/TextDB/textdb/commits{/sha}","git_commits_url":"https://api.github.com/repos/TextDB/textdb/git/commits{/sha}","comments_url":"https://api.github.com/repos/TextDB/textdb/comments{/number}","issue_comment_url":"https://api.github.com/repos/TextDB/textdb/issues/comments{/number}","contents_url":"https://api.github.com/repos/TextDB/textdb/contents/{+path}","compare_url":"https://api.github.com/repos/TextDB/textdb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/TextDB/textdb/merges","archive_url":"https://api.github.com/repos/TextDB/textdb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/TextDB/textdb/downloads","issues_url":"https://api.github.com/repos/TextDB/textdb/issues{/number}","pulls_url":"https://api.github.com/repos/TextDB/textdb/pulls{/number}","milestones_url":"https://api.github.com/repos/TextDB/textdb/milestones{/number}","notifications_url":"https://api.github.com/repos/TextDB/textdb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/TextDB/textdb/labels{/name}","releases_url":"https://api.github.com/repos/TextDB/textdb/releases{/id}","deployments_url":"https://api.github.com/repos/TextDB/textdb/deployments","created_at":"2016-03-15T20:38:46Z","updated_at":"2016-07-01T23:04:53Z","pushed_at":"2016-07-15T21:52:50Z","git_url":"git://github.com/TextDB/textdb.git","ssh_url":"git@github.com:TextDB/textdb.git","clone_url":"https://github.com/TextDB/textdb.git","svn_url":"https://github.com/TextDB/textdb","homepage":null,"size":16872,"stargazers_count":10,"watchers_count":10,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":9,"forks":4,"open_issues":9,"watchers":10,"default_branch":"master"}},"base":{"label":"TextDB:master","ref":"master","sha":"df8a4b6f95e78d4820c473e3520c778dd80fd678","user":{"login":"TextDB","id":18126950,"avatar_url":"https://avatars.githubusercontent.com/u/18126950?v=3","gravatar_id":"","url":"https://api.github.com/users/TextDB","html_url":"https://github.com/TextDB","followers_url":"https://api.github.com/users/TextDB/followers","following_url":"https://api.github.com/users/TextDB/following{/other_user}","gists_url":"https://api.github.com/users/TextDB/gists{/gist_id}","starred_url":"https://api.github.com/users/TextDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TextDB/subscriptions","organizations_url":"https://api.github.com/users/TextDB/orgs","repos_url":"https://api.github.com/users/TextDB/repos","events_url":"https://api.github.com/users/TextDB/events{/privacy}","received_events_url":"https://api.github.com/users/TextDB/received_events","type":"Organization","site_admin":false},"repo":{"id":53976910,"name":"textdb","full_name":"TextDB/textdb","owner":{"login":"TextDB","id":18126950,"avatar_url":"https://avatars.githubusercontent.com/u/18126950?v=3","gravatar_id":"","url":"https://api.github.com/users/TextDB","html_url":"https://github.com/TextDB","followers_url":"https://api.github.com/users/TextDB/followers","following_url":"https://api.github.com/users/TextDB/following{/other_user}","gists_url":"https://api.github.com/users/TextDB/gists{/gist_id}","starred_url":"https://api.github.com/users/TextDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TextDB/subscriptions","organizations_url":"https://api.github.com/users/TextDB/orgs","repos_url":"https://api.github.com/users/TextDB/repos","events_url":"https://api.github.com/users/TextDB/events{/privacy}","received_events_url":"https://api.github.com/users/TextDB/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/TextDB/textdb","description":"Text-centric data management system","fork":false,"url":"https://api.github.com/repos/TextDB/textdb","forks_url":"https://api.github.com/repos/TextDB/textdb/forks","keys_url":"https://api.github.com/repos/TextDB/textdb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/TextDB/textdb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/TextDB/textdb/teams","hooks_url":"https://api.github.com/repos/TextDB/textdb/hooks","issue_events_url":"https://api.github.com/repos/TextDB/textdb/issues/events{/number}","events_url":"https://api.github.com/repos/TextDB/textdb/events","assignees_url":"https://api.github.com/repos/TextDB/textdb/assignees{/user}","branches_url":"https://api.github.com/repos/TextDB/textdb/branches{/branch}","tags_url":"https://api.github.com/repos/TextDB/textdb/tags","blobs_url":"https://api.github.com/repos/TextDB/textdb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/TextDB/textdb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/TextDB/textdb/git/refs{/sha}","trees_url":"https://api.github.com/repos/TextDB/textdb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/TextDB/textdb/statuses/{sha}","languages_url":"https://api.github.com/repos/TextDB/textdb/languages","stargazers_url":"https://api.github.com/repos/TextDB/textdb/stargazers","contributors_url":"https://api.github.com/repos/TextDB/textdb/contributors","subscribers_url":"https://api.github.com/repos/TextDB/textdb/subscribers","subscription_url":"https://api.github.com/repos/TextDB/textdb/subscription","commits_url":"https://api.github.com/repos/TextDB/textdb/commits{/sha}","git_commits_url":"https://api.github.com/repos/TextDB/textdb/git/commits{/sha}","comments_url":"https://api.github.com/repos/TextDB/textdb/comments{/number}","issue_comment_url":"https://api.github.com/repos/TextDB/textdb/issues/comments{/number}","contents_url":"https://api.github.com/repos/TextDB/textdb/contents/{+path}","compare_url":"https://api.github.com/repos/TextDB/textdb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/TextDB/textdb/merges","archive_url":"https://api.github.com/repos/TextDB/textdb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/TextDB/textdb/downloads","issues_url":"https://api.github.com/repos/TextDB/textdb/issues{/number}","pulls_url":"https://api.github.com/repos/TextDB/textdb/pulls{/number}","milestones_url":"https://api.github.com/repos/TextDB/textdb/milestones{/number}","notifications_url":"https://api.github.com/repos/TextDB/textdb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/TextDB/textdb/labels{/name}","releases_url":"https://api.github.com/repos/TextDB/textdb/releases{/id}","deployments_url":"https://api.github.com/repos/TextDB/textdb/deployments","created_at":"2016-03-15T20:38:46Z","updated_at":"2016-07-01T23:04:53Z","pushed_at":"2016-07-15T21:52:50Z","git_url":"git://github.com/TextDB/textdb.git","ssh_url":"git@github.com:TextDB/textdb.git","clone_url":"https://github.com/TextDB/textdb.git","svn_url":"https://github.com/TextDB/textdb","homepage":null,"size":16872,"stargazers_count":10,"watchers_count":10,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":9,"forks":4,"open_issues":9,"watchers":10,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/TextDB/textdb/pulls/161"},"html":{"href":"https://github.com/TextDB/textdb/pull/161"},"issue":{"href":"https://api.github.com/repos/TextDB/textdb/issues/161"},"comments":{"href":"https://api.github.com/repos/TextDB/textdb/issues/161/comments"},"review_comments":{"href":"https://api.github.com/repos/TextDB/textdb/pulls/161/comments"},"review_comment":{"href":"https://api.github.com/repos/TextDB/textdb/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/TextDB/textdb/pulls/161/commits"},"statuses":{"href":"https://api.github.com/repos/TextDB/textdb/statuses/9e98a0ce1cb2f4e96474ce0cb88c6a7d194beefa"}}}}
{"actor":{"display_login":"chenlica"}}