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]

Reply via email to