mirror of
https://github.com/xerial/snappy-java.git
synced 2025-04-08 19:35:08 +02:00
266 lines
9.5 KiB
Java
266 lines
9.5 KiB
Java
/*--------------------------------------------------------------------------
|
|
* Copyright 2011 Taro L. Saito
|
|
*
|
|
* Licensed 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.
|
|
*--------------------------------------------------------------------------*/
|
|
//--------------------------------------
|
|
// snappy-java Project
|
|
//
|
|
// BitShuffle.java
|
|
// Since: 2016/03/31
|
|
//
|
|
// $URL$
|
|
// $Author$
|
|
//--------------------------------------
|
|
package org.xerial.snappy;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
|
|
public class BitShuffle
|
|
{
|
|
static {
|
|
try {
|
|
impl = SnappyLoader.loadBitShuffleApi();
|
|
}
|
|
catch (Exception e) {
|
|
throw new ExceptionInInitializerError(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An instance of BitShuffleNative
|
|
*/
|
|
private static BitShuffleNative impl;
|
|
|
|
/**
|
|
* Apply a bit-shuffling filter into the content in the given input buffer. After bit-shuffling,
|
|
* you can retrieve the shuffled data from the output buffer [pos() ...limit())
|
|
* (shuffled data size = limit() - pos() = remaining()).
|
|
*
|
|
* @param input buffer[pos() ... limit()) containing the input data
|
|
* @param type element type of the input data
|
|
* @param shuffled output of the shuffled data. Uses range [pos()..].
|
|
* @return byte size of the shuffled data.
|
|
* @throws SnappyError when the input is not a direct buffer
|
|
* @throws IllegalArgumentException when the input length is not a multiple of the given type size
|
|
*/
|
|
public static int shuffle(ByteBuffer input, BitShuffleType type, ByteBuffer shuffled) throws IOException {
|
|
if (!input.isDirect()) {
|
|
throw new SnappyError(SnappyErrorCode.NOT_A_DIRECT_BUFFER, "input is not a direct buffer");
|
|
}
|
|
if (!shuffled.isDirect()) {
|
|
throw new SnappyError(SnappyErrorCode.NOT_A_DIRECT_BUFFER, "destination is not a direct buffer");
|
|
}
|
|
|
|
// input: input[pos(), limit())
|
|
// output: shuffled
|
|
int uPos = input.position();
|
|
int uLen = input.remaining();
|
|
int typeSize = type.getTypeSize();
|
|
if (uLen % typeSize != 0) {
|
|
throw new IllegalArgumentException("input length must be a multiple of the given type size: " + typeSize);
|
|
}
|
|
if (shuffled.remaining() < uLen) {
|
|
throw new IllegalArgumentException("not enough space for output");
|
|
}
|
|
int numProcessed = impl.shuffleDirectBuffer(input, uPos, typeSize, uLen, shuffled, shuffled.position());
|
|
assert(numProcessed == uLen);
|
|
|
|
// pos limit
|
|
// [ ......BBBBBBB.........]
|
|
shuffled.limit(shuffled.position() + numProcessed);
|
|
return numProcessed;
|
|
}
|
|
|
|
/**
|
|
* Apply a bit-shuffling filter into the input short array.
|
|
*
|
|
* @param input
|
|
* @return bit-shuffled byte array
|
|
* @throws IOException
|
|
*/
|
|
public static byte[] shuffle(short[] input) throws IOException {
|
|
byte[] output = new byte[input.length * 2];
|
|
int numProcessed = impl.shuffle(input, 0, 2, input.length * 2, output, 0);
|
|
assert(numProcessed == input.length * 2);
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Apply a bit-shuffling filter into the input int array.
|
|
*
|
|
* @param input
|
|
* @return bit-shuffled byte array
|
|
* @throws IOException
|
|
*/
|
|
public static byte[] shuffle(int[] input) throws IOException {
|
|
byte[] output = new byte[input.length * 4];
|
|
int numProcessed = impl.shuffle(input, 0, 4, input.length * 4, output, 0);
|
|
assert(numProcessed == input.length * 4);
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Apply a bit-shuffling filter into the input long array.
|
|
*
|
|
* @param input
|
|
* @return bit-shuffled byte array
|
|
* @throws IOException
|
|
*/
|
|
public static byte[] shuffle(long[] input) throws IOException {
|
|
byte[] output = new byte[input.length * 8];
|
|
int numProcessed = impl.shuffle(input, 0, 8, input.length * 8, output, 0);
|
|
assert(numProcessed == input.length * 8);
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Apply a bit-shuffling filter into the input float array.
|
|
*
|
|
* @param input
|
|
* @return bit-shuffled byte array
|
|
* @throws IOException
|
|
*/
|
|
public static byte[] shuffle(float[] input) throws IOException {
|
|
byte[] output = new byte[input.length * 4];
|
|
int numProcessed = impl.shuffle(input, 0, 4, input.length * 4, output, 0);
|
|
assert(numProcessed == input.length * 4);
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Apply a bit-shuffling filter into the input double array.
|
|
*
|
|
* @param input
|
|
* @return bit-shuffled byte array
|
|
* @throws IOException
|
|
*/
|
|
public static byte[] shuffle(double[] input) throws IOException {
|
|
byte[] output = new byte[input.length * 8];
|
|
int numProcessed = impl.shuffle(input, 0, 8, input.length * 8, output, 0);
|
|
assert(numProcessed == input.length * 8);
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Convert the input bit-shuffled byte array into an original array. The result is dumped
|
|
* to the specified output buffer.
|
|
*
|
|
* @param shuffled buffer[pos() ... limit()) containing the input shuffled data
|
|
* @param type element type of the input data
|
|
* @param output output of the the original data. It uses buffer[pos()..]
|
|
* @return byte size of the unshuffled data.
|
|
* @throws IOException when failed to unshuffle the given input
|
|
* @throws SnappyError when the input is not a direct buffer
|
|
* @throws IllegalArgumentException when the length of input shuffled data is not a multiple of the given type size
|
|
*/
|
|
public static int unshuffle(ByteBuffer shuffled, BitShuffleType type, ByteBuffer output) throws IOException {
|
|
if (!shuffled.isDirect()) {
|
|
throw new SnappyError(SnappyErrorCode.NOT_A_DIRECT_BUFFER, "input is not a direct buffer");
|
|
}
|
|
if (!output.isDirect()) {
|
|
throw new SnappyError(SnappyErrorCode.NOT_A_DIRECT_BUFFER, "destination is not a direct buffer");
|
|
}
|
|
|
|
// input: input[pos(), limit())
|
|
// output: shuffled
|
|
int uPos = shuffled.position();
|
|
int uLen = shuffled.remaining();
|
|
int typeSize = type.getTypeSize();
|
|
if (uLen % typeSize != 0) {
|
|
throw new IllegalArgumentException("length of input shuffled data must be a multiple of the given type size: " + typeSize);
|
|
}
|
|
if (output.remaining() < uLen) {
|
|
throw new IllegalArgumentException("not enough space for output");
|
|
}
|
|
int numProcessed = impl.unshuffleDirectBuffer(shuffled, uPos, typeSize, uLen, output, shuffled.position());
|
|
assert(numProcessed == uLen);
|
|
|
|
// pos limit
|
|
// [ ......BBBBBBB.........]
|
|
shuffled.limit(shuffled.position() + numProcessed);
|
|
return numProcessed;
|
|
}
|
|
|
|
/**
|
|
* Convert the input bit-shuffled byte array into an original short array.
|
|
*
|
|
* @param input
|
|
* @return a short array
|
|
* @throws IOException
|
|
*/
|
|
public static short[] unshuffleShortArray(byte[] input) throws IOException {
|
|
short[] output = new short[input.length / 2];
|
|
int numProcessed = impl.unshuffle(input, 0, 2, input.length, output, 0);
|
|
assert(numProcessed == input.length);
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Convert the input bit-shuffled byte array into an original int array.
|
|
*
|
|
* @param input
|
|
* @return an int array
|
|
* @throws IOException
|
|
*/
|
|
public static int[] unshuffleIntArray(byte[] input) throws IOException {
|
|
int[] output = new int[input.length / 4];
|
|
int numProcessed = impl.unshuffle(input, 0, 4, input.length, output, 0);
|
|
assert(numProcessed == input.length);
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Convert the input bit-shuffled byte array into an original long array.
|
|
*
|
|
* @param input
|
|
* @return a long array
|
|
* @throws IOException
|
|
*/
|
|
public static long[] unshuffleLongArray(byte[] input) throws IOException {
|
|
long[] output = new long[input.length / 8];
|
|
int numProcessed = impl.unshuffle(input, 0, 8, input.length, output, 0);
|
|
assert(numProcessed == input.length);
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Convert the input bit-shuffled byte array into an original float array.
|
|
*
|
|
* @param input
|
|
* @return an float array
|
|
* @throws IOException
|
|
*/
|
|
public static float[] unshuffleFloatArray(byte[] input) throws IOException {
|
|
float[] output = new float[input.length / 4];
|
|
int numProcessed = impl.unshuffle(input, 0, 4, input.length, output, 0);
|
|
assert(numProcessed == input.length);
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Convert the input bit-shuffled byte array into an original double array.
|
|
*
|
|
* @param input
|
|
* @return a double array
|
|
* @throws IOException
|
|
*/
|
|
public static double[] unshuffleDoubleArray(byte[] input) throws IOException {
|
|
double[] output = new double[input.length / 8];
|
|
int numProcessed = impl.unshuffle(input, 0, 8, input.length, output, 0);
|
|
assert(numProcessed == input.length);
|
|
return output;
|
|
}
|
|
}
|