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 2014/12/02 18:19:12 UTC

[1/2] cassandra git commit: BTree updates may call provided update function twice

Repository: cassandra
Updated Branches:
  refs/heads/trunk 06f626acd -> a604b14bf


BTree updates may call provided update function twice

patch by Benjamin; reviewed by Benedict for CASSANDRA-8018


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

Branch: refs/heads/trunk
Commit: 5ab1d95b29509ee5a061eddda39d7f4189abbe37
Parents: d15c918
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Tue Dec 2 17:17:35 2014 +0000
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Tue Dec 2 17:18:51 2014 +0000

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../apache/cassandra/utils/btree/Builder.java   |   2 +-
 .../cassandra/utils/btree/NodeBuilder.java      |   6 +-
 .../org/apache/cassandra/utils/BTreeTest.java   | 120 +++++++++++++++++--
 4 files changed, 117 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/5ab1d95b/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 7df396d..c5ac66c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.1.3
+ * BTree updates may call provided update function twice (CASSANDRA-8018)
  * Release sstable references after anticompaction (CASSANDRA-8386)
  * Handle abort() in SSTableRewriter properly (CASSANDRA-8320)
  * Fix high size calculations for prepared statements (CASSANDRA-8231)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5ab1d95b/src/java/org/apache/cassandra/utils/btree/Builder.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/btree/Builder.java b/src/java/org/apache/cassandra/utils/btree/Builder.java
index f6677d4..0f2fd5b 100644
--- a/src/java/org/apache/cassandra/utils/btree/Builder.java
+++ b/src/java/org/apache/cassandra/utils/btree/Builder.java
@@ -109,7 +109,7 @@ final class Builder
 
         current.reset(EMPTY_LEAF, POSITIVE_INFINITY, updateF, null);
         for (V key : source)
-            current.addNewKey(key);
+            current.addNewKey(updateF.apply(key));
 
         current = current.ascendToRoot();
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5ab1d95b/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java b/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java
index 9d57182..c715873 100644
--- a/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java
+++ b/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java
@@ -133,7 +133,7 @@ final class NodeBuilder
 
         int i = copyFromKeyPosition;
         boolean found; // exact key match?
-        boolean owns = true; // true iff this node (or a child) should contain the key
+        boolean owns = true; // true if this node (or a child) should contain the key
         if (i == copyFromKeyEnd)
         {
             found = false;
@@ -185,7 +185,7 @@ final class NodeBuilder
                 }
                 else
                 {
-                    // if not found, we need to apply updateFunction still
+                    // if not found, we still need to apply the update function
                     key = updateFunction.apply(key);
                     addNewKey(key); // handles splitting parent if necessary via ensureRoom
                 }
@@ -319,7 +319,7 @@ final class NodeBuilder
     void addNewKey(Object key)
     {
         ensureRoom(buildKeyPosition + 1);
-        buildKeys[buildKeyPosition++] = updateFunction.apply(key);
+        buildKeys[buildKeyPosition++] = key;
     }
 
     // copies children from copyf to the builder, up to the provided index in copyf (exclusive)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5ab1d95b/test/unit/org/apache/cassandra/utils/BTreeTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/BTreeTest.java b/test/unit/org/apache/cassandra/utils/BTreeTest.java
index a6d4528..e1bf388 100644
--- a/test/unit/org/apache/cassandra/utils/BTreeTest.java
+++ b/test/unit/org/apache/cassandra/utils/BTreeTest.java
@@ -17,22 +17,21 @@
  */
 package org.apache.cassandra.utils;
 
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Random;
+import java.util.*;
 import java.util.concurrent.ThreadLocalRandom;
 
 import org.junit.Test;
 
-import junit.framework.Assert;
 import org.apache.cassandra.utils.btree.BTree;
 import org.apache.cassandra.utils.btree.BTreeSet;
 import org.apache.cassandra.utils.btree.UpdateFunction;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertTrue;
+
 public class BTreeTest
 {
-
     static Integer[] ints = new Integer[20];
     static
     {
@@ -114,13 +113,78 @@ public class BTreeTest
         }
     }
 
