You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by be...@apache.org on 2015/05/01 12:34:10 UTC

[1/6] cassandra git commit: Fix partition-level-delete-only workload accounting

Repository: cassandra
Updated Branches:
  refs/heads/cassandra-2.0 593a7257b -> f0c7a6f03
  refs/heads/cassandra-2.1 db127a107 -> 4f9c9ce55
  refs/heads/trunk 49b089893 -> 527c12a01


Fix partition-level-delete-only workload accounting

patch by benedict; reviewed by jbellis for CASSANDRA-9194


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/f0c7a6f0
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/f0c7a6f0
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/f0c7a6f0

Branch: refs/heads/cassandra-2.0
Commit: f0c7a6f03cf55ddcfe11a58c80087ed8b0806cf4
Parents: 593a725
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Fri May 1 11:32:31 2015 +0100
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Fri May 1 11:32:31 2015 +0100

----------------------------------------------------------------------
 CHANGES.txt                                    | 1 +
 src/java/org/apache/cassandra/db/Memtable.java | 6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/f0c7a6f0/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 4e7a5d0..dfdad51 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.0.15:
+ * Fix partition-level-delete-only workload accounting (CASSANDRA-9194)
  * Allow scrub to handle corrupted compressed chunks (CASSANDRA-9140)
  * Fix assertion error when resetlocalschema is run during repair (CASSANDRA-9249)
  * Disable single sstable tombstone compactions for DTCS by default (CASSANDRA-9234)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f0c7a6f0/src/java/org/apache/cassandra/db/Memtable.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Memtable.java b/src/java/org/apache/cassandra/db/Memtable.java
index 19f38be..897d94e 100644
--- a/src/java/org/apache/cassandra/db/Memtable.java
+++ b/src/java/org/apache/cassandra/db/Memtable.java
@@ -206,17 +206,21 @@ public class Memtable
     {
         AtomicSortedColumns previous = rows.get(key);
 
+        long initialSize = 0;
         if (previous == null)
         {
             AtomicSortedColumns empty = cf.cloneMeShallow(AtomicSortedColumns.factory, false);
             // We'll add the columns later. This avoids wasting works if we get beaten in the putIfAbsent
             previous = rows.putIfAbsent(new DecoratedKey(key.token, allocator.clone(key.key)), empty);
             if (previous == null)
+            {
                 previous = empty;
+                initialSize += 1;
+            }
         }
 
         final Pair<Long, Long> pair = previous.addAllWithSizeDelta(cf, allocator, localCopyFunction, indexer);
-        currentSize.addAndGet(pair.left);
+        currentSize.addAndGet(initialSize + pair.left);
         currentOperations.addAndGet(cf.getColumnCount() + (cf.isMarkedForDelete() ? 1 : 0) + cf.deletionInfo().rangeCount());
         return pair.right;
     }


[2/6] cassandra git commit: Fix partition-level-delete-only workload accounting

Posted by be...@apache.org.
Fix partition-level-delete-only workload accounting

patch by benedict; reviewed by jbellis for CASSANDRA-9194


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/f0c7a6f0
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/f0c7a6f0
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/f0c7a6f0

Branch: refs/heads/cassandra-2.1
Commit: f0c7a6f03cf55ddcfe11a58c80087ed8b0806cf4
Parents: 593a725
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Fri May 1 11:32:31 2015 +0100
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Fri May 1 11:32:31 2015 +0100

----------------------------------------------------------------------
 CHANGES.txt                                    | 1 +
 src/java/org/apache/cassandra/db/Memtable.java | 6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/f0c7a6f0/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 4e7a5d0..dfdad51 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.0.15:
+ * Fix partition-level-delete-only workload accounting (CASSANDRA-9194)
  * Allow scrub to handle corrupted compressed chunks (CASSANDRA-9140)
  * Fix assertion error when resetlocalschema is run during repair (CASSANDRA-9249)
  * Disable single sstable tombstone compactions for DTCS by default (CASSANDRA-9234)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f0c7a6f0/src/java/org/apache/cassandra/db/Memtable.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Memtable.java b/src/java/org/apache/cassandra/db/Memtable.java
