mike-tr-adamson commented on code in PR #2645:
URL: https://github.com/apache/cassandra/pull/2645#discussion_r1312826227
##########
src/java/org/apache/cassandra/index/sai/utils/PrimaryKey.java:
##########
@@ -74,66 +100,103 @@ public PrimaryKey createPartitionKeyOnly(DecoratedKey
partitionKey)
*/
public PrimaryKey create(DecoratedKey partitionKey, Clustering<?>
clustering)
{
+ assert clusteringComparator.size() > 0 : "Cannot create a wide
primary key for a table without clustering columns";
assert partitionKey != null : "Cannot create a primary key with a
null partition key";
assert clustering != null : "Cannot create a primary key with a
null clustering";
- return new ImmutablePrimaryKey(partitionKey, clustering);
+ return clustering == Clustering.STATIC_CLUSTERING ? new
StaticPrimaryKey(partitionKey) : new WidePrimaryKey(partitionKey, clustering);
+ }
+
+ /**
+ * Create a {@link PrimaryKey} from a {@link ByteSource}. This should
only be used with {@link ByteSource} instances
+ * created by calls to {@link PrimaryKey#asComparableBytes(Version)}.
+ */
+ public PrimaryKey fromComparableBytes(ByteSource byteSource)
+ {
+ if (clusteringComparator.size() > 0)
+ {
+ ByteSource.Peekable peekable = ByteSource.peekable(byteSource);
+ DecoratedKey partitionKey =
partitionKeyFromComparableBytes(ByteSourceInverse.nextComponentSource(peekable));
+ Clustering<?> clustering =
clusteringFromByteComparable(ByteSourceInverse.nextComponentSource(peekable));
+ return create(partitionKey, clustering);
+ }
+ else
+ {
+ return
createPartitionKeyOnly(partitionKeyFromComparableBytes(byteSource));
+ }
+ }
+
+ /**
+ * Create a {@link DecoratedKey} from a {@link ByteSource}. This is a
separate method because of it's use by
+ * the {@link org.apache.cassandra.index.sai.disk.PrimaryKeyMap}
implementations to create partition keys.
+ */
+ public DecoratedKey partitionKeyFromComparableBytes(ByteSource
byteSource)
+ {
+ ByteBuffer decoratedKey =
ByteBuffer.wrap(ByteSourceInverse.getUnescapedBytes(ByteSource.peekable(byteSource)));
+ return new BufferDecoratedKey(partitioner.getToken(decoratedKey),
decoratedKey);
}
- public PrimaryKey createDeferred(Token token, Supplier<PrimaryKey>
primaryKeySupplier)
+ /**
+ * Create a {@link Clustering} from a {@link ByteSource}. This is a
separate method because of its use by
+ * the {@link
org.apache.cassandra.index.sai.disk.v1.WidePrimaryKeyMap} to create its
clustering keys.
+ */
+ public Clustering<?> clusteringFromByteComparable(ByteSource
byteSource)
{
- assert token != null : "Cannot create a deferred primary key with
a null token";
- assert primaryKeySupplier != null : "Cannot create a deferred
primary key with a null key supplier";
+ Clustering<?> clustering =
clusteringComparator.clusteringFromByteComparable(ByteBufferAccessor.instance,
v -> byteSource);
- return new MutablePrimaryKey(token, primaryKeySupplier);
+ // Clustering is null for static rows
+ return (clustering == null) ? Clustering.STATIC_CLUSTERING :
clustering;
}
- abstract class AbstractPrimaryKey implements PrimaryKey
+ class TokenOnlyPrimaryKey implements PrimaryKey
{
+ protected final Token token;
+
+ TokenOnlyPrimaryKey(Token token)
+ {
+ this.token = token;
+ }
+
@Override
- @SuppressWarnings("ConstantConditions")
- public ByteSource asComparableBytes(ByteComparable.Version version)
+ public Kind kind()
{
- ByteSource keyComparable =
ByteSource.of(partitionKey().getKey(), version);
- if (clusteringComparator.size() == 0)
- return keyComparable;
- // It is important that the
ClusteringComparator.asBytesComparable method is used
- // to maintain the correct clustering sort order
- ByteSource clusteringComparable = clustering() == null ||
- clustering().isEmpty() ? null
- :
clusteringComparator.asByteComparable(clustering())
-
.asComparableBytes(version);
- return ByteSource.withTerminator(version ==
ByteComparable.Version.LEGACY ? ByteSource.END_OF_STREAM
-
: ByteSource.TERMINATOR,
- keyComparable,
- clusteringComparable);
+ return Kind.Token;
}
@Override
- @SuppressWarnings("ConstantConditions")
- public int compareTo(PrimaryKey o)
+ public Token token()
{
- int cmp = token().compareTo(o.token());
+ return token;
+ }
- // If the tokens don't match then we don't need to compare any
more of the key.
- // Otherwise, if either of the keys are token only we can only
compare tokens
- if ((cmp != 0) || isTokenOnly() || o.isTokenOnly())
- return cmp;
+ @Override
+ public DecoratedKey partitionKey()
+ {
+ throw new UnsupportedOperationException();
+ }
- // Next compare the partition keys. If they are not equal or
- // this is a single row partition key or there are no
- // clusterings then we can return the result of this without
- // needing to compare the clusterings
- cmp = partitionKey().compareTo(o.partitionKey());
- if (cmp != 0 || hasEmptyClustering() || o.hasEmptyClustering())
- return cmp;
- return clusteringComparator.compare(clustering(),
o.clustering());
+ @Override
+ public Clustering<?> clustering()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ByteSource asComparableBytes(Version version)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int compareTo(PrimaryKey o)
+ {
+ return token().compareTo(o.token());
}
@Override
public int hashCode()
{
- return Objects.hash(token(), partitionKey(), clustering(),
clusteringComparator);
+ return Objects.hash(token(), 16, 32, clusteringComparator);
Review Comment:
Ah, I think that got left in. I added them to try and avoid hash collisions
but I'm not sure that is possible here or even needed. AFAICT token only keys
are only used for comparison.
I have removed these and replaced the magic number in the `SkinnyPrimaryKey`
with `Clustering.EMPTY`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]