Merge branch 'cassandra-2.2' into cassandra-3.0
Conflicts:
src/java/org/apache/cassandra/utils/btree/TreeBuilder.java
test/unit/org/apache/cassandra/db/NativeCellTest.java
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/79f230f3
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/79f230f3
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/79f230f3
Branch: refs/heads/cassandra-3.0
Commit: 79f230f30d3834aa1b9f2d009c51b6dfc4c37288
Parents: 1e8007b 82aa796
Author: Benedict Elliott Smith <[email protected]>
Authored: Mon Nov 2 18:59:24 2015 +0000
Committer: Benedict Elliott Smith <[email protected]>
Committed: Mon Nov 2 18:59:24 2015 +0000
----------------------------------------------------------------------
.../cassandra/utils/btree/NodeBuilder.java | 11 +-
.../cassandra/utils/btree/TreeBuilder.java | 2 +-
.../cassandra/utils/memory/MemoryUtil.java | 2 +-
.../org/apache/cassandra/db/NativeCellTest.java | 280 +++++++++++++++++++
4 files changed, 288 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/79f230f3/src/java/org/apache/cassandra/utils/btree/NodeBuilder.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/79f230f3/src/java/org/apache/cassandra/utils/btree/TreeBuilder.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/utils/btree/TreeBuilder.java
index cb3ddc5,0000000..024902e
mode 100644,000000..100644
--- a/src/java/org/apache/cassandra/utils/btree/TreeBuilder.java
+++ b/src/java/org/apache/cassandra/utils/btree/TreeBuilder.java
@@@ -1,119 -1,0 +1,119 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cassandra.utils.btree;
+
+import java.util.Comparator;
+
+import static org.apache.cassandra.utils.btree.BTree.EMPTY_LEAF;
+import static org.apache.cassandra.utils.btree.BTree.FAN_SHIFT;
+import static org.apache.cassandra.utils.btree.BTree.POSITIVE_INFINITY;
+
+/**
+ * A class for constructing a new BTree, either from an existing one and some
set of modifications
+ * or a new tree from a sorted collection of items.
+ * <p/>
+ * This is a fairly heavy-weight object, so a ThreadLocal instance is created
for making modifications to a tree
+ */
+final class TreeBuilder
+{
+ private final NodeBuilder rootBuilder = new NodeBuilder();
+
+ /**
+ * At the highest level, we adhere to the classic b-tree insertion
algorithm:
+ *
+ * 1. Add to the appropriate leaf
+ * 2. Split the leaf if necessary, add the median to the parent
+ * 3. Split the parent if necessary, etc.
+ *
+ * There is one important difference: we don't actually modify the
original tree, but copy each node that we
+ * modify. Note that every node on the path to the key being inserted or
updated will be modified; this
+ * implies that at a minimum, the root node will be modified for every
update, so every root is a "snapshot"
+ * of a tree that can be iterated or sliced without fear of concurrent
modifications.
+ *
+ * The NodeBuilder class handles the details of buffering the copied
contents of the original tree and
+ * adding in our changes. Since NodeBuilder maintains parent/child
references, it also handles parent-splitting
+ * (easy enough, since any node affected by the split will already be
copied into a NodeBuilder).
+ *
+ * One other difference from the simple algorithm is that we perform
modifications in bulk;
+ * we assume @param source has been sorted, e.g. by BTree.update, so the
update of each key resumes where
+ * the previous left off.
+ */
+ public <C, K extends C, V extends C> Object[] update(Object[] btree,
Comparator<C> comparator, Iterable<K> source, UpdateFunction<K, V> updateF)
+ {
+ assert updateF != null;
+
+ NodeBuilder current = rootBuilder;
+ current.reset(btree, POSITIVE_INFINITY, updateF, comparator);
+
+ for (K key : source)
+ {
+ while (true)
+ {
+ if (updateF.abortEarly())
+ {
+ rootBuilder.clear();
+ return null;
+ }
+ NodeBuilder next = current.update(key);
+ if (next == null)
+ break;
+ // we were in a subtree from a previous key that didn't
contain this new key;
+ // retry against the correct subtree
+ current = next;
+ }
+ }
+
+ // finish copying any remaining keys from the original btree
+ while (true)
+ {
+ NodeBuilder next = current.finish();
+ if (next == null)
+ break;
+ current = next;
+ }
+
+ // updating with POSITIVE_INFINITY means that current should be back
to the root
+ assert current.isRoot();
+
+ Object[] r = current.toNode();
+ current.clear();
+ return r;
+ }
+
+ public <C, K extends C, V extends C> Object[] build(Iterable<K> source,
UpdateFunction<K, V> updateF, int size)
+ {
+ assert updateF != null;
+
+ NodeBuilder current = rootBuilder;
+ // we descend only to avoid wasting memory; in update() we will often
descend into existing trees
+ // so here we want to descend also, so we don't have lg max(N) depth
in both directions
+ while ((size >>= FAN_SHIFT) > 0)
+ current = current.ensureChild();
+
+ current.reset(EMPTY_LEAF, POSITIVE_INFINITY, updateF, null);
+ for (K key : source)
- current.addNewKey(updateF.apply(key));
++ current.addNewKey(key);
+
+ current = current.ascendToRoot();
+
+ Object[] r = current.toNode();
+ current.clear();
+ return r;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/79f230f3/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java
----------------------------------------------------------------------