index 19f38be..897d94e 100644
--- a/src/java/org/apache/cassandra/db/Memtable.java
+++ b/src/java/org/apache/cassandra/db/Memtable.java
@@ -206,17 +206,21 @@ public class Memtable
     {
         AtomicSortedColumns previous = rows.get(key);
 
+        long initialSize = 0;
         if (previous == null)
         {
             AtomicSortedColumns empty = cf.cloneMeShallow(AtomicSortedColumns.factory, false);
             // We'll add the columns later. This avoids wasting works if we get beaten in the putIfAbsent
             previous = rows.putIfAbsent(new DecoratedKey(key.token, allocator.clone(key.key)), empty);
             if (previous == null)
+            {
                 previous = empty;
+                initialSize += 1;
+            }
         }
 
         final Pair<Long, Long> pair = previous.addAllWithSizeDelta(cf, allocator, localCopyFunction, indexer);
-        currentSize.addAndGet(pair.left);
+        currentSize.addAndGet(initialSize + pair.left);
         currentOperations.addAndGet(cf.getColumnCount() + (cf.isMarkedForDelete() ? 1 : 0) + cf.deletionInfo().rangeCount());
         return pair.right;
     }


[6/6] cassandra git commit: Merge branch 'cassandra-2.1' into trunk

Posted by be...@apache.org.
Merge branch 'cassandra-2.1' into trunk


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/527c12a0
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/527c12a0
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/527c12a0

Branch: refs/heads/trunk
Commit: 527c12a0115629ad0fa7ec95a24c55fc115739a1
Parents: 49b0898 4f9c9ce
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Fri May 1 11:33:52 2015 +0100
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Fri May 1 11:33:52 2015 +0100

----------------------------------------------------------------------
 CHANGES.txt                                    | 1 +
 src/java/org/apache/cassandra/db/Memtable.java | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/527c12a0/CHANGES.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/527c12a0/src/java/org/apache/cassandra/db/Memtable.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/Memtable.java
index aa5fb1b,9a8596a..ef47aba
--- a/src/java/org/apache/cassandra/db/Memtable.java
+++ b/src/java/org/apache/cassandra/db/Memtable.java
@@@ -196,8 -197,9 +197,9 @@@ public class Memtabl
                  previous = empty;
                  // allocate the row overhead after the fact; this saves over allocating and having to free after, but
                  // means we can overshoot our declared limit.
 -                int overhead = (int) (cfs.partitioner.getHeapSizeOf(key.getToken()) + ROW_OVERHEAD_HEAP_SIZE);
 +                int overhead = (int) (key.getToken().getHeapSize() + ROW_OVERHEAD_HEAP_SIZE);
                  allocator.onHeap().allocate(overhead, opGroup);
