ConjunctionIndex { public Searcher searcher() { return new Searcher(); } ConjunctionIndex(IntObjectMap<FeatureIndex> kIndex, int[] zList, long[] idMapping); Searcher searcher(); void writeToOutputStream(DataOutputStream out); static ConjunctionIndex fromInputStream(DataInputStream in);  }
@Test public void require_that_search_for_simple_conjunctions_work() { ConjunctionIndexBuilder builder = new ConjunctionIndexBuilder(); IndexableFeatureConjunction c1 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("2"))); IndexableFeatureConjunction c2 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("2"), feature("c").inSet("3"))); IndexableFeatureConjunction c3 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("5"))); builder.indexConjunction(c1); builder.indexConjunction(c2); builder.indexConjunction(c3); ConjunctionIndex index = builder.build(); ConjunctionIndex.Searcher searcher = index.searcher(); PredicateQuery query = new PredicateQuery(); query.addFeature("a", "1"); query.addFeature("b", "2"); assertHitsEquals(searcher.search(query), c1); query.addFeature("c", "3"); assertHitsEquals(searcher.search(query), c1, c2); query.addFeature("b", "5"); assertHitsEquals(searcher.search(query), c1, c2, c3); }
@Test public void require_that_not_works_when_k_is_0() { ConjunctionIndexBuilder builder = new ConjunctionIndexBuilder(); IndexableFeatureConjunction c1 = indexableConj( conj( not(feature("a").inSet("1")), not(feature("b").inSet("1")))); IndexableFeatureConjunction c2 = indexableConj( conj( not(feature("a").inSet("1")), not(feature("b").inSet("1")), not(feature("c").inSet("1")))); IndexableFeatureConjunction c3 = indexableConj( conj( not(feature("a").inSet("1")), not(feature("b").inSet("1")), not(feature("c").inSet("1")), not(feature("d").inSet("1")))); IndexableFeatureConjunction c4 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("1"))); builder.indexConjunction(c1); builder.indexConjunction(c2); builder.indexConjunction(c3); builder.indexConjunction(c4); ConjunctionIndex index = builder.build(); ConjunctionIndex.Searcher searcher = index.searcher(); PredicateQuery query = new PredicateQuery(); assertHitsEquals(searcher.search(query), c1, c2, c3); query.addFeature("a", "1"); query.addFeature("b", "1"); assertHitsEquals(searcher.search(query), c4); query.addFeature("c", "1"); assertHitsEquals(searcher.search(query), c4); query.addFeature("d", "1"); assertHitsEquals(searcher.search(query), c4); }
@Test public void require_that_not_works_when_k_is_1() { ConjunctionIndexBuilder builder = new ConjunctionIndexBuilder(); IndexableFeatureConjunction c1 = indexableConj( conj( feature("a").inSet("1"), not(feature("b").inSet("1")))); IndexableFeatureConjunction c2 = indexableConj( conj( feature("a").inSet("1"), not(feature("b").inSet("1")), not(feature("c").inSet("1")))); IndexableFeatureConjunction c3 = indexableConj( conj( feature("a").inSet("1"), not(feature("b").inSet("1")), not(feature("c").inSet("1")), not(feature("d").inSet("1")))); builder.indexConjunction(c1); builder.indexConjunction(c2); builder.indexConjunction(c3); ConjunctionIndex index = builder.build(); ConjunctionIndex.Searcher searcher = index.searcher(); PredicateQuery query = new PredicateQuery(); assertTrue(searcher.search(query).isEmpty()); query.addFeature("a", "1"); assertHitsEquals(searcher.search(query), c1, c2, c3); query.addFeature("b", "1"); assertTrue(searcher.search(query).isEmpty()); query.addFeature("c", "1"); assertTrue(searcher.search(query).isEmpty()); query.addFeature("d", "1"); assertTrue(searcher.search(query).isEmpty()); }
@Test public void require_that_not_works_when_k_is_2() { ConjunctionIndexBuilder builder = new ConjunctionIndexBuilder(); IndexableFeatureConjunction c1 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("1"), not(feature("c").inSet("1")))); IndexableFeatureConjunction c2 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("1"), not(feature("c").inSet("1")), not(feature("d").inSet("1")))); IndexableFeatureConjunction c3 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("1"), not(feature("c").inSet("1")), not(feature("d").inSet("1")), not(feature("e").inSet("1")))); builder.indexConjunction(c1); builder.indexConjunction(c2); builder.indexConjunction(c3); ConjunctionIndex index = builder.build(); ConjunctionIndex.Searcher searcher = index.searcher(); PredicateQuery query = new PredicateQuery(); query.addFeature("a", "1"); query.addFeature("b", "1"); assertHitsEquals(searcher.search(query), c1, c2, c3); query.addFeature("c", "1"); assertTrue(searcher.search(query).isEmpty()); query.addFeature("d", "1"); assertTrue(searcher.search(query).isEmpty()); query.addFeature("e", "1"); assertTrue(searcher.search(query).isEmpty()); }
@Test public void require_that_multi_term_queries_are_supported() { ConjunctionIndexBuilder builder = new ConjunctionIndexBuilder(); IndexableFeatureConjunction c1 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("3"))); builder.indexConjunction(c1); ConjunctionIndex index = builder.build(); ConjunctionIndex.Searcher searcher = index.searcher(); PredicateQuery query = new PredicateQuery(); query.addFeature("a", "1"); query.addFeature("a", "2"); assertTrue(searcher.search(query).isEmpty()); query.addFeature("b", "3"); assertHitsEquals(searcher.search(query), c1); }
@Test public void require_that_subqueries_are_supported() { ConjunctionIndexBuilder builder = new ConjunctionIndexBuilder(); IndexableFeatureConjunction c1 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("3"), not(feature("c").inSet("4")))); IndexableFeatureConjunction c2 = indexableConj( conj( feature("a").inSet("1"), feature("b").inSet("3"))); IndexableFeatureConjunction c3 = indexableConj( conj( feature("a").inSet("2"), feature("b").inSet("3"))); IndexableFeatureConjunction c4 = indexableConj( conj( feature("e").inSet("5"), feature("f").inSet("6")) ); builder.indexConjunction(c1); builder.indexConjunction(c2); builder.indexConjunction(c3); builder.indexConjunction(c4); ConjunctionIndex index = builder.build(); ConjunctionIndex.Searcher searcher = index.searcher(); PredicateQuery query = new PredicateQuery(); query.addFeature("a", "1", 0b110); query.addFeature("a", "2", 0b001); query.addFeature("b", "3", 0b111); List<ConjunctionHit> expectedHits = matchingConjunctionList( new ConjunctionHit(c1.id, 0b110), new ConjunctionHit(c2.id, 0b110), new ConjunctionHit(c3.id, 0b001) ); List<ConjunctionHit> hits = searcher.search(query); assertHitsEquals(expectedHits, hits); query.addFeature("c", "4", 0b101); expectedHits = matchingConjunctionList( new ConjunctionHit(c1.id, 0b010), new ConjunctionHit(c2.id, 0b110), new ConjunctionHit(c3.id, 0b001) ); hits = searcher.search(query); assertHitsEquals(expectedHits, hits); PredicateQuery query2 = new PredicateQuery(); query2.addFeature("a", "2", 0b01); query2.addFeature("b", "3", 0b10); query2.addFeature("e", "5", 0b01); query2.addFeature("f", "6", 0b10); expectedHits = matchingConjunctionList( new ConjunctionHit(c1.id, 0b010), new ConjunctionHit(c2.id, 0b110), new ConjunctionHit(c3.id, 0b001) ); hits = searcher.search(query); assertHitsEquals(expectedHits, hits); }