This is an automated email from the ASF dual-hosted git repository. adelapena pushed a commit to branch cep-7-sai in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit a47baeb341a29b69bf0cb35912386bf6a82ed1bf Author: Zhao Yang <zhaoyangsingap...@gmail.com> AuthorDate: Wed Jun 14 08:55:01 2023 +0800 fix Segment#intersects to compare bound instead of token --- .../index/sai/disk/v1/segment/Segment.java | 19 ++++------ .../index/sai/cql/TokenRangeReadTest.java | 44 ++++++++++++++++++++++ .../cassandra/index/sai/disk/v1/SegmentTest.java | 16 ++++---- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/java/org/apache/cassandra/index/sai/disk/v1/segment/Segment.java b/src/java/org/apache/cassandra/index/sai/disk/v1/segment/Segment.java index a36a3504dc..5f108a638c 100644 --- a/src/java/org/apache/cassandra/index/sai/disk/v1/segment/Segment.java +++ b/src/java/org/apache/cassandra/index/sai/disk/v1/segment/Segment.java @@ -42,9 +42,7 @@ import org.apache.cassandra.io.util.FileUtils; */ public class Segment implements Closeable { - private final Token minKey; private final Token.KeyBound minKeyBound; - private final Token maxKey; private final Token.KeyBound maxKeyBound; // per sstable @@ -56,10 +54,8 @@ public class Segment implements Closeable public Segment(IndexContext indexContext, SSTableContext sstableContext, PerColumnIndexFiles indexFiles, SegmentMetadata metadata) throws IOException { - this.minKey = metadata.minKey.token(); - this.minKeyBound = minKey.minKeyBound(); - this.maxKey = metadata.maxKey.token(); - this.maxKeyBound = maxKey.maxKeyBound(); + this.minKeyBound = metadata.minKey.token().minKeyBound(); + this.maxKeyBound = metadata.maxKey.token().maxKeyBound(); this.primaryKeyMapFactory = sstableContext.primaryKeyMapFactory; this.metadata = metadata; @@ -72,9 +68,7 @@ public class Segment implements Closeable { this.primaryKeyMapFactory = null; this.metadata = null; - this.minKey = minKey; this.minKeyBound = minKey.minKeyBound(); - this.maxKey = maxKey; this.maxKeyBound = maxKey.maxKeyBound(); this.index = null; } @@ -87,14 +81,15 @@ public class Segment implements Closeable if (keyRange instanceof Range && ((Range<?>)keyRange).isWrapAround()) return keyRange.contains(minKeyBound) || keyRange.contains(maxKeyBound); - int cmp = keyRange.right.getToken().compareTo(minKey); + int cmp = keyRange.right.compareTo(minKeyBound); // if right is minimum, it means right is the max token and bigger than maxKey. - // if right bound is less than minKey, no intersection + // if right bound is less than minKeyBound, no intersection if (!keyRange.right.isMinimum() && (!keyRange.inclusiveRight() && cmp == 0 || cmp < 0)) return false; - // if left bound is bigger than maxKey, no intersection - return keyRange.isStartInclusive() || keyRange.left.getToken().compareTo(maxKey) < 0; + cmp = keyRange.left.compareTo(maxKeyBound); + // if left bound is bigger than maxKeyBound, no intersection + return (keyRange.isStartInclusive() || cmp != 0) && cmp <= 0; } public long indexFileCacheSize() diff --git a/test/unit/org/apache/cassandra/index/sai/cql/TokenRangeReadTest.java b/test/unit/org/apache/cassandra/index/sai/cql/TokenRangeReadTest.java new file mode 100644 index 0000000000..67a030ef9f --- /dev/null +++ b/test/unit/org/apache/cassandra/index/sai/cql/TokenRangeReadTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.cassandra.index.sai.cql; + +import org.junit.Test; + +import org.apache.cassandra.index.sai.SAITester; +import org.apache.cassandra.index.sai.StorageAttachedIndex; + +import static java.lang.String.format; + +public class TokenRangeReadTest extends SAITester +{ + @Test + public void testTokenRangeRead() throws Throwable + { + createTable("CREATE TABLE %s (k1 int, v1 text, PRIMARY KEY (k1))"); + createIndex(format("CREATE CUSTOM INDEX ON %%s(v1) USING '%s'", StorageAttachedIndex.class.getName())); + + execute("INSERT INTO %S(k1, v1) values(1, '1')"); + + beforeAndAfterFlush(() -> { + assertRows(execute("SELECT * FROM %s WHERE v1 = '1'"), row(1, "1")); + assertRows(execute("SELECT * FROM %s WHERE token(k1) >= token(1) AND token(k1) <= token(1)"), row(1, "1")); + assertRows(execute("SELECT * FROM %s WHERE token(k1) >= token(1) AND token(k1) <= token(1) AND v1 = '1'"), row(1, "1")); + }); + } +} diff --git a/test/unit/org/apache/cassandra/index/sai/disk/v1/SegmentTest.java b/test/unit/org/apache/cassandra/index/sai/disk/v1/SegmentTest.java index b107561687..70bf70e238 100644 --- a/test/unit/org/apache/cassandra/index/sai/disk/v1/SegmentTest.java +++ b/test/unit/org/apache/cassandra/index/sai/disk/v1/SegmentTest.java @@ -25,8 +25,6 @@ import org.junit.BeforeClass; import org.junit.Test; import org.apache.cassandra.config.DatabaseDescriptor; -import org.apache.cassandra.db.BufferDecoratedKey; -import org.apache.cassandra.db.DecoratedKey; import org.apache.cassandra.db.PartitionPosition; import org.apache.cassandra.dht.AbstractBounds; import org.apache.cassandra.dht.Bounds; @@ -35,7 +33,6 @@ import org.apache.cassandra.dht.Murmur3Partitioner; import org.apache.cassandra.dht.Range; import org.apache.cassandra.dht.Token; import org.apache.cassandra.index.sai.disk.v1.segment.Segment; -import org.apache.cassandra.utils.ByteBufferUtil; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -70,8 +67,13 @@ public class SegmentTest assertNoOverlapping(seg(tokens.get(5), tokens.get(6)), wrapAround); // exclusive intersection + assertFalse(inclusiveRight(tokens.get(0), tokens.get(1)).contains(tokens.get(0).maxKeyBound())); assertNoOverlapping(seg(min, tokens.get(0)), inclusiveRight(tokens.get(0), tokens.get(1))); + + assertFalse(exclusive(tokens.get(0), tokens.get(1)).contains(tokens.get(1).minKeyBound())); assertNoOverlapping(seg(tokens.get(1), tokens.get(2)), exclusive(tokens.get(0), tokens.get(1))); + + assertFalse(inclusiveLeft(tokens.get(0), tokens.get(3)).contains(tokens.get(3).minKeyBound())); assertNoOverlapping(seg(tokens.get(3), max), inclusiveLeft(tokens.get(0), tokens.get(3))); // disjoint @@ -155,11 +157,7 @@ public class SegmentTest private static AbstractBounds<PartitionPosition> keyRange(Token left, boolean inclusiveLeft, Token right, boolean inclusiveRight) { - return Bounds.bounds(key(left), inclusiveLeft, key(right), inclusiveRight); - } - - private static DecoratedKey key(Token token) - { - return new BufferDecoratedKey(token, ByteBufferUtil.bytes(0)); + return Bounds.bounds(inclusiveLeft ? left.minKeyBound() : left.maxKeyBound(), inclusiveLeft, + inclusiveRight ? right.maxKeyBound() : right.minKeyBound(), inclusiveRight); } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org