+                 initialSize = 8;
              }
              else
              {


[3/6] cassandra git commit: Fix partition-level-delete-only workload accounting

Posted by be...@apache.org.
Fix partition-level-delete-only workload accounting

patch by benedict; reviewed by jbellis for CASSANDRA-9194


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/f0c7a6f0
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/f0c7a6f0
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/f0c7a6f0

Branch: refs/heads/trunk
Commit: f0c7a6f03cf55ddcfe11a58c80087ed8b0806cf4
Parents: 593a725
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Fri May 1 11:32:31 2015 +0100
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Fri May 1 11:32:31 2015 +0100

----------------------------------------------------------------------
 CHANGES.txt                                    | 1 +
 src/java/org/apache/cassandra/db/Memtable.java | 6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/f0c7a6f0/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 4e7a5d0..dfdad51 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.0.15:
+ * Fix partition-level-delete-only workload accounting (CASSANDRA-9194)
  * Allow scrub to handle corrupted compressed chunks (CASSANDRA-9140)
  * Fix assertion error when resetlocalschema is run during repair (CASSANDRA-9249)
  * Disable single sstable tombstone compactions for DTCS by default (CASSANDRA-9234)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f0c7a6f0/src/java/org/apache/cassandra/db/Memtable.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Memtable.java b/src/java/org/apache/cassandra/db/Memtable.java
index 19f38be..897d94e 100644
--- a/src/java/org/apache/cassandra/db/Memtable.java
+++ b/src/java/org/apache/cassandra/db/Memtable.java
@@ -206,17 +206,21 @@ public class Memtable
     {
         AtomicSortedColumns previous = rows.get(key);
 
+        long initialSize = 0;
         if (previous == null)
         {
             AtomicSortedColumns empty = cf.cloneMeShallow(AtomicSortedColumns.factory, false);
             // We'll add the columns later. This avoids wasting works if we get beaten in the putIfAbsent
             previous = rows.putIfAbsent(new DecoratedKey(key.token, allocator.clone(key.key)), empty);
             if (previous == null)
+            {
                 previous = empty;
+                initialSize += 1;
+            }
         }
 
         final Pair<Long, Long> pair = previous.addAllWithSizeDelta(cf, allocator, localCopyFunction, indexer);
-        currentSize.addAndGet(pair.left);
+        currentSize.addAndGet(initialSize + pair.left);
         currentOperations.addAndGet(cf.getColumnCount() + (cf.isMarkedForDelete() ? 1 : 0) + cf.deletionInfo().rangeCount());
         return pair.right;
     }


[5/6] cassandra git commit: Merge branch 'cassandra-2.0' into cassandra-2.1

Posted by be...@apache.org.
Merge branch 'cassandra-2.0' into cassandra-2.1

Conflicts:
	CHANGES.txt
	src/java/org/apache/cassandra/db/Memtable.java


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/4f9c9ce5
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/4f9c9ce5
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/4f9c9ce5

Branch: refs/heads/cassandra-2.1
Commit: 4f9c9ce55fd9993d06bf6dc4d9193e973fb8515f
Parents: db127a1 f0c7a6f
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Fri May 1 11:33:40 2015 +0100
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Fri May 1 11:33:40 2015 +0100

----------------------------------------------------------------------
 CHANGES.txt                                    | 1 +
 src/java/org/apache/cassandra/db/Memtable.java | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/4f9c9ce5/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index c063368,dfdad51..59b1182
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,10 -1,5 +1,11 @@@
 -2.0.15:
 +2.1.6
 + * Fix PITR commitlog replay (CASSANDRA-9195)
 + * GCInspector logs very different times (CASSANDRA-9124)
 + * Fix deleting from an empty list (CASSANDRA-9198)
 + * Update tuple and collection types that use a user-defined type when that UDT
 +   is modified (CASSANDRA-9148, CASSANDRA-9192)
 +Merged from 2.0:
+  * Fix partition-level-delete-only workload accounting (CASSANDRA-9194)
   * Allow scrub to handle corrupted compressed chunks (CASSANDRA-9140)
   * Fix assertion error when resetlocalschema is run during repair (CASSANDRA-9249)
   * Disable single sstable tombstone compactions for DTCS by default (CASSANDRA-9234)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4f9c9ce5/src/java/org/apache/cassandra/db/Memtable.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/Memtable.java
index eb04bea,897d94e..9a8596a
--- a/src/java/org/apache/cassandra/db/Memtable.java
+++ b/src/java/org/apache/cassandra/db/Memtable.java
@@@ -151,62 -182,45 +151,64 @@@ public class Memtabl
          }
      }
  
 -    public void updateLiveRatio() throws RuntimeException
 +    public boolean isLive()
      {
 -        if (!MemoryMeter.isInitialized())
 -        {
 -            // hack for openjdk.  we log a warning about this in the startup script too.
 -            logger.error("MemoryMeter uninitialized (jamm not specified as java agent); assuming liveRatio of {}.  "
 -                         + " Usually this means cassandra-env.sh disabled jamm because you are using a buggy JRE; "
 -                         + " upgrade to the Sun JRE instead", liveRatio);
 -            return;
 -        }
 +        return allocator.isLive();
 +    }
  
 -        if (!meteringInProgress.add(cfs))
 -        {
 -            logger.debug("Metering already pending or active for {}; skipping liveRatio update", cfs);
 -            return;
 -        }
 +    public boolean isClean()
 +    {
 +        return rows.isEmpty();
 +    }
  
 -        meterExecutor.submit(new MeteringRunnable(cfs));
 +    public boolean isCleanAfter(ReplayPosition position)
 +    {
 +        return isClean() || (position != null && minReplayPosition.compareTo(position) >= 0);
      }
  
 -    private long resolve(DecoratedKey key, ColumnFamily cf, SecondaryIndexManager.Updater indexer)
 +    /**
 +     * @return true if this memtable is expired. Expiration time is determined by CF's memtable_flush_period_in_ms.
 +     */
 +    public boolean isExpired()
 +    {
 +        int period = cfs.metadata.getMemtableFlushPeriod();
 +        return period > 0 && (System.nanoTime() - creationNano >= TimeUnit.MILLISECONDS.toNanos(period));
 +    }
 +
 +    /**
 +     * Should only be called by ColumnFamilyStore.apply via Keyspace.apply, which supplies the appropriate
 +     * OpOrdering.
 +     *
 +     * replayPosition should only be null if this is a secondary index, in which case it is *expected* to be null
 +     */
 +    long put(DecoratedKey key, ColumnFamily cf, SecondaryIndexManager.Updater indexer, OpOrder.Group opGroup)
      {
 -        AtomicSortedColumns previous = rows.get(key);
 +        AtomicBTreeColumns previous = rows.get(key);
  
+         long initialSize = 0;
          if (previous == null)
          {
 -            AtomicSortedColumns empty = cf.cloneMeShallow(AtomicSortedColumns.factory, false);
 +            AtomicBTreeColumns empty = cf.cloneMeShallow(AtomicBTreeColumns.factory, false);
 +            final DecoratedKey cloneKey = allocator.clone(key, opGroup);
              // We'll add the columns later. This avoids wasting works if we get beaten in the putIfAbsent
 -            previous = rows.putIfAbsent(new DecoratedKey(key.token, allocator.clone(key.key)), empty);
 +            previous = rows.putIfAbsent(cloneKey, empty);
              if (previous == null)
              {
                  previous = empty;
 -                initialSize += 1;
 +                // allocate the row overhead after the fact; this saves over allocating and having to free after, but
 +                // means we can overshoot our declared limit.
 +                int overhead = (int) (cfs.partitioner.getHeapSizeOf(key.getToken()) + ROW_OVERHEAD_HEAP_SIZE);
 +                allocator.onHeap().allocate(overhead, opGroup);
++                initialSize = 8;
 +            }
 +            else
 +            {
 +                allocator.reclaimer().reclaimImmediately(cloneKey);
              }
          }
  
 -        final Pair<Long, Long> pair = previous.addAllWithSizeDelta(cf, allocator, localCopyFunction, indexer);
 -        currentSize.addAndGet(initialSize + pair.left);
 +        final Pair<Long, Long> pair = previous.addAllWithSizeDelta(cf, allocator, opGroup, indexer);
-         liveDataSize.addAndGet(pair.left);
++        liveDataSize.addAndGet(initialSize + pair.left);
          currentOperations.addAndGet(cf.getColumnCount() + (cf.isMarkedForDelete() ? 1 : 0) + cf.deletionInfo().rangeCount());
          return pair.right;
      }


