diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2017-11-06 12:46:27 +0100 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2017-11-06 12:46:27 +0100 |
commit | 89f857807f8244dd29abf4ef02be17b2ba3e2501 (patch) | |
tree | 8e388bd13a7abd7416c712d96d8b98a3b8340b48 /container-search | |
parent | 0df471cf727460575258c9af3e42be4ddbb344f3 (diff) |
1 - Ignores the session key when creating the cache key.
2 - Fix an earlier bug due to variable header size in cache key generation.
Diffstat (limited to 'container-search')
4 files changed, 44 insertions, 17 deletions
diff --git a/container-search/src/main/java/com/yahoo/fs4/QueryPacket.java b/container-search/src/main/java/com/yahoo/fs4/QueryPacket.java index eb05bdc672c..69113f5e057 100644 --- a/container-search/src/main/java/com/yahoo/fs4/QueryPacket.java +++ b/container-search/src/main/java/com/yahoo/fs4/QueryPacket.java @@ -26,8 +26,12 @@ import java.util.List; */ public class QueryPacket extends Packet { - private Query query; + final private Query query; private QueryPacketData queryPacketData; + int sessionOffset = 0; // Start of sessionKey ignore section for cache key + int sessionSize = 0; // Length of sessionKey ignore section for cache key + int ignoreableOffset = 0; // Start of (hits/offset/timestamp) ignore section for cache key + int ignoreableSize = 0; // Length of (hits/offset/timestamp) ignore section for cache key private QueryPacket(Query query) { this.query = query; @@ -73,6 +77,9 @@ public class QueryPacket extends Packet { return new byte[0]; } + private int getSessionKeySkipLength() { + return (sessionSize > 0) ? sessionSize + 4 : 0; + } /** * Returns an opaque cache key for the query represented by this * (pre-serialized) packet. @@ -86,35 +93,41 @@ public class QueryPacket extends Packet { // need to fiddle with feature flags to handle a non-existing // summary class. - int skipOffset = 4; // offset of offset/hits/timestamp fields - int skipLength = 12; // length of offset/hits/timestamp fields byte[] utf8Summary = getSummaryClassAsUtf8(); - byte[] stripped = new byte[encodedBody.length - skipLength + utf8Summary.length + 1]; - - System.arraycopy(encodedBody, 0, stripped, 0, skipOffset); - System.arraycopy(utf8Summary, 0, stripped, skipOffset, utf8Summary.length); - stripped[skipOffset + utf8Summary.length] = 0; - System.arraycopy(encodedBody, skipOffset + skipLength, - stripped, skipOffset + utf8Summary.length + 1, - encodedBody.length - (skipOffset + skipLength)); + byte[] stripped = new byte[encodedBody.length - (ignoreableSize + getSessionKeySkipLength()) + utf8Summary.length + 1]; + + System.arraycopy(encodedBody, 0, stripped, 0, ignoreableOffset); + stripped[1] = (byte)(stripped[1] & 0x7f); // Ignor sessionKey feature flag + System.arraycopy(utf8Summary, 0, stripped, ignoreableOffset, utf8Summary.length); + stripped[ignoreableOffset + utf8Summary.length] = 0; + + // Copy part up to sessionKey + System.arraycopy(encodedBody, ignoreableOffset + ignoreableSize, + stripped, ignoreableOffset + utf8Summary.length + 1, + sessionOffset - (ignoreableOffset + ignoreableSize)); + // Copy part after sessionKey + System.arraycopy(encodedBody, sessionOffset + getSessionKeySkipLength(), + stripped, utf8Summary.length + 1 + (sessionOffset - ignoreableSize), + encodedBody.length - (sessionOffset + getSessionKeySkipLength())); return stripped; } public void encodeBody(ByteBuffer buffer) { queryPacketData = new QueryPacketData(); - int startOfFieldToSave; + final int relativeZero = buffer.position(); boolean sendSessionKey = query.getGroupingSessionCache() || query.getRanking().getQueryCache(); int featureFlag = getFeatureInt(sendSessionKey); buffer.putInt(featureFlag); + ignoreableOffset = buffer.position() - relativeZero; IntegerCompressor.putCompressedPositiveNumber(getOffset(), buffer); IntegerCompressor.putCompressedPositiveNumber(getHits(), buffer); // store the cutoff time in the tag object, and then do a similar Math.max there buffer.putInt(Math.max(50, (int)query.getTimeLeft())); buffer.putInt(getFlagInt()); - - startOfFieldToSave = buffer.position(); + ignoreableSize = buffer.position() - relativeZero - ignoreableOffset; + int startOfFieldToSave = buffer.position(); Item.putString(query.getRanking().getProfile(), buffer); queryPacketData.setRankProfile(buffer, startOfFieldToSave); @@ -147,8 +160,10 @@ public class QueryPacket extends Packet { buffer.put(blob); } + sessionOffset = buffer.position() - relativeZero; if (sendSessionKey) { Utf8String key = query.getSessionId(true).asUtf8String(); + sessionSize = key.getByteLength(); buffer.putInt(key.getByteLength()); buffer.put(key.getBytes()); } diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/CacheKey.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/CacheKey.java index 725ef89eadb..6af0d181695 100644 --- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/CacheKey.java +++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/CacheKey.java @@ -14,8 +14,8 @@ import com.yahoo.fs4.QueryPacket; * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> */ public class CacheKey { - private int hashCode; - private byte[] serialized = null; + final private int hashCode; + final private byte[] serialized; /** * Create a cache key from the query packet. diff --git a/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/CacheKeyTestCase.java b/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/CacheKeyTestCase.java index d87d32fa5cf..e7ab1cc137a 100644 --- a/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/CacheKeyTestCase.java +++ b/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/CacheKeyTestCase.java @@ -26,4 +26,16 @@ public class CacheKeyTestCase extends junit.framework.TestCase { assertEquals(k1, k2); assertEquals(k1.hashCode(), k2.hashCode()); } + + public void testSessionKeyIgnored() { + Query a = new Query("/?query=abcd"); + QueryPacket ap = QueryPacket.create(a); + Query b = new Query("/?query=abcd&ranking.queryCache=true"); + QueryPacket bp = QueryPacket.create(b); + CacheKey ak = new CacheKey(ap); + CacheKey bk = new CacheKey(bp); + assertEquals(ak, bk); + assertEquals(ak.hashCode(), bk.hashCode()); + assertFalse(ap.getQueryPacketData().equals(bp.getQueryPacketData())); + } } diff --git a/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/PacketCacheTestCase.java b/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/PacketCacheTestCase.java index 257dfcc456d..e81a1ae2864 100644 --- a/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/PacketCacheTestCase.java +++ b/container-search/src/test/java/com/yahoo/prelude/fastsearch/test/PacketCacheTestCase.java @@ -50,7 +50,7 @@ public class PacketCacheTestCase extends junit.framework.TestCase { cache.setMaxCacheItemPercentage(50); - final int keysz = 30; + final int keysz = 32; // first control assumptions assertEquals(keysz, key1.byteSize()); |