Copilot commented on code in PR #23999:
URL: https://github.com/apache/kafka/pull/23999#discussion_r4424664041


##########
streams/src/main/java/org/apache/kafka/streams/state/internals/RocksDBTransactionBuffer.java:
##########
@@ -286,21 +294,58 @@ private ManagedKeyValueIterator<Bytes, byte[]> 
newBaseIterator(final ColumnFamil
         return new RangeTombstoneFilterIterator(iter, rangeTombstones);
     }
 
+    @Override
+    void prepareFlush() {
+        preparedBatch = new WriteBatch();
+        try {
+            for (final PendingRangeDelete delete : pendingRangeDeletes) {
+                preparedBatch.deleteRange(delete.cf, delete.from.get(), 
delete.to.get());
+            }
+            addPoints(cfHandle, pendingWrites);
+            for (final Map.Entry<ColumnFamilyHandle, NavigableMap<Bytes, 
Optional<byte[]>>> cfWrites : otherCfWrites.entrySet()) {
+                addPoints(cfWrites.getKey(), cfWrites.getValue());
+            }
+        } catch (final RocksDBException e) {
+            preparedBatch.close();
+            preparedBatch = null;
+            throw new ProcessorStateException("Error preparing commit batch 
for store " + storeName, e);
+        }
+    }
+
+    private void addPoints(final ColumnFamilyHandle cf,
+                           final NavigableMap<Bytes, Optional<byte[]>> writes) 
throws RocksDBException {
+        for (final Map.Entry<Bytes, Optional<byte[]>> entry : 
writes.entrySet()) {
+            if (entry.getValue().isPresent()) {
+                preparedBatch.put(cf, entry.getKey().get(), 
entry.getValue().get());

Review Comment:
   With `Serdes.ByteArray()` and caching disabled, modifying an input array or 
a value returned by a staged read before commit now changes what RocksDB 
persists without another `put`; the previous WriteBatch captured the bytes when 
staged. Snapshot keys, values, and range endpoints when staging, and keep reads 
and iterators from exposing those snapshots.



##########
streams/src/main/java/org/apache/kafka/streams/state/internals/AbstractTransactionBuffer.java:
##########
@@ -100,9 +103,11 @@ abstract ManagedKeyValueIterator<K, byte[]> 
newBaseSnapshotIterator(K from, K to
     public void stage(final K key, final byte[] value) {
         snapshotLock.writeLock().lock();
         try {
-            pendingWrites.put(key, Optional.ofNullable(value));
+            final Optional<byte[]> previous = pendingWrites.put(key, 
Optional.ofNullable(value));
+            if (previous != null) {
+                pendingWritesBytes -= estimateKeySize(key) + previous.map(v -> 
v.length).orElse(0);
+            }
             pendingWritesBytes += estimateKeySize(key) + (value != null ? 
value.length : 0);

Review Comment:
   Counting only key/value bytes makes an empty-key write with an empty value 
or tombstone report zero, so a write from `Processor.init()` can fail to set 
`commitNeeded` in `StreamTask.completeRestoration()` and remain uncommitted 
while the task is idle. For short keys and tombstones, this also understates 
the native batch size used to reserve commit memory in both stream and global 
threads. Include conservative batch-record overhead in the accounting, covering 
primary and other column-family writes, range deletes, and the header of a 
nonempty batch.



-- 
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]

Reply via email to