diff options
Diffstat (limited to 'container-search/src/main/java/com/yahoo/prelude/searcher/CachingSearcher.java')
-rw-r--r-- | container-search/src/main/java/com/yahoo/prelude/searcher/CachingSearcher.java | 77 |
1 files changed, 77 insertions, 0 deletions
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 new file mode 100644 index 00000000000..1152246a32e --- /dev/null +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/CachingSearcher.java @@ -0,0 +1,77 @@ +// Copyright 2016 Yahoo Inc. 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; + } + +} |