+    /**
+     * Tests that the apply method of the <code>UpdateFunction</code> is only called once with each key update.
+     * (see CASSANDRA-8018).
+     */
+    @Test
+    public void testUpdate_UpdateFunctionCallBack()
+    {
+        Object[] btree = new Object[0];
+        CallsMonitor monitor = new CallsMonitor();
+
+        btree = BTree.update(btree, CMP, Arrays.asList(1), true, monitor);
+        assertArrayEquals(new Object[] {1, null}, btree);
+        assertEquals(1, monitor.getNumberOfCalls(1));
+
+        monitor.clear();
+        btree = BTree.update(btree, CMP, Arrays.asList(2), true, monitor);
+        assertArrayEquals(new Object[] {1, 2}, btree);
+        assertEquals(1, monitor.getNumberOfCalls(2));
+
+        // with existing value
+        monitor.clear();
+        btree = BTree.update(btree, CMP, Arrays.asList(1), true, monitor);
+        assertArrayEquals(new Object[] {1, 2}, btree);
+        assertEquals(1, monitor.getNumberOfCalls(1));
+
+        // with two non-existing values
+        monitor.clear();
+        btree = BTree.update(btree, CMP, Arrays.asList(3, 4), true, monitor);
+        assertArrayEquals(new Object[] {1, 2, 3, 4}, btree);
+        assertEquals(1, monitor.getNumberOfCalls(3));
+        assertEquals(1, monitor.getNumberOfCalls(4));
+
+        // with one existing value and one non existing value in disorder
+        monitor.clear();
+        btree = BTree.update(btree, CMP, Arrays.asList(5, 2), false, monitor);
+        assertArrayEquals(new Object[] {3, new Object[]{1, 2}, new Object[]{4, 5}}, btree);
+        assertEquals(1, monitor.getNumberOfCalls(2));
+        assertEquals(1, monitor.getNumberOfCalls(5));
+    }
+
+    /**
+     * Tests that the apply method of the <code>UpdateFunction</code> is only called once per value with each build call.
+     */
+    @Test
+    public void testBuilding_UpdateFunctionCallBack()
+    {
+        CallsMonitor monitor = new CallsMonitor();
+        Object[] btree = BTree.build(Arrays.asList(1), CMP, true, monitor);
+        assertArrayEquals(new Object[] {1, null}, btree);
+        assertEquals(1, monitor.getNumberOfCalls(1));
+
+        monitor.clear();
+        btree = BTree.build(Arrays.asList(1, 2), CMP, true, monitor);
+        assertArrayEquals(new Object[] {1, 2}, btree);
+        assertEquals(1, monitor.getNumberOfCalls(1));
+        assertEquals(1, monitor.getNumberOfCalls(2));
+
+        monitor.clear();
+        btree = BTree.build(Arrays.asList(3, 1, 2), CMP, false, monitor);
+        assertArrayEquals(new Object[] {1, 2, 3, null}, btree);
+        assertEquals(1, monitor.getNumberOfCalls(1));
+        assertEquals(1, monitor.getNumberOfCalls(2));
+        assertEquals(1, monitor.getNumberOfCalls(3));
+    }
+
     private static void checkResult(int count, Object[] btree)
     {
         BTreeSet<Integer> vs = new BTreeSet<>(btree, CMP);
         assert vs.size() == count;
         int i = 0;
         for (Integer j : vs)
-            Assert.assertEquals(j, ints[i++]);
+            assertEquals(j, ints[i++]);
     }
 
     @Test
@@ -137,7 +201,7 @@ public class BTreeTest
         Object[] btree = BTree.build(ranges(range(0, 8)), cmp, true, UpdateFunction.NoOp.<String>instance());
         BTree.update(btree, cmp, ranges(range(0, 94)), false, new AbortAfterX(90));
         btree = BTree.update(btree, cmp, ranges(range(0, 94)), false, UpdateFunction.NoOp.<String>instance());
-        Assert.assertTrue(BTree.isWellFormed(btree, cmp));
+        assertTrue(BTree.isWellFormed(btree, cmp));
     }
 
     private static final class AbortAfterX implements UpdateFunction<String>
@@ -181,4 +245,44 @@ public class BTreeTest
         }
         return r;
     }
+
+    /**
+     * <code>UpdateFunction</code> that count the number of call made to apply for each value.
+     */
+    public static final class CallsMonitor implements UpdateFunction<Integer>
+    {
+        private int[] numberOfCalls = new int[20];
+
+        public Integer apply(Integer replacing, Integer update)
+        {
+            numberOfCalls[update] = numberOfCalls[update] + 1;
+            return update;
+        }
+
+        public boolean abortEarly()
+        {
+            return false;
+        }
+
+        public void allocated(long heapSize)
+        {
+
+        }
+
+        public Integer apply(Integer integer)
+        {
+            numberOfCalls[integer] = numberOfCalls[integer] + 1;
+            return integer;
+        }
+
+        public int getNumberOfCalls(Integer key)
+        {
+            return numberOfCalls[key];
+        }
+
+        public void clear()
+        {
+            Arrays.fill(numberOfCalls, 0);
+        }
+    };
 }


