This is an automated email from the ASF dual-hosted git repository.

bereng pushed a commit to branch cassandra-4.0
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/cassandra-4.0 by this push:
     new ff54fd5ffd CASSANDRA-19986 Prepared statements cache computation 
improvements
ff54fd5ffd is described below

commit ff54fd5ffd03846326862951e2a6de9b52de01f6
Author: Bereng <[email protected]>
AuthorDate: Mon Oct 14 10:34:21 2024 +0200

    CASSANDRA-19986 Prepared statements cache computation improvements
    
    patch by Berenguer Blasi; reviewed by Maxwell Guo, Stefan Miklosovic for 
CASSANDRA-19986
---
 .../org/apache/cassandra/cql3/QueryHandler.java    |  3 +++
 .../org/apache/cassandra/cql3/QueryProcessor.java  | 30 +++++++++++++++-------
 src/java/org/apache/cassandra/utils/MD5Digest.java |  6 +++++
 .../cassandra/cql3/PstmtPersistenceTest.java       |  4 ++-
 4 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/src/java/org/apache/cassandra/cql3/QueryHandler.java 
b/src/java/org/apache/cassandra/cql3/QueryHandler.java
index 8be7184d44..e0480a6e4b 100644
--- a/src/java/org/apache/cassandra/cql3/QueryHandler.java
+++ b/src/java/org/apache/cassandra/cql3/QueryHandler.java
@@ -58,6 +58,9 @@ public interface QueryHandler
 
     public static class Prepared
     {
+        // CASSANDRA-19986 Precomputed size might be available
+        public volatile int pstmntSize = -1;
+
         public final CQLStatement statement;
 
         public final MD5Digest resultMetadataId;
diff --git a/src/java/org/apache/cassandra/cql3/QueryProcessor.java 
b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
index 66ce2ef5a6..910f8c79f8 100644
--- a/src/java/org/apache/cassandra/cql3/QueryProcessor.java
+++ b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
@@ -93,7 +93,7 @@ public class QueryProcessor implements QueryHandler
         preparedStatements = Caffeine.newBuilder()
                              .executor(MoreExecutors.directExecutor())
                              
.maximumWeight(capacityToBytes(DatabaseDescriptor.getPreparedStatementsCacheSizeMB()))
-                             .weigher(QueryProcessor::measure)
+                             
.weigher(QueryProcessor::getSizeOfPreparedStatementForCache)
                              .removalListener((key, prepared, cause) -> {
                                  MD5Digest md5Digest = (MD5Digest) key;
                                  if (cause.wasEvicted())
@@ -411,10 +411,14 @@ public class QueryProcessor implements QueryHandler
         CQLStatement statement = raw.prepare(clientState);
         statement.validate(clientState);
 
+        Prepared res;
         if (isInternal)
-            return new Prepared(statement, "", fullyQualified, keyspace);
+            res = new Prepared(statement, "", fullyQualified, keyspace);
         else
-            return new Prepared(statement, query, fullyQualified, keyspace);
+            res = new Prepared(statement, query, fullyQualified, keyspace);
+        res.pstmntSize = measurePstmnt(res);
+
+        return res;
     }
 
     public static UntypedResultSet executeInternal(String query, Object... 
values)
@@ -674,14 +678,14 @@ public class QueryProcessor implements QueryHandler
     {
         // Concatenate the current keyspace so we don't mix prepared 
statements between keyspace (#5352).
         // (if the keyspace is null, queryString has to have a fully-qualified 
keyspace so it's fine.
-        long statementSize = ObjectSizes.measureDeep(prepared.statement);
+        MD5Digest statementId = computeId(queryString, keyspace);
         // don't execute the statement if it's bigger than the allowed 
threshold
-        if (statementSize > 
capacityToBytes(DatabaseDescriptor.getPreparedStatementsCacheSizeMB()))
+        if (getSizeOfPreparedStatementForCache(statementId, prepared) > 
capacityToBytes(DatabaseDescriptor.getPreparedStatementsCacheSizeMB()))
             throw new InvalidRequestException(String.format("Prepared 
statement of size %d bytes is larger than allowed maximum of %d MB: %s...",
-                                                            statementSize,
+                                                            
prepared.pstmntSize,
                                                             
DatabaseDescriptor.getPreparedStatementsCacheSizeMB(),
                                                             
queryString.substring(0, 200)));
-        MD5Digest statementId = computeId(queryString, keyspace);
+
         Prepared previous = preparedStatements.get(statementId, (ignored_) -> 
prepared);
         if (previous == prepared)
             SystemKeyspace.writePreparedStatement(keyspace, statementId, 
queryString);
@@ -797,9 +801,17 @@ public class QueryProcessor implements QueryHandler
         }
     }
 
-    private static int measure(Object key, Prepared value)
+    private static int measurePstmnt(Prepared value)
     {
-        return Ints.checkedCast(ObjectSizes.measureDeep(key) + 
ObjectSizes.measureDeep(value));
+        return Ints.checkedCast(ObjectSizes.measureDeep(value));
+    }
+
+    private static int getSizeOfPreparedStatementForCache(MD5Digest key, 
Prepared value)
+    {
+        if (value.pstmntSize < 0)
+            throw new IllegalStateException("Precomputed prepared statement 
size not available");
+
+        return Ints.checkedCast(key.size() + value.pstmntSize);
     }
 
     /**
diff --git a/src/java/org/apache/cassandra/utils/MD5Digest.java 
b/src/java/org/apache/cassandra/utils/MD5Digest.java
index d5429918d5..1f3d0a52d8 100644
--- a/src/java/org/apache/cassandra/utils/MD5Digest.java
+++ b/src/java/org/apache/cassandra/utils/MD5Digest.java
@@ -113,4 +113,10 @@ public class MD5Digest
     {
         return localMD5Digest.get();
     }
+
+    public int size()
+    {
+        return bytes.length + //bytes
+               4; // int hashCode
+    }
 }
diff --git a/test/unit/org/apache/cassandra/cql3/PstmtPersistenceTest.java 
b/test/unit/org/apache/cassandra/cql3/PstmtPersistenceTest.java
index 8e3f7f4c3e..c0d4994262 100644
--- a/test/unit/org/apache/cassandra/cql3/PstmtPersistenceTest.java
+++ b/test/unit/org/apache/cassandra/cql3/PstmtPersistenceTest.java
@@ -21,7 +21,9 @@ import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
+import org.apache.cassandra.Util;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -153,7 +155,7 @@ public class PstmtPersistenceTest extends CQLTester
                     prepareStatement("INSERT INTO %s (key, val) VALUES (?, ?) 
USING TIMESTAMP " + cnt2, clientState);
 
                 // each new prepared statement should have caused an eviction
-                assertEquals("eviction count didn't increase by the expected 
number", numberOfEvictedStatements(), 10);
+                Util.spinAssertEquals("eviction count didn't increase by the 
expected number", 10L, this::numberOfEvictedStatements, 5, TimeUnit.SECONDS);
                 assertEquals("Number of statements in table and in cache don't 
match", numberOfStatementsInMemory(), numberOfStatementsOnDisk());
 
                 return;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to