You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by up...@apache.org on 2015/09/24 00:53:49 UTC
incubator-geode git commit: Implementing LuceneQueryImpl.search
Repository: incubator-geode
Updated Branches:
refs/heads/feature/GEODE-11 8fb4ad7a2 -> 3e743df86
Implementing LuceneQueryImpl.search
Implementing search by invoking the LuceneFunction from within
LuceneQueryImpl.search and building a result set. Adding unit tests for
the same.
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/3e743df8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/3e743df8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/3e743df8
Branch: refs/heads/feature/GEODE-11
Commit: 3e743df86ce7487fd1cf094734ca8a5bbe7895cb
Parents: 8fb4ad7
Author: Dan Smith <up...@apache.org>
Authored: Wed Sep 23 15:28:19 2015 -0700
Committer: Dan Smith <up...@apache.org>
Committed: Wed Sep 23 15:53:09 2015 -0700
----------------------------------------------------------------------
.../gemfire/cache/lucene/LuceneQuery.java | 4 +-
.../cache/lucene/LuceneQueryFactory.java | 8 +-
.../lucene/internal/LuceneQueryFactoryImpl.java | 39 ++++-----
.../cache/lucene/internal/LuceneQueryImpl.java | 42 +++++++---
.../lucene/internal/LuceneServiceImpl.java | 2 +-
.../LuceneQueryFactoryImplJUnitTest.java | 32 ++++++++
.../internal/LuceneQueryImplJUnitTest.java | 84 ++++++++++++++++++++
.../LuceneFunctionReadPathDUnitTest.java | 34 +++-----
8 files changed, 177 insertions(+), 68 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3e743df8/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQuery.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQuery.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQuery.java
index 548bb00..09d3a07 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQuery.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQuery.java
@@ -6,11 +6,11 @@ package com.gemstone.gemfire.cache.lucene;
* {@link LuceneQueryFactory#create}.
*
*/
-public interface LuceneQuery {
+public interface LuceneQuery<K, V> {
/**
* Execute the search and get results.
*/
- public LuceneQueryResults search();
+ public LuceneQueryResults<K, V> search();
/**
* Get page size setting of current query.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3e743df8/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQueryFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQueryFactory.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQueryFactory.java
index 55f1b3a..b5598ad 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQueryFactory.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/LuceneQueryFactory.java
@@ -56,10 +56,12 @@ public interface LuceneQueryFactory {
* @param regionName region name
* @param indexName index name
* @param queryString query string in lucene QueryParser's syntax
+ * @param K the key type in the query results
+ * @param V the value type in the query results
* @return LuceneQuery object
* @throws ParseException
*/
- public LuceneQuery create(String indexName, String regionName, String queryString)
+ public <K, V> LuceneQuery<K, V> create(String indexName, String regionName, String queryString)
throws ParseException;
/**
@@ -70,7 +72,9 @@ public interface LuceneQueryFactory {
* @param indexName index name
* @param regionName region name
* @param provider constructs and provides a Lucene Query object
+ * @param K the key type in the query results
+ * @param V the value type in the query results
* @return LuceneQuery object
*/
- public LuceneQuery create(String indexName, String regionName, LuceneQueryProvider provider);
+ public <K, V> LuceneQuery<K, V> create(String indexName, String regionName, LuceneQueryProvider provider);
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3e743df8/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryFactoryImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryFactoryImpl.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryFactoryImpl.java
index 9210929..2a602a5 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryFactoryImpl.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryFactoryImpl.java
@@ -3,13 +3,10 @@ package com.gemstone.gemfire.cache.lucene.internal;
import java.util.HashSet;
import java.util.Set;
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryparser.classic.ParseException;
-import org.apache.lucene.queryparser.classic.QueryParser;
-import org.apache.lucene.search.Query;
-import com.gemstone.gemfire.cache.lucene.LuceneIndex;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.lucene.LuceneQuery;
import com.gemstone.gemfire.cache.lucene.LuceneQueryFactory;
import com.gemstone.gemfire.cache.lucene.LuceneQueryProvider;
@@ -17,13 +14,13 @@ import com.gemstone.gemfire.cache.lucene.LuceneQueryProvider;
public class LuceneQueryFactoryImpl implements LuceneQueryFactory {
private int limit = DEFAULT_LIMIT;
private int pageSize = DEFAULT_PAGESIZE;
- private Set<String> projectionFields = new HashSet<String>();
+ private String[] projectionFields = null;
+ private Cache cache;
+
+ LuceneQueryFactoryImpl(Cache cache) {
+ this.cache = cache;
+ }
- /* reference to the index. One index could have multiple Queries, but one Query must belong
- * to one index
- */
- private LuceneIndex relatedIndex;
-
@Override
public LuceneQueryFactory setPageSize(int pageSize) {
this.pageSize = pageSize;
@@ -37,28 +34,20 @@ public class LuceneQueryFactoryImpl implements LuceneQueryFactory {
}
@Override
- public LuceneQuery create(String indexName, String regionName,
- String queryString) throws ParseException {
+ public <K, V> LuceneQuery<K, V> create(String indexName, String regionName,
+ String queryString) {
return create(indexName, regionName, new StringQueryProvider(queryString));
}
- public LuceneQuery create(String indexName, String regionName, LuceneQueryProvider provider) {
- LuceneQueryImpl luceneQuery = new LuceneQueryImpl(indexName, regionName, provider, projectionFields, limit, pageSize);
+ public <K, V> LuceneQuery<K, V> create(String indexName, String regionName, LuceneQueryProvider provider) {
+ Region region = cache.getRegion(regionName);
+ LuceneQueryImpl<K, V> luceneQuery = new LuceneQueryImpl<K, V>(indexName, region, provider, projectionFields, limit, pageSize);
return luceneQuery;
}
-
- public LuceneIndex getRelatedIndex() {
- return this.relatedIndex;
- }
-
@Override
public LuceneQueryFactory setProjectionFields(String... fieldNames) {
- if (fieldNames != null) {
- for (String fieldName:fieldNames) {
- this.projectionFields.add(fieldName);
- }
- }
+ projectionFields = fieldNames.clone();
return this;
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3e743df8/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryImpl.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryImpl.java
index 714df95..a5cbc79 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryImpl.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryImpl.java
@@ -2,29 +2,34 @@ package com.gemstone.gemfire.cache.lucene.internal;
import java.util.Set;
-import org.apache.lucene.search.Query;
-
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.execute.ResultCollector;
import com.gemstone.gemfire.cache.lucene.LuceneQuery;
import com.gemstone.gemfire.cache.lucene.LuceneQueryFactory;
import com.gemstone.gemfire.cache.lucene.LuceneQueryProvider;
import com.gemstone.gemfire.cache.lucene.LuceneQueryResults;
+import com.gemstone.gemfire.cache.lucene.internal.distributed.LuceneFunction;
+import com.gemstone.gemfire.cache.lucene.internal.distributed.LuceneFunctionContext;
+import com.gemstone.gemfire.cache.lucene.internal.distributed.TopEntries;
+import com.gemstone.gemfire.cache.lucene.internal.distributed.TopEntriesCollector;
+import com.gemstone.gemfire.cache.lucene.internal.distributed.TopEntriesCollectorManager;
+import com.gemstone.gemfire.cache.lucene.internal.distributed.TopEntriesFunctionCollector;
-public class LuceneQueryImpl implements LuceneQuery {
+public class LuceneQueryImpl<K, V> implements LuceneQuery<K, V> {
private int limit = LuceneQueryFactory.DEFAULT_LIMIT;
private int pageSize = LuceneQueryFactory.DEFAULT_PAGESIZE;
private String indexName;
- private String regionName;
-
// The projected fields are local to a specific index per Query object.
- private Set<String> projectedFieldNames;
-
+ private String[] projectedFieldNames;
/* the lucene Query object to be wrapped here */
private LuceneQueryProvider query;
+ private Region<K, V> region;
- LuceneQueryImpl(String indexName, String regionName, LuceneQueryProvider provider, Set<String> projectionFields,
+ public LuceneQueryImpl(String indexName, Region<K, V> region, LuceneQueryProvider provider, String[] projectionFields,
int limit, int pageSize) {
this.indexName = indexName;
- this.regionName = regionName;
+ this.region = region;
this.limit = limit;
this.pageSize = pageSize;
this.projectedFieldNames = projectionFields;
@@ -32,9 +37,20 @@ public class LuceneQueryImpl implements LuceneQuery {
}
@Override
- public LuceneQueryResults search() {
- // TODO Auto-generated method stub
- return null;
+ public LuceneQueryResults<K, V> search() {
+ LuceneFunctionContext<TopEntriesCollector> context = new LuceneFunctionContext<>(query, indexName,
+ new TopEntriesCollectorManager());
+ TopEntriesFunctionCollector collector = new TopEntriesFunctionCollector();
+
+ ResultCollector<TopEntriesCollector, TopEntries> rc = (ResultCollector<TopEntriesCollector, TopEntries>) FunctionService.onRegion(region)
+ .withArgs(context)
+ .withCollector(collector)
+ .execute(LuceneFunction.ID);
+
+ //TODO provide a timeout to the user?
+ TopEntries entries = rc.getResult();
+
+ return new LuceneQueryResultsImpl<K, V>(entries.getHits(), region, pageSize);
}
@Override
@@ -49,7 +65,7 @@ public class LuceneQueryImpl implements LuceneQuery {
@Override
public String[] getProjectedFieldNames() {
- return (String[])this.projectedFieldNames.toArray();
+ return this.projectedFieldNames;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3e743df8/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java
index cb6e5fc..b1631d1 100644
--- a/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java
+++ b/gemfire-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/LuceneServiceImpl.java
@@ -142,7 +142,7 @@ public class LuceneServiceImpl implements InternalLuceneService {
@Override
public LuceneQueryFactory createLuceneQueryFactory() {
- return new LuceneQueryFactoryImpl();
+ return new LuceneQueryFactoryImpl(cache);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3e743df8/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryFactoryImplJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryFactoryImplJUnitTest.java b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryFactoryImplJUnitTest.java
new file mode 100644
index 0000000..6cb5368
--- /dev/null
+++ b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryFactoryImplJUnitTest.java
@@ -0,0 +1,32 @@
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.Mockito;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.lucene.LuceneQuery;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class LuceneQueryFactoryImplJUnitTest {
+
+ @Test
+ public void test() {
+ Cache cache = Mockito.mock(Cache.class);
+ LuceneQueryFactoryImpl f = new LuceneQueryFactoryImpl(cache);
+ f.setPageSize(5);
+ f.setResultLimit(25);
+ String[] projection = new String[] {"a", "b"};
+ f.setProjectionFields(projection);
+ LuceneQuery<Object, Object> query = f.create("index", "region", new StringQueryProvider("test"));
+ assertEquals(25, query.getLimit());
+ assertEquals(5, query.getPageSize());
+ assertArrayEquals(projection, query.getProjectedFieldNames());
+
+ Mockito.verify(cache).getRegion(Mockito.eq("region"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3e743df8/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryImplJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryImplJUnitTest.java b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryImplJUnitTest.java
new file mode 100644
index 0000000..d3ffd19
--- /dev/null
+++ b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/LuceneQueryImplJUnitTest.java
@@ -0,0 +1,84 @@
+package com.gemstone.gemfire.cache.lucene.internal;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.execute.FunctionAdapter;
+import com.gemstone.gemfire.cache.execute.FunctionContext;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.lucene.LuceneQueryResults;
+import com.gemstone.gemfire.cache.lucene.internal.distributed.LuceneFunction;
+import com.gemstone.gemfire.cache.lucene.internal.distributed.LuceneFunctionContext;
+import com.gemstone.gemfire.cache.lucene.internal.distributed.TopEntriesCollector;
+import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+
+@Category(IntegrationTest.class)
+public class LuceneQueryImplJUnitTest {
+
+ private Cache cache;
+ private Region<Object, Object> region;
+ @Before
+ public void createCache() {
+ cache = new CacheFactory().set("mcast-port", "0").create();
+ region = cache.createRegionFactory(RegionShortcut.REPLICATE).create("region");
+ }
+
+ @After
+ public void removeCache() {
+ FunctionService.unregisterFunction(LuceneFunction.ID);
+ cache.close();
+ }
+ @Test
+ public void test() {
+ //Register a fake function to observe the function invocation
+ FunctionService.unregisterFunction(LuceneFunction.ID);
+ TestLuceneFunction function = new TestLuceneFunction();
+ FunctionService.registerFunction(function);
+
+
+ StringQueryProvider provider = new StringQueryProvider();
+ LuceneQueryImpl query = new LuceneQueryImpl("index", region, provider, null, 100, 20);
+ LuceneQueryResults results = query.search();
+ List nextPage = results.getNextPage();
+ assertEquals(3, nextPage.size());
+ assertEquals(.3f, results.getMaxScore(), 0.01);
+ assertTrue(function.wasInvoked);
+
+ LuceneFunctionContext args = (LuceneFunctionContext) function.args;
+ assertEquals(provider.getQueryString(), ((StringQueryProvider) args.getQueryProvider()).getQueryString());
+ assertEquals("index", args.getIndexName());
+ assertEquals(100, args.getLimit());
+ }
+
+ private static class TestLuceneFunction extends FunctionAdapter {
+
+ private boolean wasInvoked;
+ private Object args;
+
+ @Override
+ public void execute(FunctionContext context) {
+ this.args = context.getArguments();
+ wasInvoked = true;
+ TopEntriesCollector lastResult = new TopEntriesCollector();
+ lastResult.collect(3, .3f);
+ lastResult.collect(2, .2f);
+ lastResult.collect(1, .1f);
+ context.getResultSender().lastResult(lastResult);
+ }
+
+ @Override
+ public String getId() {
+ return LuceneFunction.ID;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3e743df8/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionReadPathDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionReadPathDUnitTest.java b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionReadPathDUnitTest.java
index 939790d..3448725 100644
--- a/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionReadPathDUnitTest.java
+++ b/gemfire-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionReadPathDUnitTest.java
@@ -1,7 +1,6 @@
package com.gemstone.gemfire.cache.lucene.internal.distributed;
import java.io.Serializable;
-import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.junit.experimental.categories.Category;
@@ -10,14 +9,11 @@ import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.RegionFactory;
import com.gemstone.gemfire.cache.RegionShortcut;
-import com.gemstone.gemfire.cache.execute.FunctionService;
-import com.gemstone.gemfire.cache.execute.ResultCollector;
-import com.gemstone.gemfire.cache.lucene.LuceneIndex;
-import com.gemstone.gemfire.cache.lucene.LuceneQueryProvider;
+import com.gemstone.gemfire.cache.lucene.LuceneQuery;
+import com.gemstone.gemfire.cache.lucene.LuceneQueryResults;
import com.gemstone.gemfire.cache.lucene.LuceneService;
import com.gemstone.gemfire.cache.lucene.LuceneServiceProvider;
import com.gemstone.gemfire.cache.lucene.internal.InternalLuceneIndex;
-import com.gemstone.gemfire.cache.lucene.internal.StringQueryProvider;
import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository;
import com.gemstone.gemfire.cache30.CacheTestCase;
import com.gemstone.gemfire.internal.cache.BucketNotFoundException;
@@ -25,7 +21,6 @@ import com.gemstone.gemfire.test.junit.categories.DistributedTest;
import dunit.Host;
import dunit.SerializableCallable;
-import dunit.SerializableRunnable;
import dunit.VM;
@Category(DistributedTest.class)
@@ -87,32 +82,21 @@ public class LuceneFunctionReadPathDUnitTest extends CacheTestCase {
server1.invoke(createPartitionRegion);
server2.invoke(createPartitionRegion);
- SerializableRunnable executeSearch = new SerializableRunnable("executeSearch") {
+ SerializableCallable executeSearch = new SerializableCallable("executeSearch") {
private static final long serialVersionUID = 1L;
- public void run() {
+ public Object call() throws Exception {
Cache cache = getCache();
assertNotNull(cache);
Region<Object, Object> region = cache.getRegion(REGION_NAME);
Assert.assertNotNull(region);
LuceneService service = LuceneServiceProvider.get(cache);
- LuceneIndex index = service.getIndex(INDEX_NAME, REGION_NAME);
- LuceneQueryProvider provider = new StringQueryProvider("text:world");
-
- LuceneFunctionContext<TopEntriesCollector> context = new LuceneFunctionContext<>(provider, index.getName(),
- new TopEntriesCollectorManager());
- TopEntriesFunctionCollector collector = new TopEntriesFunctionCollector();
-
- ResultCollector<TopEntriesCollector, TopEntries> rc = (ResultCollector<TopEntriesCollector, TopEntries>) FunctionService.onRegion(region).withArgs(context).withCollector(collector).execute(LuceneFunction.ID);
- TopEntries entries;
- try {
- entries = rc.getResult(30, TimeUnit.SECONDS);
- assertNotNull(entries);
- assertEquals(2, entries.getHits().size());
- } catch (Exception e) {
- fail("failed", e);
- }
+ LuceneQuery query = service.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "text:world");
+ LuceneQueryResults results = query.search();
+ assertEquals(2, results.size());
+
+ return null;
}
};