aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorsumansomasundar <suman.somasundar@oracle.com>2016-10-04 10:31:56 +0100
committerSean Owen <sowen@cloudera.com>2016-10-04 10:31:56 +0100
commit7d5160883542f3d9dcb3babda92880985398e9af (patch)
treed328424f28f76a1b1f46e5bf55b9ffb43988cf89 /common
parent8e8de0073d71bb00baeb24c612d7841b6274f652 (diff)
downloadspark-7d5160883542f3d9dcb3babda92880985398e9af.tar.gz
spark-7d5160883542f3d9dcb3babda92880985398e9af.tar.bz2
spark-7d5160883542f3d9dcb3babda92880985398e9af.zip
[SPARK-16962][CORE][SQL] Fix misaligned record accesses for SPARC architectures
## What changes were proposed in this pull request? Made changes to record length offsets to make them uniform throughout various areas of Spark core and unsafe ## How was this patch tested? This change affects only SPARC architectures and was tested on X86 architectures as well for regression. Author: sumansomasundar <suman.somasundar@oracle.com> Closes #14762 from sumansomasundar/master.
Diffstat (limited to 'common')
-rw-r--r--common/unsafe/src/main/java/org/apache/spark/unsafe/UnsafeAlignedOffset.java58
-rw-r--r--common/unsafe/src/main/java/org/apache/spark/unsafe/array/ByteArrayMethods.java31
2 files changed, 82 insertions, 7 deletions
diff --git a/common/unsafe/src/main/java/org/apache/spark/unsafe/UnsafeAlignedOffset.java b/common/unsafe/src/main/java/org/apache/spark/unsafe/UnsafeAlignedOffset.java
new file mode 100644
index 0000000000..be62e40412
--- /dev/null
+++ b/common/unsafe/src/main/java/org/apache/spark/unsafe/UnsafeAlignedOffset.java
@@ -0,0 +1,58 @@
+/*
+ * 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.spark.unsafe;
+
+/**
+ * Class to make changes to record length offsets uniform through out
+ * various areas of Apache Spark core and unsafe. The SPARC platform
+ * requires this because using a 4 byte Int for record lengths causes
+ * the entire record of 8 byte Items to become misaligned by 4 bytes.
+ * Using a 8 byte long for record length keeps things 8 byte aligned.
+ */
+public class UnsafeAlignedOffset {
+
+ private static final int UAO_SIZE = Platform.unaligned() ? 4 : 8;
+
+ public static int getUaoSize() {
+ return UAO_SIZE;
+ }
+
+ public static int getSize(Object object, long offset) {
+ switch (UAO_SIZE) {
+ case 4:
+ return Platform.getInt(object, offset);
+ case 8:
+ return (int)Platform.getLong(object, offset);
+ default:
+ throw new AssertionError("Illegal UAO_SIZE");
+ }
+ }
+
+ public static void putSize(Object object, long offset, int value) {
+ switch (UAO_SIZE) {
+ case 4:
+ Platform.putInt(object, offset, value);
+ break;
+ case 8:
+ Platform.putLong(object, offset, value);
+ break;
+ default:
+ throw new AssertionError("Illegal UAO_SIZE");
+ }
+ }
+}
diff --git a/common/unsafe/src/main/java/org/apache/spark/unsafe/array/ByteArrayMethods.java b/common/unsafe/src/main/java/org/apache/spark/unsafe/array/ByteArrayMethods.java
index cf42877bf9..9c551ab19e 100644
--- a/common/unsafe/src/main/java/org/apache/spark/unsafe/array/ByteArrayMethods.java
+++ b/common/unsafe/src/main/java/org/apache/spark/unsafe/array/ByteArrayMethods.java
@@ -40,6 +40,7 @@ public class ByteArrayMethods {
}
}
+ private static final boolean unaligned = Platform.unaligned();
/**
* Optimized byte array equality check for byte arrays.
* @return true if the arrays are equal, false otherwise
@@ -47,17 +48,33 @@ public class ByteArrayMethods {
public static boolean arrayEquals(
Object leftBase, long leftOffset, Object rightBase, long rightOffset, final long length) {
int i = 0;
- while (i <= length - 8) {
- if (Platform.getLong(leftBase, leftOffset + i) !=
- Platform.getLong(rightBase, rightOffset + i)) {
- return false;
+
+ // check if stars align and we can get both offsets to be aligned
+ if ((leftOffset % 8) == (rightOffset % 8)) {
+ while ((leftOffset + i) % 8 != 0 && i < length) {
+ if (Platform.getByte(leftBase, leftOffset + i) !=
+ Platform.getByte(rightBase, rightOffset + i)) {
+ return false;
+ }
+ i += 1;
+ }
+ }
+ // for architectures that suport unaligned accesses, chew it up 8 bytes at a time
+ if (unaligned || (((leftOffset + i) % 8 == 0) && ((rightOffset + i) % 8 == 0))) {
+ while (i <= length - 8) {
+ if (Platform.getLong(leftBase, leftOffset + i) !=
+ Platform.getLong(rightBase, rightOffset + i)) {
+ return false;
+ }
+ i += 8;
}
- i += 8;
}
+ // this will finish off the unaligned comparisons, or do the entire aligned
+ // comparison whichever is needed.
while (i < length) {
if (Platform.getByte(leftBase, leftOffset + i) !=
- Platform.getByte(rightBase, rightOffset + i)) {
- return false;
+ Platform.getByte(rightBase, rightOffset + i)) {
+ return false;
}
i += 1;
}