Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one or more
0003  * contributor license agreements.  See the NOTICE file distributed with
0004  * this work for additional information regarding copyright ownership.
0005  * The ASF licenses this file to You under the Apache License, Version 2.0
0006  * (the "License"); you may not use this file except in compliance with
0007  * the License.  You may obtain a copy of the License at
0008  *
0009  *    http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  */
0017 
0018 package org.apache.spark.unsafe.array;
0019 
0020 import org.apache.spark.unsafe.Platform;
0021 
0022 public class ByteArrayMethods {
0023 
0024   private ByteArrayMethods() {
0025     // Private constructor, since this class only contains static methods.
0026   }
0027 
0028   /** Returns the next number greater or equal num that is power of 2. */
0029   public static long nextPowerOf2(long num) {
0030     final long highBit = Long.highestOneBit(num);
0031     return (highBit == num) ? num : highBit << 1;
0032   }
0033 
0034   public static int roundNumberOfBytesToNearestWord(int numBytes) {
0035     return (int)roundNumberOfBytesToNearestWord((long)numBytes);
0036   }
0037 
0038   public static long roundNumberOfBytesToNearestWord(long numBytes) {
0039     long remainder = numBytes & 0x07;  // This is equivalent to `numBytes % 8`
0040     if (remainder == 0) {
0041       return numBytes;
0042     } else {
0043       return numBytes + (8 - remainder);
0044     }
0045   }
0046 
0047   // Some JVMs can't allocate arrays of length Integer.MAX_VALUE; actual max is somewhat smaller.
0048   // Be conservative and lower the cap a little.
0049   // Refer to "http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/util/ArrayList.java#l229"
0050   // This value is word rounded. Use this value if the allocated byte arrays are used to store other
0051   // types rather than bytes.
0052   public static int MAX_ROUNDED_ARRAY_LENGTH = Integer.MAX_VALUE - 15;
0053 
0054   private static final boolean unaligned = Platform.unaligned();
0055   /**
0056    * Optimized byte array equality check for byte arrays.
0057    * @return true if the arrays are equal, false otherwise
0058    */
0059   public static boolean arrayEquals(
0060       Object leftBase, long leftOffset, Object rightBase, long rightOffset, final long length) {
0061     int i = 0;
0062 
0063     // check if stars align and we can get both offsets to be aligned
0064     if ((leftOffset % 8) == (rightOffset % 8)) {
0065       while ((leftOffset + i) % 8 != 0 && i < length) {
0066         if (Platform.getByte(leftBase, leftOffset + i) !=
0067             Platform.getByte(rightBase, rightOffset + i)) {
0068               return false;
0069         }
0070         i += 1;
0071       }
0072     }
0073     // for architectures that support unaligned accesses, chew it up 8 bytes at a time
0074     if (unaligned || (((leftOffset + i) % 8 == 0) && ((rightOffset + i) % 8 == 0))) {
0075       while (i <= length - 8) {
0076         if (Platform.getLong(leftBase, leftOffset + i) !=
0077             Platform.getLong(rightBase, rightOffset + i)) {
0078               return false;
0079         }
0080         i += 8;
0081       }
0082     }
0083     // this will finish off the unaligned comparisons, or do the entire aligned
0084     // comparison whichever is needed.
0085     while (i < length) {
0086       if (Platform.getByte(leftBase, leftOffset + i) !=
0087           Platform.getByte(rightBase, rightOffset + i)) {
0088             return false;
0089       }
0090       i += 1;
0091     }
0092     return true;
0093   }
0094 }