[2/2] 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/a604b14b
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/a604b14b
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/a604b14b

Branch: refs/heads/trunk
Commit: a604b14bf422709175322ee913b9fee247e74710
Parents: 06f626a 5ab1d95
Author: Benedict Elliott Smith <be...@apache.org>
Authored: Tue Dec 2 17:18:56 2014 +0000
Committer: Benedict Elliott Smith <be...@apache.org>
Committed: Tue Dec 2 17:18:56 2014 +0000

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../apache/cassandra/utils/btree/Builder.java   |   2 +-
 .../cassandra/utils/btree/NodeBuilder.java      |   6 +-
 .../org/apache/cassandra/utils/BTreeTest.java   | 120 +++++++++++++++++--
 4 files changed, 117 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/a604b14b/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 141c3a8,c5ac66c..3cb1c0f
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,43 -1,8 +1,44 @@@
 +3.0
 + * Support UDTs, tuples, and collections in user-defined
 +   functions (CASSANDRA-7563)
 + * Fix aggregate fn results on empty selection, result column name,
 +   and cqlsh parsing (CASSANDRA-8229)
 + * Mark sstables as repaired after full repair (CASSANDRA-7586)
 + * Extend Descriptor to include a format value and refactor reader/writer apis (CASSANDRA-7443)
 + * Integrate JMH for microbenchmarks (CASSANDRA-8151)
 + * Keep sstable levels when bootstrapping (CASSANDRA-7460)
 + * Add Sigar library and perform basic OS settings check on startup (CASSANDRA-7838)
 + * Support for aggregation functions (CASSANDRA-4914)
 + * Remove cassandra-cli (CASSANDRA-7920)
 + * Accept dollar quoted strings in CQL (CASSANDRA-7769)
 + * Make assassinate a first class command (CASSANDRA-7935)
 + * Support IN clause on any clustering column (CASSANDRA-4762)
 + * Improve compaction logging (CASSANDRA-7818)
 + * Remove YamlFileNetworkTopologySnitch (CASSANDRA-7917)
 + * Do anticompaction in groups (CASSANDRA-6851)
 + * Support pure user-defined functions (CASSANDRA-7395, 7526, 7562, 7740, 7781, 7929,
 +   7924, 7812, 8063, 7813)
 + * Permit configurable timestamps with cassandra-stress (CASSANDRA-7416)
 + * Move sstable RandomAccessReader to nio2, which allows using the
 +   FILE_SHARE_DELETE flag on Windows (CASSANDRA-4050)
 + * Remove CQL2 (CASSANDRA-5918)
 + * Add Thrift get_multi_slice call (CASSANDRA-6757)
 + * Optimize fetching multiple cells by name (CASSANDRA-6933)
 + * Allow compilation in java 8 (CASSANDRA-7028)
 + * Make incremental repair default (CASSANDRA-7250)
 + * Enable code coverage thru JaCoCo (CASSANDRA-7226)
 + * Switch external naming of 'column families' to 'tables' (CASSANDRA-4369) 
 + * Shorten SSTable path (CASSANDRA-6962)
 + * Use unsafe mutations for most unit tests (CASSANDRA-6969)
 + * Fix race condition during calculation of pending ranges (CASSANDRA-7390)
 + * Fail on very large batch sizes (CASSANDRA-8011)
 + * Improve concurrency of repair (CASSANDRA-6455, 8208)
 +
 +
  2.1.3
+  * BTree updates may call provided update function twice (CASSANDRA-8018)
   * Release sstable references after anticompaction (CASSANDRA-8386)
   * Handle abort() in SSTableRewriter properly (CASSANDRA-8320)
 - * Fix high size calculations for prepared statements (CASSANDRA-8231)
   * Centralize shared executors (CASSANDRA-8055)
   * Fix filtering for CONTAINS (KEY) relations on frozen collection
     clustering columns when the query is restricted to a single

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a604b14b/src/java/org/apache/cassandra/utils/btree/Builder.java
----------------------------------------------------------------------