[4/6] cassandra git commit: Merge branch 'cassandra-2.0' into cassandra-2.1

Posted by be...@apache.org.
Merge branch 'cassandra-2.0' into cassandra-2.1

Conflicts:
	CHANGES.txt
	src/java/org/apache/cassandra/db/Memtable.java


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/4f9c9ce5
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/4f9c9ce5
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/4f9c9ce5

Branch: refs/heads/trunk
Commit: 4f9c9ce55fd9993d06bf6dc4d9193e973fb8515f
Parents: db127a1 f0c7a6f
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Fri May 1 11:33:40 2015 +0100
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Fri May 1 11:33:40 2015 +0100

----------------------------------------------------------------------
 CHANGES.txt                                    | 1 +
 src/java/org/apache/cassandra/db/Memtable.java | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/4f9c9ce5/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index c063368,dfdad51..59b1182
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,10 -1,5 +1,11 @@@
 -2.0.15:
 +2.1.6
 + * Fix PITR commitlog replay (CASSANDRA-9195)
 + * GCInspector logs very different times (CASSANDRA-9124)
 + * Fix deleting from an empty list (CASSANDRA-9198)
 + * Update tuple and collection types that use a user-defined type when that UDT
 +   is modified (CASSANDRA-9148, CASSANDRA-9192)
 +Merged from 2.0:
+  * Fix partition-level-delete-only workload accounting (CASSANDRA-9194)
   * Allow scrub to handle corrupted compressed chunks (CASSANDRA-9140)
   * Fix assertion error when resetlocalschema is run during repair (CASSANDRA-9249)
   * Disable single sstable tombstone compactions for DTCS by default (CASSANDRA-9234)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4f9c9ce5/src/java/org/apache/cassandra/db/Memtable.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/Memtable.java
