diff options
author | Jon Bratseth <bratseth@oath.com> | 2018-05-07 10:40:37 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@oath.com> | 2018-05-07 10:40:37 +0200 |
commit | 2e8b2ca9c60d3449e51238f11e988123d437e170 (patch) | |
tree | 1f054cac6aa3acdd17343fcd887bcbb61dd44ab4 /container-search | |
parent | dd16e6c4caba6bd41812f353d3ec48cdf048474d (diff) | |
parent | 7f4e7753d438b8bb099e966c21f810b605b5a8b9 (diff) |
Merge branch 'master' into bratseth/lazy-summary-decoding
Diffstat (limited to 'container-search')
6 files changed, 5 insertions, 716 deletions
diff --git a/container-search/pom.xml b/container-search/pom.xml index 0df502cf21a..cdfcdb2434a 100644 --- a/container-search/pom.xml +++ b/container-search/pom.xml @@ -142,6 +142,11 @@ </exclusions> </dependency> <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.antlr</groupId> <artifactId>antlr4-runtime</artifactId> </dependency> diff --git a/container-search/src/main/java/com/yahoo/prelude/cache/Cache.java b/container-search/src/main/java/com/yahoo/prelude/cache/Cache.java deleted file mode 100644 index 9e0dde4b63a..00000000000 --- a/container-search/src/main/java/com/yahoo/prelude/cache/Cache.java +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.prelude.cache; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import com.yahoo.cache.SizeCalculator; -import com.yahoo.search.Result; -import com.yahoo.statistics.Statistics; -import com.yahoo.statistics.Value; - -/** - * <p>A generic cache which keeps the total memory consumed by its content - * below a configured maximum.</p> - * - * <p>Thread safe.</p> - * - * @author vegardh - */ -public class Cache<K, V> { - private Value elems = null; - private Value entrySizes = null; - - private Map<CacheKey<K>,CacheValue<K, V>> content=new LinkedHashMap<>(12500, 1.0f, true); - private SizeCalculator calc = new SizeCalculator(); - private long maxSizeBytes; - - private long currentSizeBytes=0; - - /** The time an element is allowed to live, negative for indefinite lifespan */ - private long timeToLiveMillis=-1; - - /** The max allowed size of an entry */ - private long maxEntrySizeBytes=10000; - - /** - * Creates a new cache - * - * @param maxSizeBytes the max size in bytes this cache is permitted to consume, - * including Result objects and Query keys - * @param timeToLiveMillis a negative value means unlimited time - * @param manager the current Statistics manager acquired by injection - */ - public Cache(long maxSizeBytes,long timeToLiveMillis, long maxEntrySizeBytes, Statistics manager) { - this.maxSizeBytes=maxSizeBytes; - this.timeToLiveMillis=timeToLiveMillis; - this.maxEntrySizeBytes=maxEntrySizeBytes; - initStats(manager); - } - - private void initStats(Statistics manager) { - elems = new Value("querycache_elems", manager, new Value.Parameters() - .setLogRaw(true).setNameExtension(true).setLogMax(true)); - entrySizes = new Value("querycache_entry_sizes", manager, - new Value.Parameters().setLogRaw(false).setLogMean(true) - .setNameExtension(true).setLogMax(true)); - } - - private synchronized CacheValue<K, V> synchGet(CacheKey<K> k) { - return content.get(k); - } - - private synchronized boolean synchPut(K key,V value, long keySizeBytes, long valueSizeBytes) { - // log.info("Put "+key.toString()+ " key size:"+keySizeBytes+" val size:"+valueSizeBytes); - makeRoomForBytes(valueSizeBytes+keySizeBytes); - CacheKey<K> cacheKey = new CacheKey<>(keySizeBytes, key); - CacheValue<K, V> cacheValue; - if (timeToLiveMillis<0) { - cacheValue=new CacheValue<>(valueSizeBytes,value, cacheKey); - } else { - cacheValue=new AgingCacheValue<>(valueSizeBytes,value, cacheKey); - } - currentSizeBytes+=(valueSizeBytes+keySizeBytes); - elems.put(content.size()); - content.put(cacheKey, cacheValue); - return true; - } - - /** - * Attempts to add a value to the cache - * - * @param key the key of the value - * @param value the value to add - * @return true if the value was added, false if it could not be added - */ - public boolean put(K key,V value) { - if (value instanceof Result) { // Optimized for CachingSearcher. Assuming the key is the Query. - long totalSizeBytes = calc.sizeOf(value); // Result has a Query field - if (tooBigToCache(totalSizeBytes)) { - return false; - } - entrySizes.put(totalSizeBytes); - return synchPut(key, value, 0, totalSizeBytes); - } - long keySizeBytes=calc.sizeOf(key); - long valueSizeBytes=calc.sizeOf(value); - if (tooBigToCache(keySizeBytes+valueSizeBytes)) { - return false; - } - entrySizes.put(keySizeBytes+valueSizeBytes); - return synchPut(key, value, keySizeBytes, valueSizeBytes); - } - - /** - * Don't cache elems that are too big, even if there's space - */ - private boolean tooBigToCache(long totalSize) { - if (totalSize > maxEntrySizeBytes) { - return true; - } - if (totalSize > maxSizeBytes) { - return true; - } - return false; - } - - private void makeRoomForBytes(long bytes) { - if ((maxSizeBytes-currentSizeBytes) > bytes) { - return; - } - if (content.isEmpty()) { - return; - } - for (Iterator<Map.Entry<CacheKey<K>, CacheValue<K, V>>> i = content.entrySet().iterator() ; i.hasNext() ; ) { - Map.Entry<CacheKey<K>, CacheValue<K, V>> entry = i.next(); - CacheKey<K> key = entry.getKey(); - CacheValue<K, V> value = entry.getValue(); - // Can't call this.removeField(), breaks iterator. - i.remove(); // Access order: first ones are LRU. - currentSizeBytes-=key.sizeBytes(); - currentSizeBytes-=value.sizeBytes(); - if ((maxSizeBytes-currentSizeBytes) > bytes) { - break; - } - } - } - - public boolean containsKey(K k) { - return content.containsKey(new CacheKey<>(-1, k)); - } - - /** Returns a value, if it is present in the cache */ - public V get(K key) { - // Currently it works to make a new CacheKey object without size - // because we have changed hashCode() there. - CacheKey<K> cacheKey = new CacheKey<>(-1, key); - CacheValue<K, V> value=synchGet(cacheKey); - if (value==null) { - return null; - } - if (timeToLiveMillis<0) { - return value.value(); - } - - if (value.expired(timeToLiveMillis)) { - // There was a value, which has now expired - remove(key); - return null; - } else { - return value.value(); - } - } - - /** - * Removes a cache value if present - * - * @return true if the value was removed, false if it was not present - */ - public synchronized boolean remove(K key) { - CacheValue<K, V> value=content.remove(key); - if (value==null) { - return false; - } - currentSizeBytes-=value.sizeBytes(); - currentSizeBytes-=value.getKey().sizeBytes(); - elems.put(content.size()); - return true; - } - - public int size() { - return content.size(); - } - - private static class CacheKey<K> { - private long sizeBytes; - private K key; - public CacheKey(long sizeBytes,K key) { - this.sizeBytes=sizeBytes; - this.key=key; - } - - public long sizeBytes() { - return sizeBytes; - } - - public K getKey() { - return key; - } - - public int hashCode() { - return key.hashCode(); - } - - @SuppressWarnings("rawtypes") - public boolean equals(Object k) { - if (key==null) { - return false; - } - if (k==null) { - return false; - } - if (k instanceof CacheKey) { - return key.equals(((CacheKey)k).getKey()); - } - return false; - } - - public String toString() { - return key.toString(); - } - - } - - private static class CacheValue<K, V> { - private long sizeBytes; - private V value; - private CacheKey<K> key; - public CacheValue(long sizeBytes, V value, CacheKey<K> key) { - this.sizeBytes=sizeBytes; - this.value=value; - this.key = key; - } - - public boolean expired(long ttl) { - return false; - } - - public V value() { - return value; - } - - public long sizeBytes() { - return sizeBytes; - } - - public CacheKey<K> getKey() { - return key; - } - - public String toString() { - return value.toString(); - } - - } - - private static class AgingCacheValue<K, V> extends CacheValue<K, V> { - private long birthTimeMillis; - - public AgingCacheValue(long sizeBytes,V value, CacheKey<K> key) { - super(sizeBytes,value, key); - this.birthTimeMillis=System.currentTimeMillis(); - } - - public long ageMillis() { - return System.currentTimeMillis()-birthTimeMillis; - } - - public boolean expired(long ttl) { - return (ageMillis() >= ttl); - } - } - -} diff --git a/container-search/src/main/java/com/yahoo/prelude/cache/QueryCacheKey.java b/container-search/src/main/java/com/yahoo/prelude/cache/QueryCacheKey.java deleted file mode 100644 index f627124b6f7..00000000000 --- a/container-search/src/main/java/com/yahoo/prelude/cache/QueryCacheKey.java +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.prelude.cache; - -import com.yahoo.search.Query; - -public class QueryCacheKey { - private Query query; - private int offset; - private int hits; - - public QueryCacheKey(Query query) { - this.query = query; - this.offset = query.getOffset(); - this.hits = query.getHits(); - } - - public boolean equals(Object key) { - if (key==null) { - return false; - } - if (query==null) { - return false; - } - if (key instanceof QueryCacheKey) { - QueryCacheKey ckey = (QueryCacheKey)key; - boolean res = equalQueryWith(ckey) && equalPathWith(ckey); - return res; - } - return false; - } - - private boolean equalQueryWith(QueryCacheKey other) { - return query.equals(other.getQuery()); - } - - private boolean equalPathWith(QueryCacheKey other) { - if (other == null) return false; - if (other.getQuery() == null) return false; - - return query.getHttpRequest().getUri().getPath().equals(other.getQuery().getHttpRequest().getUri().getPath()); - } - - public int getHits() { - return hits; - } - - public int getOffset() { - return offset; - } - - public Query getQuery() { - return query; - } - - public void setQuery(Query newQuery) { - query = newQuery; - } - - public String toString() { - if (query==null) { - return super.toString(); - } - return query.toString(); - } - - public int hashCode() { - if (query==null) { - return super.hashCode(); - } - int ret = query.hashCode(); - return ret; - } -} diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/CachingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/CachingSearcher.java deleted file mode 100644 index f80d6f2e1eb..00000000000 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/CachingSearcher.java +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.prelude.searcher; - -import com.yahoo.component.chain.dependencies.After; -import com.yahoo.component.chain.dependencies.Before; -import com.yahoo.container.QrSearchersConfig; -import com.yahoo.search.Query; -import com.yahoo.search.Result; -import com.yahoo.prelude.cache.Cache; -import com.yahoo.prelude.cache.QueryCacheKey; -import com.yahoo.search.Searcher; -import com.yahoo.processing.request.CompoundName; -import com.yahoo.search.searchchain.Execution; -import com.yahoo.statistics.Statistics; -import com.yahoo.statistics.Value; - -/** - * A generic caching searcher which caches all passing results. - * - * @author vegardh - */ -@After("rawQuery") -@Before("transformedQuery") -public class CachingSearcher extends Searcher { - - private static final CompoundName nocachewrite=new CompoundName("nocachewrite"); - - private Cache<QueryCacheKey, Result> cache; - private Value cacheHitRatio = null; - - public CachingSearcher(QrSearchersConfig config, Statistics manager) { - long maxSizeBytes = config.com().yahoo().prelude().searcher().CachingSearcher().cachesizemegabytes()*1024*1024; - long timeToLiveMillis = config.com().yahoo().prelude().searcher().CachingSearcher().timetoliveseconds()*1000; - long maxEntrySizeBytes = config.com().yahoo().prelude().searcher().CachingSearcher().maxentrysizebytes(); - cache=new Cache<>(maxSizeBytes, timeToLiveMillis, maxEntrySizeBytes, manager); - initRatio(manager); - } - - private void initRatio(Statistics manager) { - cacheHitRatio = new Value("querycache_hit_ratio", manager, - new Value.Parameters().setNameExtension(false).setLogRaw(false).setLogMean(true)); - } - - private synchronized void cacheHit() { - cacheHitRatio.put(1.0d); - } - - private synchronized void cacheMiss() { - cacheHitRatio.put(0.0d); - } - - private boolean noCacheWrite(Query query) { - return query.properties().getBoolean(nocachewrite); - } - - public Result search(com.yahoo.search.Query query, Execution execution) { - if (query.getNoCache()) { - return execution.search(query); - } - QueryCacheKey queryKey = new QueryCacheKey(query); - Result cachedResult=cache.get(queryKey); - if (cachedResult!=null) { - cacheHit(); - return cachedResult; - } - cacheMiss(); - Query originalQuery = query.clone(); // Need a copy, as cache hash key later on, maybe. - Result result = execution.search(query); - execution.fill(result); - if (!noCacheWrite(query)) { - queryKey.setQuery(originalQuery); // Because the query member has changed state - cache.put(queryKey,result); - } - return result; - } - -} diff --git a/container-search/src/test/java/com/yahoo/prelude/cache/test/CacheTestCase.java b/container-search/src/test/java/com/yahoo/prelude/cache/test/CacheTestCase.java deleted file mode 100644 index 5d7048f05ea..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/cache/test/CacheTestCase.java +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.prelude.cache.test; - -import com.yahoo.search.result.Hit; -import com.yahoo.search.Query; -import com.yahoo.search.Result; -import com.yahoo.statistics.Statistics; -import com.yahoo.prelude.cache.Cache; -import com.yahoo.prelude.cache.QueryCacheKey; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -@SuppressWarnings({"rawtypes", "unchecked"}) -public class CacheTestCase { - - private Result getSomeResult(Query q, String id) { - Result r = new Result(q); - r.hits().add(new Hit(id, 10)); - return r; - } - - @Test - public void testBasicGet() { - Cache<QueryCacheKey, Result> cache=new Cache<>(100*1024,3600, 100000, Statistics.nullImplementation); - Query q = new Query("/std_xmls_a00?hits=5&offset=5&query=flowers+shop&tracelevel=4&objid=ffffffffffffffff"); - Query q2 = new Query("/std_xmls_a00?hits=5&offset=5&query=flowers+shop&tracelevel=4&objid=ffffffffffffffff"); - QueryCacheKey qk = new QueryCacheKey(q); - QueryCacheKey qk2 = new QueryCacheKey(q2); - Result r = getSomeResult(q, "foo"); - Result r2 = getSomeResult(q, "bar"); - assertNull(cache.get(qk)); - cache.put(qk, r); - assertNotNull(cache.get(qk)); - assertEquals(cache.get(qk), r); - cache.put(qk2, r); - assertEquals(cache.get(qk2), r); - cache.put(qk, r2); - assertEquals(cache.get(qk), r2); - } - - @Test - public void testPutTooLarge() { - byte[] tenKB = new byte[10*1024]; - for (int i = 0 ; i <10*1024 ; i++) { - tenKB[i]=127; - } - byte[] sevenKB = new byte[7*1024]; - for (int i = 0 ; i <7*1024 ; i++) { - sevenKB[i]=127; - } - Cache cache=new Cache(9*1024,3600, 100*1024, Statistics.nullImplementation); // 9 KB - assertFalse(cache.put("foo", tenKB)); - assertTrue(cache.put("foo", sevenKB)); - assertEquals(cache.get("foo"), sevenKB); - } - - @Test - public void testInvalidate() { - byte[] tenKB = new byte[10*1024]; - for (int i = 0 ; i <10*1024 ; i++) { - tenKB[i]=127; - } - byte[] sevenKB = new byte[7*1024]; - for (int i = 0 ; i <7*1024 ; i++) { - sevenKB[i]=127; - } - Cache cache=new Cache(11*1024,3600, 100*1024, Statistics.nullImplementation); // 11 KB - assertTrue(cache.put("foo", sevenKB)); - assertTrue(cache.put("bar", tenKB)); - assertNull(cache.get("foo")); - assertEquals(cache.get("bar"), tenKB); - } - - @Test - public void testInvalidateLRU() { - Cache cache=new Cache(10*1024,3600, 100*1024, Statistics.nullImplementation); // 10 MB - byte[] fiveKB = new byte[5*1024]; - for (int i = 0 ; i <5*1024 ; i++) { - fiveKB[i]=127; - } - - byte[] twoKB = new byte[2*1024]; - for (int i = 0 ; i <2*1024 ; i++) { - twoKB[i]=127; - } - - byte[] fourKB = new byte[4*1024]; - for (int i = 0 ; i <4*1024 ; i++) { - fourKB[i]=127; - } - assertTrue(cache.put("five", fiveKB)); - assertTrue(cache.put("two", twoKB)); - Object dummy = cache.get("five"); // Makes two LRU - assertEquals(dummy, fiveKB); - assertTrue(cache.put("four", fourKB)); - assertNull(cache.get("two")); - assertEquals(cache.get("five"), fiveKB); - assertEquals(cache.get("four"), fourKB); - - // Same, without the access, just to check - cache=new Cache(10*1024,3600, 100*1024, Statistics.nullImplementation); // 10 KB - assertTrue(cache.put("five", fiveKB)); - assertTrue(cache.put("two", twoKB)); - assertTrue(cache.put("four", fourKB)); - assertEquals(cache.get("two"), twoKB); - assertNull(cache.get("five")); - assertEquals(cache.get("four"), fourKB); - } - - @Test - public void testPutSameKey() { - Cache cache=new Cache(10*1024,3600, 100*1024, Statistics.nullImplementation); // 10 MB - byte[] fiveKB = new byte[5*1024]; - for (int i = 0 ; i <5*1024 ; i++) { - fiveKB[i]=127; - } - - byte[] twoKB = new byte[2*1024]; - for (int i = 0 ; i <2*1024 ; i++) { - twoKB[i]=127; - } - - byte[] fourKB = new byte[4*1024]; - for (int i = 0 ; i <4*1024 ; i++) { - fourKB[i]=127; - } - assertTrue(cache.put("five", fiveKB)); - assertTrue(cache.put("two", twoKB)); - assertEquals(cache.get("two"), twoKB); - assertEquals(cache.get("five"), fiveKB); - assertTrue(cache.put("five", twoKB)); - assertEquals(cache.get("five"), twoKB); - assertEquals(cache.get("two"), twoKB); - } - - @Test - public void testExpire() throws InterruptedException { - Cache cache=new Cache(10*1024,50, 10000, Statistics.nullImplementation); // 10 KB, 50ms expire - boolean success = false; - for (int tries = 0; tries < 10; tries++) { - long before = System.currentTimeMillis(); - cache.put("foo", "bar"); - cache.put("hey", "ho"); - Object got1 = cache.get("foo"); - Object got2 = cache.get("hey"); - long after = System.currentTimeMillis(); - if (after - before < 50) { - assertEquals(got1, "bar"); - assertEquals(got2, "ho"); - success = true; - break; - } - } - assertTrue(success); - Thread.sleep(100); - assertNull(cache.get("foo")); - assertNull(cache.get("hey")); - } - - @Test - public void testInsertSame() { - Cache cache=new Cache(100*1024,500, 100000, Statistics.nullImplementation); // 100 KB, .5 sec expire - Query q = new Query("/std_xmls_a00?hits=5&offset=5&query=flowers+shop&tracelevel=4&objid=ffffffffffffffff"); - Result r = getSomeResult(q, "foo"); - QueryCacheKey k = new QueryCacheKey(q); - cache.put(k, r); - assertEquals(1, cache.size()); - q = new Query("/std_xmls_a00?hits=5&offset=5&query=flowers+shop&tracelevel=4&objid=ffffffffffffffff"); - k = new QueryCacheKey(q); - cache.put(k, r); - assertEquals(1, cache.size()); - } - - @Test - public void testMaxSize() { - Cache cache=new Cache(20*1024,500, 3*1024, Statistics.nullImplementation); - byte[] fourKB = new byte[4*1024]; - for (int i = 0 ; i <4*1024 ; i++) { - fourKB[i]=127; - } - byte[] twoKB = new byte[2*1024]; - for (int i = 0 ; i <2*1024 ; i++) { - twoKB[i]=127; - } - assertFalse(cache.put("four", fourKB)); - assertTrue(cache.put("two", twoKB)); - assertNull(cache.get("four")); - assertNotNull(cache.get("two")); - } - -} diff --git a/container-search/src/test/java/com/yahoo/prelude/searcher/test/CachingSearcherTestCase.java b/container-search/src/test/java/com/yahoo/prelude/searcher/test/CachingSearcherTestCase.java deleted file mode 100644 index 570402fdaae..00000000000 --- a/container-search/src/test/java/com/yahoo/prelude/searcher/test/CachingSearcherTestCase.java +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.prelude.searcher.test; - -import static org.junit.Assert.*; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.yahoo.component.chain.Chain; -import com.yahoo.container.QrSearchersConfig; -import com.yahoo.prelude.fastsearch.FastHit; -import com.yahoo.prelude.searcher.CachingSearcher; -import com.yahoo.prelude.searcher.DocumentSourceSearcher; -import com.yahoo.search.Query; -import com.yahoo.search.Result; -import com.yahoo.search.Searcher; -import com.yahoo.search.searchchain.Execution; -import com.yahoo.statistics.Statistics; - -/** - * Check CachingSearcher basically works. - * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> - */ -public class CachingSearcherTestCase { - - private static final String QUERY_A_NOCACHEWRITE_TRUE = "/?query=a&nocachewrite=true"; - private static final String QUERY_A = "/?query=a"; - private Chain<Searcher> searchChain; - private DocumentSourceSearcher hits; - - @Before - public void setUp() throws Exception { - hits = new DocumentSourceSearcher(); - QrSearchersConfig config = new QrSearchersConfig( - new QrSearchersConfig.Builder() - .com(new QrSearchersConfig.Com.Builder() - .yahoo(new QrSearchersConfig.Com.Yahoo.Builder() - .prelude(new QrSearchersConfig.Com.Yahoo.Prelude.Builder() - .searcher(new QrSearchersConfig.Com.Yahoo.Prelude.Searcher.Builder() - .CachingSearcher( - new QrSearchersConfig.Com.Yahoo.Prelude.Searcher.CachingSearcher.Builder() - .cachesizemegabytes(10) - .maxentrysizebytes(5 * 1024 * 1024) - .timetoliveseconds(86400))))))); - CachingSearcher cache = new CachingSearcher(config, Statistics.nullImplementation); - searchChain = new Chain<>(cache, hits); - } - - public void readyResult(String q) { - Query query = new Query(q); - Result r = new Result(query); - for (int i = 0; i < 10; ++i) { - FastHit h = new FastHit("http://127.0.0.1/" + i, - 1.0 - ((double) i) / 10.0); - r.hits().add(h); - } - hits.addResultSet(query, r); - } - - @After - public void tearDown() throws Exception { - } - - @Test - public final void test() { - readyResult(QUERY_A); - Execution e = new Execution(searchChain, Execution.Context.createContextStub()); - Result r = e.search(new Query(QUERY_A)); - assertEquals(10, r.hits().getConcreteSize()); - Query query = new Query(QUERY_A); - Result expected = new Result(query); - hits.addResultSet(query, expected); - e = new Execution(searchChain, Execution.Context.createContextStub()); - r = e.search(new Query(QUERY_A)); - assertEquals(10, r.hits().getConcreteSize()); - assertEquals(1, hits.getQueryCount()); - } - - @Test - public final void testNoCacheWrite() { - readyResult(QUERY_A_NOCACHEWRITE_TRUE); - Execution e = new Execution(searchChain, Execution.Context.createContextStub()); - Result r = e.search(new Query(QUERY_A_NOCACHEWRITE_TRUE)); - assertEquals(10, r.hits().getConcreteSize()); - Query query = new Query(QUERY_A_NOCACHEWRITE_TRUE); - Result expected = new Result(query); - hits.addResultSet(query, expected); - e = new Execution(searchChain, Execution.Context.createContextStub()); - r = e.search(new Query(QUERY_A_NOCACHEWRITE_TRUE)); - assertEquals(0, r.hits().getConcreteSize()); - assertEquals(2, hits.getQueryCount()); - } - -} |