This is an automated email from the ASF dual-hosted git repository.
mck pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new 5815f0d5eb Fix (unsupported) big endian unaligned architecture (s390x)
5815f0d5eb is described below
commit 5815f0d5eb43ce890dc3ea71f45a7488e5c6163a
Author: Mick Semb Wever <[email protected]>
AuthorDate: Tue Jul 11 12:44:17 2023 +0200
Fix (unsupported) big endian unaligned architecture (s390x)
patch by Shahid Shaikh; reviewed by Mick Semb Wever, Brandon Williams for
CASSANDRA-17723
---
CHANGES.txt | 1 +
.../io/sstable/indexsummary/IndexSummary.java | 3 +-
.../sstable/indexsummary/IndexSummaryBuilder.java | 4 +-
src/java/org/apache/cassandra/io/util/Memory.java | 43 ++++++----------------
.../org/apache/cassandra/utils/Architecture.java | 4 ++
.../apache/cassandra/utils/memory/MemoryUtil.java | 41 ++++++++++++---------
6 files changed, 42 insertions(+), 54 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index ef4749b12c..9875217ba8 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
5.0
+ * Fix for (unsupported) big endian unaligned architecture, eg s390x
(CASSANDRA-17723)
* CIDR filtering authorizer (CASSANDRA-18592)
* Remove 3.x from the versions checked for prepared statement behaviour
(CASSANDRA-18695)
* Add vector similarity functions (CASSANDRA-18640)
diff --git
a/src/java/org/apache/cassandra/io/sstable/indexsummary/IndexSummary.java
b/src/java/org/apache/cassandra/io/sstable/indexsummary/IndexSummary.java
index 105d235373..0d5ccb750b 100644
--- a/src/java/org/apache/cassandra/io/sstable/indexsummary/IndexSummary.java
+++ b/src/java/org/apache/cassandra/io/sstable/indexsummary/IndexSummary.java
@@ -414,8 +414,7 @@ public class IndexSummary extends WrappedSharedCloseable
int offset = t.offsets.getInt(i * 4) + baseOffset;
// our serialization format for this file uses native byte
order, so if this is different to the
// default Java serialization order (BIG_ENDIAN) we have to
reverse our bytes
- if (ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN)
- offset = Integer.reverseBytes(offset);
+ offset = Integer.reverseBytes(offset);
out.writeInt(offset);
}
out.write(t.entries, 0, t.entriesLength);
diff --git
a/src/java/org/apache/cassandra/io/sstable/indexsummary/IndexSummaryBuilder.java
b/src/java/org/apache/cassandra/io/sstable/indexsummary/IndexSummaryBuilder.java
index 5f38fc91f8..862df0fb88 100644
---
a/src/java/org/apache/cassandra/io/sstable/indexsummary/IndexSummaryBuilder.java
+++
b/src/java/org/apache/cassandra/io/sstable/indexsummary/IndexSummaryBuilder.java
@@ -123,8 +123,8 @@ public class IndexSummaryBuilder implements AutoCloseable
// for initializing data structures, adjust our estimates based on the
sampling level
maxExpectedEntries = Math.max(1, (maxExpectedEntries * samplingLevel)
/ BASE_SAMPLING_LEVEL);
- offsets = new SafeMemoryWriter(4 *
maxExpectedEntries).order(ByteOrder.nativeOrder());
- entries = new SafeMemoryWriter(expectedEntrySize *
maxExpectedEntries).order(ByteOrder.nativeOrder());
+ offsets = new SafeMemoryWriter(4 *
maxExpectedEntries).order(ByteOrder.LITTLE_ENDIAN);
+ entries = new SafeMemoryWriter(expectedEntrySize *
maxExpectedEntries).order(ByteOrder.LITTLE_ENDIAN);
// the summary will always contain the first index entry (downsampling
will never remove it)
nextSamplePosition = 0;
diff --git a/src/java/org/apache/cassandra/io/util/Memory.java
b/src/java/org/apache/cassandra/io/util/Memory.java
index 7fd4225ec0..1d1fca2edf 100644
--- a/src/java/org/apache/cassandra/io/util/Memory.java
+++ b/src/java/org/apache/cassandra/io/util/Memory.java
@@ -19,7 +19,6 @@ package org.apache.cassandra.io.util;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
import net.nicoulaj.compilecommand.annotations.Inline;
@@ -51,8 +50,6 @@ public class Memory implements AutoCloseable, ReadableMemory
private static final long BYTE_ARRAY_BASE_OFFSET =
unsafe.arrayBaseOffset(byte[].class);
- private static final boolean bigEndian =
ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
-
public static final ByteBuffer[] NO_BYTE_BUFFERS = new ByteBuffer[0];
protected long peer;
@@ -107,18 +104,14 @@ public class Memory implements AutoCloseable,
ReadableMemory
{
checkBounds(offset, offset + 8);
if (Architecture.IS_UNALIGNED)
- {
- unsafe.putLong(peer + offset, l);
- }
+ unsafe.putLong(peer + offset, Architecture.BIG_ENDIAN ?
Long.reverseBytes(l) : l);
else
- {
putLongByByte(peer + offset, l);
- }
}
private void putLongByByte(long address, long value)
{
- if (bigEndian)
+ if (Architecture.BIG_ENDIAN)
{
unsafe.putByte(address, (byte) (value >> 56));
unsafe.putByte(address + 1, (byte) (value >> 48));
@@ -146,18 +139,14 @@ public class Memory implements AutoCloseable,
ReadableMemory
{
checkBounds(offset, offset + 4);
if (Architecture.IS_UNALIGNED)
- {
- unsafe.putInt(peer + offset, l);
- }
+ unsafe.putInt(peer + offset, Architecture.BIG_ENDIAN ?
Integer.reverseBytes(l) : l);
else
- {
putIntByByte(peer + offset, l);
- }
}
private void putIntByByte(long address, int value)
{
- if (bigEndian)
+ if (Architecture.BIG_ENDIAN)
{
unsafe.putByte(address, (byte) (value >> 24));
unsafe.putByte(address + 1, (byte) (value >> 16));
@@ -177,18 +166,14 @@ public class Memory implements AutoCloseable,
ReadableMemory
{
checkBounds(offset, offset + 2);
if (Architecture.IS_UNALIGNED)
- {
- unsafe.putShort(peer + offset, l);
- }
+ unsafe.putShort(peer + offset, Architecture.BIG_ENDIAN ?
Short.reverseBytes(l) : l);
else
- {
putShortByByte(peer + offset, l);
- }
}
private void putShortByByte(long address, short value)
{
- if (bigEndian)
+ if (Architecture.BIG_ENDIAN)
{
unsafe.putByte(address, (byte) (value >> 8));
unsafe.putByte(address + 1, (byte) (value));
@@ -252,16 +237,14 @@ public class Memory implements AutoCloseable,
ReadableMemory
{
checkBounds(offset, offset + 8);
if (Architecture.IS_UNALIGNED)
- {
- return unsafe.getLong(peer + offset);
- } else {
+ return Architecture.BIG_ENDIAN ?
Long.reverseBytes(unsafe.getLong(peer+offset)) : unsafe.getLong(peer+offset);
+ else
return getLongByByte(peer + offset);
- }
}
private long getLongByByte(long address)
{
- if (bigEndian)
+ if (Architecture.BIG_ENDIAN)
{
return (((long) unsafe.getByte(address ) ) << 56) |
(((long) unsafe.getByte(address + 1) & 0xff) << 48) |
@@ -289,18 +272,14 @@ public class Memory implements AutoCloseable,
ReadableMemory
{
checkBounds(offset, offset + 4);
if (Architecture.IS_UNALIGNED)
- {
- return unsafe.getInt(peer + offset);
- }
+ return Architecture.BIG_ENDIAN ?
Integer.reverseBytes(unsafe.getInt(peer+offset)) : unsafe.getInt(peer+offset);
else
- {
return getIntByByte(peer + offset);
- }
}
private int getIntByByte(long address)
{
- if (bigEndian)
+ if (Architecture.BIG_ENDIAN)
{
return ((unsafe.getByte(address ) ) << 24) |
((unsafe.getByte(address + 1) & 0xff) << 16) |
diff --git a/src/java/org/apache/cassandra/utils/Architecture.java
b/src/java/org/apache/cassandra/utils/Architecture.java
index bdea769add..4362b2fcb2 100644
--- a/src/java/org/apache/cassandra/utils/Architecture.java
+++ b/src/java/org/apache/cassandra/utils/Architecture.java
@@ -19,6 +19,7 @@
package org.apache.cassandra.utils;
+import java.nio.ByteOrder;
import java.util.Collections;
import java.util.Set;
@@ -42,6 +43,9 @@ public final class Architecture
public static final boolean IS_UNALIGNED =
UNALIGNED_ARCH.contains(OS_ARCH.getString());
+ // Note that s390x (and all unaligned, see UNALIGNED_ARCH above)
architectures are not officially supported, ref #17723
+ public static final boolean BIG_ENDIAN =
ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
+
private Architecture()
{
}
diff --git a/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java
b/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java
index 4a9f41409a..453f3eda1b 100644
--- a/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java
+++ b/src/java/org/apache/cassandra/utils/memory/MemoryUtil.java
@@ -44,10 +44,6 @@ public abstract class MemoryUtil
private static final long BYTE_BUFFER_HB_OFFSET;
private static final long BYTE_ARRAY_BASE_OFFSET;
- private static final boolean BIG_ENDIAN =
ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
-
- public static final boolean INVERTED_ORDER = Architecture.IS_UNALIGNED &&
!BIG_ENDIAN;
-
static
{
try
@@ -110,13 +106,13 @@ public abstract class MemoryUtil
public static void setShort(long address, short s)
{
- unsafe.putShort(address, s);
+ unsafe.putShort(address, Architecture.BIG_ENDIAN ?
Short.reverseBytes(s) : s);
}
public static void setInt(long address, int l)
{
if (Architecture.IS_UNALIGNED)
- unsafe.putInt(address, l);
+ unsafe.putInt(address, Architecture.BIG_ENDIAN ?
Integer.reverseBytes(l) : l);
else
putIntByByte(address, l);
}
@@ -124,7 +120,7 @@ public abstract class MemoryUtil
public static void setLong(long address, long l)
{
if (Architecture.IS_UNALIGNED)
- unsafe.putLong(address, l);
+ unsafe.putLong(address, Architecture.BIG_ENDIAN ?
Long.reverseBytes(l) : l);
else
putLongByByte(address, l);
}
@@ -136,18 +132,27 @@ public abstract class MemoryUtil
public static int getShort(long address)
{
- return (Architecture.IS_UNALIGNED ? unsafe.getShort(address) :
getShortByByte(address)) & 0xffff;
- }
+ if (Architecture.IS_UNALIGNED)
+ return (Architecture.BIG_ENDIAN ?
Short.reverseBytes(unsafe.getShort(address)) : unsafe.getShort(address)) &
0xffff;
+ else
+ return getShortByByte(address) & 0xffff;
+ }
public static int getInt(long address)
{
- return Architecture.IS_UNALIGNED ? unsafe.getInt(address) :
getIntByByte(address);
- }
+ if (Architecture.IS_UNALIGNED)
+ return Architecture.BIG_ENDIAN ?
Integer.reverseBytes(unsafe.getInt(address)) : unsafe.getInt(address);
+ else
+ return getIntByByte(address);
+ }
public static long getLong(long address)
{
- return Architecture.IS_UNALIGNED ? unsafe.getLong(address) :
getLongByByte(address);
- }
+ if (Architecture.IS_UNALIGNED)
+ return Architecture.BIG_ENDIAN ?
Long.reverseBytes(unsafe.getLong(address)) : unsafe.getLong(address);
+ else
+ return getLongByByte(address);
+ }
public static ByteBuffer getByteBuffer(long address, int length)
{
@@ -247,7 +252,7 @@ public abstract class MemoryUtil
public static long getLongByByte(long address)
{
- if (BIG_ENDIAN)
+ if (Architecture.BIG_ENDIAN)
{
return (((long) unsafe.getByte(address ) ) << 56) |
(((long) unsafe.getByte(address + 1) & 0xff) << 48) |
@@ -273,7 +278,7 @@ public abstract class MemoryUtil
public static int getIntByByte(long address)
{
- if (BIG_ENDIAN)
+ if (Architecture.BIG_ENDIAN)
{
return (((int) unsafe.getByte(address ) ) << 24) |
(((int) unsafe.getByte(address + 1) & 0xff) << 16) |
@@ -292,7 +297,7 @@ public abstract class MemoryUtil
public static int getShortByByte(long address)
{
- if (BIG_ENDIAN)
+ if (Architecture.BIG_ENDIAN)
{
return (((int) unsafe.getByte(address ) ) << 8) |
(((int) unsafe.getByte(address + 1) & 0xff) );
@@ -306,7 +311,7 @@ public abstract class MemoryUtil
public static void putLongByByte(long address, long value)
{
- if (BIG_ENDIAN)
+ if (Architecture.BIG_ENDIAN)
{
unsafe.putByte(address, (byte) (value >> 56));
unsafe.putByte(address + 1, (byte) (value >> 48));
@@ -332,7 +337,7 @@ public abstract class MemoryUtil
public static void putIntByByte(long address, int value)
{
- if (BIG_ENDIAN)
+ if (Architecture.BIG_ENDIAN)
{
unsafe.putByte(address, (byte) (value >> 24));
unsafe.putByte(address + 1, (byte) (value >> 16));
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]