index eb04bea,897d94e..9a8596a
--- a/src/java/org/apache/cassandra/db/Memtable.java
+++ b/src/java/org/apache/cassandra/db/Memtable.java
@@@ -151,62 -182,45 +151,64 @@@ public class Memtabl
          }
      }
  
 -    public void updateLiveRatio() throws RuntimeException
 +    public boolean isLive()
      {
 -        if (!MemoryMeter.isInitialized())
 -        {
 -            // hack for openjdk.  we log a warning about this in the startup script too.
 -            logger.error("MemoryMeter uninitialized (jamm not specified as java agent); assuming liveRatio of {}.  "
 -                         + " Usually this means cassandra-env.sh disabled jamm because you are using a buggy JRE; "
 -                         + " upgrade to the Sun JRE instead", liveRatio);
 -            return;
 -        }
 +        return allocator.isLive();
 +    }
  
 -        if (!meteringInProgress.add(cfs))
 -        {
 -            logger.debug("Metering already pending or active for {}; skipping liveRatio update", cfs);
 -            return;
 -        }
 +    public boolean isClean()
 +    {
 +        return rows.isEmpty();
 +    }
  
 -        meterExecutor.submit(new MeteringRunnable(cfs));
 +    public boolean isCleanAfter(ReplayPosition position)
 +    {
 +        return isClean() || (position != null && minReplayPosition.compareTo(position) >= 0);
      }
  
 -    private long resolve(DecoratedKey key, ColumnFamily cf, SecondaryIndexManager.Updater indexer)
 +    /**
 +     * @return true if this memtable is expired. Expiration time is determined by CF's memtable_flush_period_in_ms.
 +     */
 +    public boolean isExpired()
 +    {
 +        int period = cfs.metadata.getMemtableFlushPeriod();
 +        return period > 0 && (System.nanoTime() - creationNano >= TimeUnit.MILLISECONDS.toNanos(period));
 +    }
 +
 +    /**
 +     * Should only be called by ColumnFamilyStore.apply via Keyspace.apply, which supplies the appropriate
 +     * OpOrdering.
 +     *
 +     * replayPosition should only be null if this is a secondary index, in which case it is *expected* to be null
 +     */
 +    long put(DecoratedKey key, ColumnFamily cf, SecondaryIndexManager.Updater indexer, OpOrder.Group opGroup)
      {
 -        AtomicSortedColumns previous = rows.get(key);
 +        AtomicBTreeColumns previous = rows.get(key);
  
+         long initialSize = 0;
          if (previous == null)
          {
 -            AtomicSortedColumns empty = cf.cloneMeShallow(AtomicSortedColumns.factory, false);
 +            AtomicBTreeColumns empty = cf.cloneMeShallow(AtomicBTreeColumns.factory, false);
 +            final DecoratedKey cloneKey = allocator.clone(key, opGroup);
              // We'll add the columns later. This avoids wasting works if we get beaten in the putIfAbsent
 -            previous = rows.putIfAbsent(new DecoratedKey(key.token, allocator.clone(key.key)), empty);
 +            previous = rows.putIfAbsent(cloneKey, empty);
              if (previous == null)
              {
                  previous = empty;
 -                initialSize += 1;
 +                // allocate the row overhead after the fact; this saves over allocating and having to free after, but
 +                // means we can overshoot our declared limit.
 +                int overhead = (int) (cfs.partitioner.getHeapSizeOf(key.getToken()) + ROW_OVERHEAD_HEAP_SIZE);
 +                allocator.onHeap().allocate(overhead, opGroup);
++                initialSize = 8;
 +            }
 +            else
 +            {
 +                allocator.reclaimer().reclaimImmediately(cloneKey);
              }
          }
  
 -        final Pair<Long, Long> pair = previous.addAllWithSizeDelta(cf, allocator, localCopyFunction, indexer);
 -        currentSize.addAndGet(initialSize + pair.left);
 +        final Pair<Long, Long> pair = previous.addAllWithSizeDelta(cf, allocator, opGroup, indexer);
-         liveDataSize.addAndGet(pair.left);
++        liveDataSize.addAndGet(initialSize + pair.left);
          currentOperations.addAndGet(cf.getColumnCount() + (cf.isMarkedForDelete() ? 1 : 0) + cf.deletionInfo().rangeCount());
          return pair.right;
      }