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

brandonwilliams 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 2842c01ce7 Fix BTree.FastBuilder.reset() and test
2842c01ce7 is described below

commit 2842c01ce7eaeb6e72a63435075cc282a1cdd2db
Author: Benedict Elliott Smith <bened...@apache.org>
AuthorDate: Fri Aug 16 07:54:38 2024 +0100

    Fix BTree.FastBuilder.reset() and test
    
    Patch by benedict; reviewed by blambov for CASSANDRA-19785
---
 CHANGES.txt                                        |  1 +
 .../org/apache/cassandra/utils/btree/BTree.java    | 40 +++++++++++++++++-----
 .../org/apache/cassandra/utils/LongBTreeTest.java  |  3 ++
 3 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index a0b5553a03..8511f34eae 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 4.0.14
+ * Fix memory leak in BTree.FastBuilder (CASSANDRA-19785)
  * Fix millisecond and microsecond precision for commit log replay 
(CASSANDRA-19448)
  * Improve accuracy of memtable heap usage tracking (CASSANDRA-17298)
  * Fix rendering UNSET collection types in query tracing (CASSANDRA-19880)
diff --git a/src/java/org/apache/cassandra/utils/btree/BTree.java 
b/src/java/org/apache/cassandra/utils/btree/BTree.java
index 3a36912786..8242fb00f6 100644
--- a/src/java/org/apache/cassandra/utils/btree/BTree.java
+++ b/src/java/org/apache/cassandra/utils/btree/BTree.java
@@ -3312,28 +3312,52 @@ public class BTree
         public void close()
         {
             reset();
-            pool.offer(this);
-            pool = null;
+            if (pool != null)
+            {
+                pool.offer(this);
+                pool = null;
+            }
         }
 
         @Override
         void reset()
         {
-            // we clear precisely to leaf().count and branch.count because, in 
the case of a builder,
-            // if we ever fill the buffer we will consume it entirely for the 
tree we are building
-            // so the last count should match the number of non-null entries
-            Arrays.fill(leaf().buffer, 0, leaf().count, null);
+            Arrays.fill(leaf().buffer, null);
             leaf().count = 0;
             BranchBuilder branch = leaf().parent;
             while (branch != null && branch.inUse)
             {
-                Arrays.fill(branch.buffer, 0, branch.count, null);
-                Arrays.fill(branch.buffer, MAX_KEYS, MAX_KEYS + 1 + 
branch.count, null);
+                Arrays.fill(branch.buffer, null);
                 branch.count = 0;
                 branch.inUse = false;
                 branch = branch.parent;
             }
         }
+
+        public boolean validateEmpty()
+        {
+            LeafOrBranchBuilder cur = leaf();
+            boolean hasOnlyNulls = true;
+            while (hasOnlyNulls && cur != null)
+            {
+                hasOnlyNulls = hasOnlyNulls(cur.buffer) && 
hasOnlyNulls(cur.savedBuffer) && cur.savedNextKey == null;
+                cur = cur.parent;
+            }
+            return hasOnlyNulls;
+        }
+
+        private static boolean hasOnlyNulls(Object[] buffer)
+        {
+            if (buffer == null)
+                return true;
+
+            for (int i = 0 ; i < buffer.length ; ++i)
+            {
+                if (buffer[i] != null)
+                    return false;
+            }
+            return true;
+        }
     }
 
     private static abstract class AbstractUpdater extends AbstractFastBuilder 
implements AutoCloseable
diff --git a/test/burn/org/apache/cassandra/utils/LongBTreeTest.java 
b/test/burn/org/apache/cassandra/utils/LongBTreeTest.java
index aaa4e530f3..3a5beff8a3 100644
--- a/test/burn/org/apache/cassandra/utils/LongBTreeTest.java
+++ b/test/burn/org/apache/cassandra/utils/LongBTreeTest.java
@@ -728,6 +728,9 @@ public class LongBTreeTest
                 Object[] btree = builder.build();
                 assertEquals(i + 1, BTree.size(btree));
                 assertTrue(""+i, BTree.<Integer>isWellFormed(btree, 
naturalOrder()));
+                assertTrue(""+i, BTree.<Integer>isWellFormed(btree, 
naturalOrder()));
+                builder.close();
+                assertTrue(builder.validateEmpty());
             }
         }
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to