diff --git a/build.xml b/build.xml
index c34bcfc109..bc2bbfd99f 100644
--- a/build.xml
+++ b/build.xml
@@ -62,7 +62,6 @@
-
@@ -402,6 +401,7 @@
+
@@ -433,6 +433,7 @@
+
+
diff --git a/conf/cassandra-env.sh b/conf/cassandra-env.sh
index eb0553b61b..1655438a53 100644
--- a/conf/cassandra-env.sh
+++ b/conf/cassandra-env.sh
@@ -212,6 +212,7 @@ JVM_OPTS="$JVM_OPTS -XX:MaxTenuringThreshold=1"
JVM_OPTS="$JVM_OPTS -XX:CMSInitiatingOccupancyFraction=75"
JVM_OPTS="$JVM_OPTS -XX:+UseCMSInitiatingOccupancyOnly"
JVM_OPTS="$JVM_OPTS -XX:+UseTLAB"
+JVM_OPTS="$JVM_OPTS -XX:CompileCommandFile=$CASSANDRA_CONF/hotspot_compiler"
# note: bash evals '1.7.x' as > '1.7' so this is really a >= 1.7 jvm check
if [ "$JVM_ARCH" = "64-Bit" ] ; then
@@ -242,6 +243,9 @@ fi
# uncomment to have Cassandra JVM listen for remote debuggers/profilers on port 1414
# JVM_OPTS="$JVM_OPTS -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1414"
+# uncomment to have Cassandra JVM log internal method compilation (developers only)
+# JVM_OPTS="$JVM_OPTS -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation"
+
# Prefer binding to IPv4 network intefaces (when net.ipv6.bindv6only=1). See
# http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6342561 (short version:
# comment out this entry to enable IPv6 support).
diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml
index f1e5576268..4d97e864d0 100644
--- a/conf/cassandra.yaml
+++ b/conf/cassandra.yaml
@@ -290,7 +290,7 @@ memtable_cleanup_threshold: 0.4
# heap_buffers: on heap nio buffers
# offheap_buffers: off heap (direct) nio buffers
# offheap_objects: native memory, eliminating nio buffer heap overhead
-memtable_allocation_type: heap_buffers
+memtable_allocation_type: offheap_objects
# Total space to use for commitlogs. Since commitlog segments are
# mmapped, and hence use up address space, the default size is 32
diff --git a/src/java/org/apache/cassandra/db/AbstractNativeCell.java b/src/java/org/apache/cassandra/db/AbstractNativeCell.java
index f3128b8760..d79ad19667 100644
--- a/src/java/org/apache/cassandra/db/AbstractNativeCell.java
+++ b/src/java/org/apache/cassandra/db/AbstractNativeCell.java
@@ -21,6 +21,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.MessageDigest;
+import net.nicoulaj.compilecommand.annotations.Inline;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.cql3.ColumnIdentifier;
@@ -30,6 +31,7 @@ import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.CompositeType;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.FBUtilities;
+import org.apache.cassandra.utils.FastByteOperations;
import org.apache.cassandra.utils.concurrent.OpOrder;
import org.apache.cassandra.utils.memory.*;
@@ -285,6 +287,12 @@ public abstract class AbstractNativeCell extends AbstractCell implements CellNam
}
public ByteBuffer get(int i)
+ {
+ return get(i, null);
+ }
+
+ @Inline
+ private ByteBuffer get(int i, AbstractAllocator copy)
{
// remember to take dense/sparse into account, and only return EOC when not dense
int size = size();
@@ -292,7 +300,12 @@ public abstract class AbstractNativeCell extends AbstractCell implements CellNam
int cellNamesOffset = nameDeltaOffset(size);
int startDelta = i == 0 ? 0 : getShort(nameDeltaOffset(i));
int endDelta = i < size - 1 ? getShort(nameDeltaOffset(i + 1)) : valueStartOffset() - cellNamesOffset;
- return getByteBuffer(cellNamesOffset + startDelta, endDelta - startDelta).order(ByteOrder.BIG_ENDIAN);
+ int length = endDelta - startDelta;
+ if (copy == null)
+ return getByteBuffer(cellNamesOffset + startDelta, length).order(ByteOrder.BIG_ENDIAN);
+ ByteBuffer result = copy.allocate(length);
+ FastByteOperations.UnsafeOperations.copy(null, peer + cellNamesOffset + startDelta, result, 0, length);
+ return result;
}
private static final ThreadLocal BUFFER = new ThreadLocal()
@@ -496,12 +509,12 @@ public abstract class AbstractNativeCell extends AbstractCell implements CellNam
switch (nametype())
{
case SIMPLE_DENSE:
- return CellNames.simpleDense(allocator.clone(get(0)));
+ return CellNames.simpleDense(get(0, allocator));
case COMPOUND_DENSE:
r = new ByteBuffer[size()];
for (int i = 0; i < r.length; i++)
- r[i] = allocator.clone(get(i));
+ r[i] = get(i, allocator);
return CellNames.compositeDense(r);
case COMPOUND_SPARSE_STATIC:
@@ -509,7 +522,7 @@ public abstract class AbstractNativeCell extends AbstractCell implements CellNam
int clusteringSize = clusteringSize();
r = clusteringSize == 0 ? EMPTY : new ByteBuffer[clusteringSize()];
for (int i = 0; i < clusteringSize; i++)
- r[i] = allocator.clone(get(i));
+ r[i] = get(i, allocator);
ByteBuffer nameBuffer = get(r.length);
ColumnIdentifier name;
@@ -645,4 +658,38 @@ public abstract class AbstractNativeCell extends AbstractCell implements CellNam
checkPosition(offset, length);
return MemoryUtil.getByteBuffer(peer + offset, length);
}
+
+ // requires isByteOrderComparable to be true. Compares the name components only; ; may need to compare EOC etc still
+ public final int compareTo(final Composite that)
+ {
+ int size = size();
+ int size2 = that.size();
+ int minSize = Math.min(size, size2);
+ int startDelta = 0;
+ int cellNamesOffset = nameDeltaOffset(size);
+ for (int i = 0 ; i < minSize ; i++)
+ {
+ int endDelta = i < size - 1 ? getShort(nameDeltaOffset(i + 1)) : valueStartOffset() - cellNamesOffset;
+ long offset = peer + cellNamesOffset + startDelta;
+ int length = endDelta - startDelta;
+ int cmp = FastByteOperations.UnsafeOperations.compareTo(null, offset, length, that.get(i));
+ if (cmp != 0)
+ return cmp;
+ startDelta = endDelta;
+ }
+
+ EOC eoc = that.eoc();
+ if (size == size2)
+ return this.eoc().compareTo(eoc);
+
+ return size < size2 ? this.eoc().prefixComparisonResult : -eoc.prefixComparisonResult;
+ }
+
+ public final int compareToSimple(final Composite that)
+ {
+ assert size() == 1 && that.size() == 1;
+ int length = valueStartOffset() - nameDeltaOffset(1);
+ long offset = peer + nameDeltaOffset(1);
+ return FastByteOperations.UnsafeOperations.compareTo(null, offset, length, that.get(0));
+ }
}
diff --git a/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java b/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java
index 8a2d43ebca..e92d5a3c40 100644
--- a/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java
+++ b/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java
@@ -27,6 +27,7 @@ import com.google.common.base.Function;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.Iterables;
+import net.nicoulaj.compilecommand.annotations.Inline;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.db.composites.CellName;
import org.apache.cassandra.db.composites.Composite;
@@ -122,6 +123,7 @@ public class ArrayBackedSortedColumns extends ColumnFamily
/**
* synchronized so that concurrent (read-only) accessors don't mess the internal state.
*/
+ @Inline
private synchronized void sortCells()
{
if (isSorted)
@@ -129,7 +131,7 @@ public class ArrayBackedSortedColumns extends ColumnFamily
Comparator| comparator = reversed
? getComparator().columnReverseComparator()
- : getComparator().columnComparator();
+ : getComparator().columnComparator(false);
// Sort the unsorted segment - will still potentially contain duplicate (non-reconciled) cells
Arrays.sort(cells, sortedSize, size, comparator);
diff --git a/src/java/org/apache/cassandra/db/AtomicBTreeColumns.java b/src/java/org/apache/cassandra/db/AtomicBTreeColumns.java
index 03cd0c56d0..559e75988c 100644
--- a/src/java/org/apache/cassandra/db/AtomicBTreeColumns.java
+++ b/src/java/org/apache/cassandra/db/AtomicBTreeColumns.java
@@ -40,6 +40,8 @@ import org.apache.cassandra.utils.btree.UpdateFunction;
import org.apache.cassandra.utils.concurrent.OpOrder;
import org.apache.cassandra.utils.memory.HeapAllocator;
import org.apache.cassandra.utils.memory.MemtableAllocator;
+import org.apache.cassandra.utils.memory.NativeAllocator;
+import org.apache.cassandra.utils.memory.NativePool;
import static org.apache.cassandra.db.index.SecondaryIndexManager.Updater;
@@ -186,7 +188,7 @@ public class AtomicBTreeColumns extends ColumnFamily
deletionInfo = current.deletionInfo;
}
- Object[] tree = BTree.update(current.tree, metadata.comparator.columnComparator(), cm, cm.getColumnCount(), true, updater);
+ Object[] tree = BTree.update(current.tree, metadata.comparator.columnComparator(Memtable.MEMORY_POOL instanceof NativePool), cm, cm.getColumnCount(), true, updater);
if (tree != null && refUpdater.compareAndSet(this, current, new Holder(tree, deletionInfo)))
{
@@ -226,14 +228,7 @@ public class AtomicBTreeColumns extends ColumnFamily
private Comparator |