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.types;
0019 
0020 import java.util.Arrays;
0021 
0022 import com.google.common.primitives.Ints;
0023 
0024 import org.apache.spark.unsafe.Platform;
0025 
0026 public final class ByteArray {
0027 
0028   public static final byte[] EMPTY_BYTE = new byte[0];
0029 
0030   /**
0031    * Writes the content of a byte array into a memory address, identified by an object and an
0032    * offset. The target memory address must already been allocated, and have enough space to
0033    * hold all the bytes in this string.
0034    */
0035   public static void writeToMemory(byte[] src, Object target, long targetOffset) {
0036     Platform.copyMemory(src, Platform.BYTE_ARRAY_OFFSET, target, targetOffset, src.length);
0037   }
0038 
0039   /**
0040    * Returns a 64-bit integer that can be used as the prefix used in sorting.
0041    */
0042   public static long getPrefix(byte[] bytes) {
0043     if (bytes == null) {
0044       return 0L;
0045     } else {
0046       final int minLen = Math.min(bytes.length, 8);
0047       long p = 0;
0048       for (int i = 0; i < minLen; ++i) {
0049         p |= ((long) Platform.getByte(bytes, Platform.BYTE_ARRAY_OFFSET + i) & 0xff)
0050             << (56 - 8 * i);
0051       }
0052       return p;
0053     }
0054   }
0055 
0056   public static byte[] subStringSQL(byte[] bytes, int pos, int len) {
0057     // This pos calculation is according to UTF8String#subStringSQL
0058     if (pos > bytes.length) {
0059       return EMPTY_BYTE;
0060     }
0061     int start = 0;
0062     int end;
0063     if (pos > 0) {
0064       start = pos - 1;
0065     } else if (pos < 0) {
0066       start = bytes.length + pos;
0067     }
0068     if ((bytes.length - start) < len) {
0069       end = bytes.length;
0070     } else {
0071       end = start + len;
0072     }
0073     start = Math.max(start, 0); // underflow
0074     if (start >= end) {
0075       return EMPTY_BYTE;
0076     }
0077     return Arrays.copyOfRange(bytes, start, end);
0078   }
0079 
0080   public static byte[] concat(byte[]... inputs) {
0081     // Compute the total length of the result
0082     long totalLength = 0;
0083     for (int i = 0; i < inputs.length; i++) {
0084       if (inputs[i] != null) {
0085         totalLength += (long)inputs[i].length;
0086       } else {
0087         return null;
0088       }
0089     }
0090 
0091     // Allocate a new byte array, and copy the inputs one by one into it
0092     final byte[] result = new byte[Ints.checkedCast(totalLength)];
0093     int offset = 0;
0094     for (int i = 0; i < inputs.length; i++) {
0095       int len = inputs[i].length;
0096       Platform.copyMemory(
0097         inputs[i], Platform.BYTE_ARRAY_OFFSET,
0098         result, Platform.BYTE_ARRAY_OFFSET + offset,
0099         len);
0100       offset += len;
0101     }
0102     return result;
0103   }
0104 }