You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2014/02/04 06:51:27 UTC
[1/3] git commit: Fix direct Memory on architectures that do not
support unaligned long access patch by Dmitry Shohov and Benedict Elliott
Smith for CASSANDRA-6628
Updated Branches:
refs/heads/cassandra-2.0 066d00ba5 -> 039e9b9a1
refs/heads/trunk 78f71420c -> b25a63a81
Fix direct Memory on architectures that do not support unaligned long access
patch by Dmitry Shohov and Benedict Elliott Smith for CASSANDRA-6628
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/039e9b9a
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/039e9b9a
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/039e9b9a
Branch: refs/heads/cassandra-2.0
Commit: 039e9b9a18cbe78091231a4538b6d428deacc771
Parents: 066d00b
Author: Jonathan Ellis <jb...@apache.org>
Authored: Mon Feb 3 23:50:08 2014 -0600
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Mon Feb 3 23:50:08 2014 -0600
----------------------------------------------------------------------
CHANGES.txt | 2 +
.../cassandra/config/DatabaseDescriptor.java | 20 ++-
.../org/apache/cassandra/io/util/Memory.java | 123 ++++++++++++++++++-
.../cassandra/service/CassandraDaemon.java | 2 +-
.../cassandra/utils/FastByteComparisons.java | 6 +
5 files changed, 145 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 4440942..b1fade1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,6 @@
2.0.6
+ * Fix direct Memory on architectures that do not support unaligned long access
+ (CASSANDRA-6628)
* Let scrub optionally skip broken counter partitions (CASSANDRA-5930)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 44d9d3a..bd5db69 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -172,12 +172,12 @@ public class DatabaseDescriptor
}
if (conf.commitlog_total_space_in_mb == null)
- conf.commitlog_total_space_in_mb = System.getProperty("os.arch").contains("64") ? 1024 : 32;
+ conf.commitlog_total_space_in_mb = hasLargeAddressSpace() ? 1024 : 32;
/* evaluate the DiskAccessMode Config directive, which also affects indexAccessMode selection */
if (conf.disk_access_mode == Config.DiskAccessMode.auto)
{
- conf.disk_access_mode = System.getProperty("os.arch").contains("64") ? Config.DiskAccessMode.mmap : Config.DiskAccessMode.standard;
+ conf.disk_access_mode = hasLargeAddressSpace() ? Config.DiskAccessMode.mmap : Config.DiskAccessMode.standard;
indexAccessMode = conf.disk_access_mode;
logger.info("DiskAccessMode 'auto' determined to be " + conf.disk_access_mode + ", indexAccessMode is " + indexAccessMode );
}
@@ -1323,4 +1323,20 @@ public class DatabaseDescriptor
throw new RuntimeException(e);
}
}
+
+ public static boolean hasLargeAddressSpace()
+ {
+ // currently we just check if it's a 64bit arch, but any we only really care if the address space is large
+ String datamodel = System.getProperty("sun.arch.data.model");
+ if (datamodel != null)
+ {
+ switch (datamodel)
+ {
+ case "64": return true;
+ case "32": return false;
+ }
+ }
+ String arch = System.getProperty("os.arch");
+ return arch.contains("64") || arch.contains("sparcv9");
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/src/java/org/apache/cassandra/io/util/Memory.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/util/Memory.java b/src/java/org/apache/cassandra/io/util/Memory.java
index f276190..263205b 100644
--- a/src/java/org/apache/cassandra/io/util/Memory.java
+++ b/src/java/org/apache/cassandra/io/util/Memory.java
@@ -17,9 +17,10 @@
*/
package org.apache.cassandra.io.util;
-import sun.misc.Unsafe;
+import java.nio.ByteOrder;
import org.apache.cassandra.config.DatabaseDescriptor;
+import sun.misc.Unsafe;
/**
* An off-heap region of memory that must be manually free'd when no longer needed.
@@ -30,6 +31,16 @@ public class Memory
private static final IAllocator allocator = DatabaseDescriptor.getoffHeapMemoryAllocator();
private static final long BYTE_ARRAY_BASE_OFFSET = unsafe.arrayBaseOffset(byte[].class);
+ private static final boolean bigEndian = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
+ private static final boolean unaligned;
+
+ static
+ {
+ String arch = System.getProperty("os.arch");
+ unaligned = arch.equals("i386") || arch.equals("x86")
+ || arch.equals("amd64") || arch.equals("x86_64");
+ }
+
protected long peer;
// size of the memory region
private final long size;
@@ -64,13 +75,71 @@ public class Memory
public void setLong(long offset, long l)
{
checkPosition(offset);
- unsafe.putLong(peer + offset, l);
+ if (unaligned)
+ {
+ unsafe.putLong(peer + offset, l);
+ }
+ else
+ {
+ putLongByByte(peer + offset, l);
+ }
+ }
+
+ private void putLongByByte(long address, long value)
+ {
+ if (bigEndian)
+ {
+ unsafe.putByte(address, (byte) (value >> 56));
+ unsafe.putByte(address + 1, (byte) (value >> 48));
+ unsafe.putByte(address + 2, (byte) (value >> 40));
+ unsafe.putByte(address + 3, (byte) (value >> 32));
+ unsafe.putByte(address + 4, (byte) (value >> 24));
+ unsafe.putByte(address + 5, (byte) (value >> 16));
+ unsafe.putByte(address + 6, (byte) (value >> 8));
+ unsafe.putByte(address + 7, (byte) (value));
+ }
+ else
+ {
+ unsafe.putByte(address + 7, (byte) (value >> 56));
+ unsafe.putByte(address + 6, (byte) (value >> 48));
+ unsafe.putByte(address + 5, (byte) (value >> 40));
+ unsafe.putByte(address + 4, (byte) (value >> 32));
+ unsafe.putByte(address + 3, (byte) (value >> 24));
+ unsafe.putByte(address + 2, (byte) (value >> 16));
+ unsafe.putByte(address + 1, (byte) (value >> 8));
+ unsafe.putByte(address, (byte) (value));
+ }
}
public void setInt(long offset, int l)
{
checkPosition(offset);
- unsafe.putInt(peer + offset, l);
+ if (unaligned)
+ {
+ unsafe.putInt(peer + offset, l);
+ }
+ else
+ {
+ putIntByByte(peer + offset, l);
+ }
+ }
+
+ private void putIntByByte(long address, int value)
+ {
+ if (bigEndian)
+ {
+ unsafe.putByte(address, (byte) (value >> 24));
+ unsafe.putByte(address + 1, (byte) (value >> 16));
+ unsafe.putByte(address + 2, (byte) (value >> 8));
+ unsafe.putByte(address + 3, (byte) (value));
+ }
+ else
+ {
+ unsafe.putByte(address + 3, (byte) (value >> 24));
+ unsafe.putByte(address + 2, (byte) (value >> 16));
+ unsafe.putByte(address + 1, (byte) (value >> 8));
+ unsafe.putByte(address, (byte) (value));
+ }
}
/**
@@ -108,13 +177,57 @@ public class Memory
public long getLong(long offset)
{
checkPosition(offset);
- return unsafe.getLong(peer + offset);
+ if (unaligned) {
+ return unsafe.getLong(peer + offset);
+ } else {
+ return getLongByByte(peer + offset);
+ }
+ }
+
+ private long getLongByByte(long address) {
+ if (bigEndian) {
+ return (((long) unsafe.getByte(address ) ) << 56) |
+ (((long) unsafe.getByte(address + 1) & 0xff) << 48) |
+ (((long) unsafe.getByte(address + 2) & 0xff) << 40) |
+ (((long) unsafe.getByte(address + 3) & 0xff) << 32) |
+ (((long) unsafe.getByte(address + 4) & 0xff) << 24) |
+ (((long) unsafe.getByte(address + 5) & 0xff) << 16) |
+ (((long) unsafe.getByte(address + 6) & 0xff) << 8) |
+ (((long) unsafe.getByte(address + 7) & 0xff) );
+ } else {
+ return (((long) unsafe.getByte(address + 7) ) << 56) |
+ (((long) unsafe.getByte(address + 6) & 0xff) << 48) |
+ (((long) unsafe.getByte(address + 5) & 0xff) << 40) |
+ (((long) unsafe.getByte(address + 4) & 0xff) << 32) |
+ (((long) unsafe.getByte(address + 3) & 0xff) << 24) |
+ (((long) unsafe.getByte(address + 2) & 0xff) << 16) |
+ (((long) unsafe.getByte(address + 1) & 0xff) << 8) |
+ (((long) unsafe.getByte(address ) & 0xff) );
+ }
}
public int getInt(long offset)
{
checkPosition(offset);
- return unsafe.getInt(peer + offset);
+ if (unaligned) {
+ return unsafe.getInt(peer + offset);
+ } else {
+ return getIntByByte(peer + offset);
+ }
+ }
+
+ private int getIntByByte(long address) {
+ if (bigEndian) {
+ return (((int) unsafe.getByte(address ) ) << 24) |
+ (((int) unsafe.getByte(address + 1) & 0xff) << 16) |
+ (((int) unsafe.getByte(address + 2) & 0xff) << 8 ) |
+ (((int) unsafe.getByte(address + 3) & 0xff) );
+ } else {
+ return (((int) unsafe.getByte(address + 3) ) << 24) |
+ (((int) unsafe.getByte(address + 2) & 0xff) << 16) |
+ (((int) unsafe.getByte(address + 1) & 0xff) << 8) |
+ (((int) unsafe.getByte(address ) & 0xff) );
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/src/java/org/apache/cassandra/service/CassandraDaemon.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/CassandraDaemon.java b/src/java/org/apache/cassandra/service/CassandraDaemon.java
index 60e9c25..9e63c05 100644
--- a/src/java/org/apache/cassandra/service/CassandraDaemon.java
+++ b/src/java/org/apache/cassandra/service/CassandraDaemon.java
@@ -148,7 +148,7 @@ public class CassandraDaemon
protected void setup()
{
// log warnings for different kinds of sub-optimal JVMs. tldr use 64-bit Oracle >= 1.6u32
- if (!System.getProperty("os.arch").contains("64"))
+ if (!DatabaseDescriptor.hasLargeAddressSpace())
logger.info("32bit JVM detected. It is recommended to run Cassandra on a 64bit JVM for better performance.");
String javaVersion = System.getProperty("java.version");
String javaVmName = System.getProperty("java.vm.name");
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/src/java/org/apache/cassandra/utils/FastByteComparisons.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/FastByteComparisons.java b/src/java/org/apache/cassandra/utils/FastByteComparisons.java
index c135a01..4be6cd4 100644
--- a/src/java/org/apache/cassandra/utils/FastByteComparisons.java
+++ b/src/java/org/apache/cassandra/utils/FastByteComparisons.java
@@ -69,6 +69,11 @@ abstract class FastByteComparisons {
* implementation if unable to do so.
*/
static Comparer<byte[]> getBestComparer() {
+ String arch = System.getProperty("os.arch");
+ boolean unaligned = arch.equals("i386") || arch.equals("x86")
+ || arch.equals("amd64") || arch.equals("x86_64");
+ if (!unaligned)
+ return lexicographicalComparerJavaImpl();
try {
Class<?> theClass = Class.forName(UNSAFE_COMPARER_NAME);
@@ -229,6 +234,7 @@ abstract class FastByteComparisons {
}
return length1 - length2;
}
+
}
}
}
[3/3] git commit: merge from 2.0
Posted by jb...@apache.org.
merge from 2.0
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/b25a63a8
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/b25a63a8
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/b25a63a8
Branch: refs/heads/trunk
Commit: b25a63a81d22e409e607ca28c39e20604332cb5d
Parents: 78f7142 039e9b9
Author: Jonathan Ellis <jb...@apache.org>
Authored: Mon Feb 3 23:51:16 2014 -0600
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Mon Feb 3 23:51:16 2014 -0600
----------------------------------------------------------------------
CHANGES.txt | 2 +
.../cassandra/config/DatabaseDescriptor.java | 20 ++-
.../org/apache/cassandra/io/util/Memory.java | 123 ++++++++++++++++++-
.../cassandra/service/CassandraDaemon.java | 2 +-
.../cassandra/utils/FastByteComparisons.java | 6 +
5 files changed, 145 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b25a63a8/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 6a4c507,b1fade1..28278c4
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,33 -1,6 +1,35 @@@
+2.1
+ * add listsnapshots command to nodetool (CASSANDRA-5742)
+ * Introduce AtomicBTreeColumns (CASSANDRA-6271)
+ * Multithreaded commitlog (CASSANDRA-3578)
+ * allocate fixed index summary memory pool and resample cold index summaries
+ to use less memory (CASSANDRA-5519)
+ * Removed multithreaded compaction (CASSANDRA-6142)
+ * Parallelize fetching rows for low-cardinality indexes (CASSANDRA-1337)
+ * change logging from log4j to logback (CASSANDRA-5883)
+ * switch to LZ4 compression for internode communication (CASSANDRA-5887)
+ * Stop using Thrift-generated Index* classes internally (CASSANDRA-5971)
+ * Remove 1.2 network compatibility code (CASSANDRA-5960)
+ * Remove leveled json manifest migration code (CASSANDRA-5996)
+ * Remove CFDefinition (CASSANDRA-6253)
+ * Use AtomicIntegerFieldUpdater in RefCountedMemory (CASSANDRA-6278)
+ * User-defined types for CQL3 (CASSANDRA-5590)
+ * Use of o.a.c.metrics in nodetool (CASSANDRA-5871, 6406)
+ * Batch read from OTC's queue and cleanup (CASSANDRA-1632)
+ * Secondary index support for collections (CASSANDRA-4511, 6383)
+ * SSTable metadata(Stats.db) format change (CASSANDRA-6356)
+ * Push composites support in the storage engine
+ (CASSANDRA-5417, CASSANDRA-6520)
+ * Add snapshot space used to cfstats (CASSANDRA-6231)
+ * Add cardinality estimator for key count estimation (CASSANDRA-5906)
+ * CF id is changed to be non-deterministic. Data dir/key cache are created
+ uniquely for CF id (CASSANDRA-5202)
+ * New counters implementation (CASSANDRA-6504)
+
+
2.0.6
+ * Fix direct Memory on architectures that do not support unaligned long access
+ (CASSANDRA-6628)
* Let scrub optionally skip broken counter partitions (CASSANDRA-5930)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b25a63a8/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 2793237,bd5db69..378fa8a
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@@ -177,9 -177,9 +177,9 @@@ public class DatabaseDescripto
/* evaluate the DiskAccessMode Config directive, which also affects indexAccessMode selection */
if (conf.disk_access_mode == Config.DiskAccessMode.auto)
{
- conf.disk_access_mode = System.getProperty("os.arch").contains("64") ? Config.DiskAccessMode.mmap : Config.DiskAccessMode.standard;
+ conf.disk_access_mode = hasLargeAddressSpace() ? Config.DiskAccessMode.mmap : Config.DiskAccessMode.standard;
indexAccessMode = conf.disk_access_mode;
- logger.info("DiskAccessMode 'auto' determined to be " + conf.disk_access_mode + ", indexAccessMode is " + indexAccessMode );
+ logger.info("DiskAccessMode 'auto' determined to be {}, indexAccessMode is {}", conf.disk_access_mode, indexAccessMode);
}
else if (conf.disk_access_mode == Config.DiskAccessMode.mmap_index_only)
{
@@@ -1384,8 -1324,19 +1384,24 @@@
}
}
+ public static int getIndexSummaryResizeIntervalInMinutes()
+ {
+ return conf.index_summary_resize_interval_in_minutes;
+ }
++
+ public static boolean hasLargeAddressSpace()
+ {
+ // currently we just check if it's a 64bit arch, but any we only really care if the address space is large
+ String datamodel = System.getProperty("sun.arch.data.model");
+ if (datamodel != null)
+ {
+ switch (datamodel)
+ {
+ case "64": return true;
+ case "32": return false;
+ }
+ }
+ String arch = System.getProperty("os.arch");
+ return arch.contains("64") || arch.contains("sparcv9");
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b25a63a8/src/java/org/apache/cassandra/service/CassandraDaemon.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/service/CassandraDaemon.java
index 2903fc4,9e63c05..0ad47ac
--- a/src/java/org/apache/cassandra/service/CassandraDaemon.java
+++ b/src/java/org/apache/cassandra/service/CassandraDaemon.java
@@@ -94,16 -147,8 +94,16 @@@ public class CassandraDaemo
*/
protected void setup()
{
+ try
+ {
+ logger.info("Hostname: {}", InetAddress.getLocalHost().getHostName());
+ }
+ catch (UnknownHostException e1)
+ {
+ logger.info("Could not resolve local host");
+ }
// log warnings for different kinds of sub-optimal JVMs. tldr use 64-bit Oracle >= 1.6u32
- if (!System.getProperty("os.arch").contains("64"))
+ if (!DatabaseDescriptor.hasLargeAddressSpace())
logger.info("32bit JVM detected. It is recommended to run Cassandra on a 64bit JVM for better performance.");
String javaVersion = System.getProperty("java.version");
String javaVmName = System.getProperty("java.vm.name");
[2/3] git commit: Fix direct Memory on architectures that do not
support unaligned long access patch by Dmitry Shohov and Benedict Elliott
Smith for CASSANDRA-6628
Posted by jb...@apache.org.
Fix direct Memory on architectures that do not support unaligned long access
patch by Dmitry Shohov and Benedict Elliott Smith for CASSANDRA-6628
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/039e9b9a
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/039e9b9a
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/039e9b9a
Branch: refs/heads/trunk
Commit: 039e9b9a18cbe78091231a4538b6d428deacc771
Parents: 066d00b
Author: Jonathan Ellis <jb...@apache.org>
Authored: Mon Feb 3 23:50:08 2014 -0600
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Mon Feb 3 23:50:08 2014 -0600
----------------------------------------------------------------------
CHANGES.txt | 2 +
.../cassandra/config/DatabaseDescriptor.java | 20 ++-
.../org/apache/cassandra/io/util/Memory.java | 123 ++++++++++++++++++-
.../cassandra/service/CassandraDaemon.java | 2 +-
.../cassandra/utils/FastByteComparisons.java | 6 +
5 files changed, 145 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 4440942..b1fade1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,6 @@
2.0.6
+ * Fix direct Memory on architectures that do not support unaligned long access
+ (CASSANDRA-6628)
* Let scrub optionally skip broken counter partitions (CASSANDRA-5930)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 44d9d3a..bd5db69 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -172,12 +172,12 @@ public class DatabaseDescriptor
}
if (conf.commitlog_total_space_in_mb == null)
- conf.commitlog_total_space_in_mb = System.getProperty("os.arch").contains("64") ? 1024 : 32;
+ conf.commitlog_total_space_in_mb = hasLargeAddressSpace() ? 1024 : 32;
/* evaluate the DiskAccessMode Config directive, which also affects indexAccessMode selection */
if (conf.disk_access_mode == Config.DiskAccessMode.auto)
{
- conf.disk_access_mode = System.getProperty("os.arch").contains("64") ? Config.DiskAccessMode.mmap : Config.DiskAccessMode.standard;
+ conf.disk_access_mode = hasLargeAddressSpace() ? Config.DiskAccessMode.mmap : Config.DiskAccessMode.standard;
indexAccessMode = conf.disk_access_mode;
logger.info("DiskAccessMode 'auto' determined to be " + conf.disk_access_mode + ", indexAccessMode is " + indexAccessMode );
}
@@ -1323,4 +1323,20 @@ public class DatabaseDescriptor
throw new RuntimeException(e);
}
}
+
+ public static boolean hasLargeAddressSpace()
+ {
+ // currently we just check if it's a 64bit arch, but any we only really care if the address space is large
+ String datamodel = System.getProperty("sun.arch.data.model");
+ if (datamodel != null)
+ {
+ switch (datamodel)
+ {
+ case "64": return true;
+ case "32": return false;
+ }
+ }
+ String arch = System.getProperty("os.arch");
+ return arch.contains("64") || arch.contains("sparcv9");
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/src/java/org/apache/cassandra/io/util/Memory.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/util/Memory.java b/src/java/org/apache/cassandra/io/util/Memory.java
index f276190..263205b 100644
--- a/src/java/org/apache/cassandra/io/util/Memory.java
+++ b/src/java/org/apache/cassandra/io/util/Memory.java
@@ -17,9 +17,10 @@
*/
package org.apache.cassandra.io.util;
-import sun.misc.Unsafe;
+import java.nio.ByteOrder;
import org.apache.cassandra.config.DatabaseDescriptor;
+import sun.misc.Unsafe;
/**
* An off-heap region of memory that must be manually free'd when no longer needed.
@@ -30,6 +31,16 @@ public class Memory
private static final IAllocator allocator = DatabaseDescriptor.getoffHeapMemoryAllocator();
private static final long BYTE_ARRAY_BASE_OFFSET = unsafe.arrayBaseOffset(byte[].class);
+ private static final boolean bigEndian = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
+ private static final boolean unaligned;
+
+ static
+ {
+ String arch = System.getProperty("os.arch");
+ unaligned = arch.equals("i386") || arch.equals("x86")
+ || arch.equals("amd64") || arch.equals("x86_64");
+ }
+
protected long peer;
// size of the memory region
private final long size;
@@ -64,13 +75,71 @@ public class Memory
public void setLong(long offset, long l)
{
checkPosition(offset);
- unsafe.putLong(peer + offset, l);
+ if (unaligned)
+ {
+ unsafe.putLong(peer + offset, l);
+ }
+ else
+ {
+ putLongByByte(peer + offset, l);
+ }
+ }
+
+ private void putLongByByte(long address, long value)
+ {
+ if (bigEndian)
+ {
+ unsafe.putByte(address, (byte) (value >> 56));
+ unsafe.putByte(address + 1, (byte) (value >> 48));
+ unsafe.putByte(address + 2, (byte) (value >> 40));
+ unsafe.putByte(address + 3, (byte) (value >> 32));
+ unsafe.putByte(address + 4, (byte) (value >> 24));
+ unsafe.putByte(address + 5, (byte) (value >> 16));
+ unsafe.putByte(address + 6, (byte) (value >> 8));
+ unsafe.putByte(address + 7, (byte) (value));
+ }
+ else
+ {
+ unsafe.putByte(address + 7, (byte) (value >> 56));
+ unsafe.putByte(address + 6, (byte) (value >> 48));
+ unsafe.putByte(address + 5, (byte) (value >> 40));
+ unsafe.putByte(address + 4, (byte) (value >> 32));
+ unsafe.putByte(address + 3, (byte) (value >> 24));
+ unsafe.putByte(address + 2, (byte) (value >> 16));
+ unsafe.putByte(address + 1, (byte) (value >> 8));
+ unsafe.putByte(address, (byte) (value));
+ }
}
public void setInt(long offset, int l)
{
checkPosition(offset);
- unsafe.putInt(peer + offset, l);
+ if (unaligned)
+ {
+ unsafe.putInt(peer + offset, l);
+ }
+ else
+ {
+ putIntByByte(peer + offset, l);
+ }
+ }
+
+ private void putIntByByte(long address, int value)
+ {
+ if (bigEndian)
+ {
+ unsafe.putByte(address, (byte) (value >> 24));
+ unsafe.putByte(address + 1, (byte) (value >> 16));
+ unsafe.putByte(address + 2, (byte) (value >> 8));
+ unsafe.putByte(address + 3, (byte) (value));
+ }
+ else
+ {
+ unsafe.putByte(address + 3, (byte) (value >> 24));
+ unsafe.putByte(address + 2, (byte) (value >> 16));
+ unsafe.putByte(address + 1, (byte) (value >> 8));
+ unsafe.putByte(address, (byte) (value));
+ }
}
/**
@@ -108,13 +177,57 @@ public class Memory
public long getLong(long offset)
{
checkPosition(offset);
- return unsafe.getLong(peer + offset);
+ if (unaligned) {
+ return unsafe.getLong(peer + offset);
+ } else {
+ return getLongByByte(peer + offset);
+ }
+ }
+
+ private long getLongByByte(long address) {
+ if (bigEndian) {
+ return (((long) unsafe.getByte(address ) ) << 56) |
+ (((long) unsafe.getByte(address + 1) & 0xff) << 48) |
+ (((long) unsafe.getByte(address + 2) & 0xff) << 40) |
+ (((long) unsafe.getByte(address + 3) & 0xff) << 32) |
+ (((long) unsafe.getByte(address + 4) & 0xff) << 24) |
+ (((long) unsafe.getByte(address + 5) & 0xff) << 16) |
+ (((long) unsafe.getByte(address + 6) & 0xff) << 8) |
+ (((long) unsafe.getByte(address + 7) & 0xff) );
+ } else {
+ return (((long) unsafe.getByte(address + 7) ) << 56) |
+ (((long) unsafe.getByte(address + 6) & 0xff) << 48) |
+ (((long) unsafe.getByte(address + 5) & 0xff) << 40) |
+ (((long) unsafe.getByte(address + 4) & 0xff) << 32) |
+ (((long) unsafe.getByte(address + 3) & 0xff) << 24) |
+ (((long) unsafe.getByte(address + 2) & 0xff) << 16) |
+ (((long) unsafe.getByte(address + 1) & 0xff) << 8) |
+ (((long) unsafe.getByte(address ) & 0xff) );
+ }
}
public int getInt(long offset)
{
checkPosition(offset);
- return unsafe.getInt(peer + offset);
+ if (unaligned) {
+ return unsafe.getInt(peer + offset);
+ } else {
+ return getIntByByte(peer + offset);
+ }
+ }
+
+ private int getIntByByte(long address) {
+ if (bigEndian) {
+ return (((int) unsafe.getByte(address ) ) << 24) |
+ (((int) unsafe.getByte(address + 1) & 0xff) << 16) |
+ (((int) unsafe.getByte(address + 2) & 0xff) << 8 ) |
+ (((int) unsafe.getByte(address + 3) & 0xff) );
+ } else {
+ return (((int) unsafe.getByte(address + 3) ) << 24) |
+ (((int) unsafe.getByte(address + 2) & 0xff) << 16) |
+ (((int) unsafe.getByte(address + 1) & 0xff) << 8) |
+ (((int) unsafe.getByte(address ) & 0xff) );
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/src/java/org/apache/cassandra/service/CassandraDaemon.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/CassandraDaemon.java b/src/java/org/apache/cassandra/service/CassandraDaemon.java
index 60e9c25..9e63c05 100644
--- a/src/java/org/apache/cassandra/service/CassandraDaemon.java
+++ b/src/java/org/apache/cassandra/service/CassandraDaemon.java
@@ -148,7 +148,7 @@ public class CassandraDaemon
protected void setup()
{
// log warnings for different kinds of sub-optimal JVMs. tldr use 64-bit Oracle >= 1.6u32
- if (!System.getProperty("os.arch").contains("64"))
+ if (!DatabaseDescriptor.hasLargeAddressSpace())
logger.info("32bit JVM detected. It is recommended to run Cassandra on a 64bit JVM for better performance.");
String javaVersion = System.getProperty("java.version");
String javaVmName = System.getProperty("java.vm.name");
http://git-wip-us.apache.org/repos/asf/cassandra/blob/039e9b9a/src/java/org/apache/cassandra/utils/FastByteComparisons.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/FastByteComparisons.java b/src/java/org/apache/cassandra/utils/FastByteComparisons.java
index c135a01..4be6cd4 100644
--- a/src/java/org/apache/cassandra/utils/FastByteComparisons.java
+++ b/src/java/org/apache/cassandra/utils/FastByteComparisons.java
@@ -69,6 +69,11 @@ abstract class FastByteComparisons {
* implementation if unable to do so.
*/
static Comparer<byte[]> getBestComparer() {
+ String arch = System.getProperty("os.arch");
+ boolean unaligned = arch.equals("i386") || arch.equals("x86")
+ || arch.equals("amd64") || arch.equals("x86_64");
+ if (!unaligned)
+ return lexicographicalComparerJavaImpl();
try {
Class<?> theClass = Class.forName(UNSAFE_COMPARER_NAME);
@@ -229,6 +234,7 @@ abstract class FastByteComparisons {
}
return length1 - length2;
}
+
}
}
}