X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.server%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fserver%2Finternal%2FClusterDecompressor.java;h=a4e9404364f0d68095096ff99f94bf6763ff7790;hb=HEAD;hp=1beaf2cda06b619bbd1fcaa8bbce49389e6099a1;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.server/src/org/simantics/db/server/internal/ClusterDecompressor.java b/bundles/org.simantics.db.server/src/org/simantics/db/server/internal/ClusterDecompressor.java index 1beaf2cda..a4e940436 100644 --- a/bundles/org.simantics.db.server/src/org/simantics/db/server/internal/ClusterDecompressor.java +++ b/bundles/org.simantics.db.server/src/org/simantics/db/server/internal/ClusterDecompressor.java @@ -1,157 +1,157 @@ -package org.simantics.db.server.internal; - -import java.nio.ByteBuffer; -import java.util.Arrays; - -import org.simantics.fastlz.FastLZ; -import org.simantics.fastlz.FastLZJava; - - -/** - * @author Tuukka Lehtonen - */ -public class ClusterDecompressor { - - private byte[] inflateBuffer; - - public Object[] inflateCluster(int inflateSize, ByteBuffer deflatedCluster) - throws CompressionException { - int deflatedSize = deflatedCluster.limit(); - Object[] arrays = new Object[3]; - int inflated = decompressCluster(deflatedCluster, deflatedSize, inflateSize, arrays); - if (inflated != inflateSize) - throw new CompressionException("decompression error, inflated " - + inflated + " bytes when " + inflateSize + " expected."); - return arrays; - } - - /** - * Wrapper for the old native direct byte buffer version of cluster - * decompression. - * - * @param deflated - * @param deflatedSize - * @param inflatedSize - * @param arrays - * expects an array of 3 elements. The decompression result will - * be stored in here. [0] = cluster long array (long[]), [1] = - * cluster int array (int[]), [2] = cluster byte array (byte[]). - * @return the amount of bytes inflated from the deflated cluster. Matches - * inflatedSize when successful. - * - * @see FastLZ#decompressCluster(ByteBuffer, int, int, Object[]) - */ - public int decompressCluster(ByteBuffer deflated, int deflatedSize, int inflatedSize, Object[] arrays) { - if (deflated.isDirect()) { - if (FastLZ.isNativeInitialized()) { - FastLZ.decompressCluster(deflated, deflatedSize, inflatedSize, arrays); - return inflatedSize; - } - // REALLY SLOW FALLBACK: java code for direct byte buffers - } - byte[] array = null; - if (deflated.hasArray()) { - array = deflated.array(); - } else { - // SLOW FALLBACK: read-only heap byte buffer - array = new byte[deflatedSize]; - int pos = deflated.position(); - deflated.position(0); - deflated.get(array, 0, deflatedSize); - deflated.position(pos); - } - return decompressCluster(array, deflatedSize, inflatedSize, arrays); - } - - /** - * @param deflated - * @param deflatedSize - * @param inflatedSize - * @param arrays - * @return - */ - public synchronized int decompressCluster(byte[] deflated, int deflatedSize, int inflatedSize, Object[] arrays) { - if (inflateBuffer == null) { - inflateBuffer = new byte[inflatedSize]; - } else if (inflateBuffer.length < inflatedSize) { - inflateBuffer = new byte[inflatedSize]; - } - return decompressCluster(deflated, deflatedSize, inflateBuffer, inflatedSize, arrays); - } - - /** - * @param deflated - * @param deflatedSize - * @param inflated - * @param inflatedSize - * @param arrays - * @return amount of bytes inflated from the original deflated buffer. - * Should match inflatedSize if everything went ok, otherwise will - * not. - */ - public static int decompressCluster(byte[] deflated, int deflatedSize, byte[] inflated, int inflatedSize, Object[] arrays) { - if (inflated.length < inflatedSize) - throw new IllegalArgumentException("inflate buffer size (" + inflated.length + ") is smaller than inflated size (" + inflatedSize + ")"); - - int decompressedBytes = FastLZJava.decompress(deflated, 0, deflatedSize, inflated, 0, inflatedSize); - if (decompressedBytes != inflatedSize) - return decompressedBytes; - - int offset = 0; - - int longCount = readInt(inflated, offset); - long[] longs = new long[longCount]; - copyLongs(inflated, offset + 4, longs); - offset += 4 + 8*longCount; - - int intCount = readInt(inflated, offset); - int[] ints = new int[intCount]; - copyInts(inflated, offset + 4, ints); - offset += 4 + 4*intCount; - - int byteCount = readInt(inflated, offset); - byte[] bytes = Arrays.copyOfRange(inflated, offset + 4, offset + 4 + byteCount); - - arrays[0] = longs; - arrays[1] = ints; - arrays[2] = bytes; - - return decompressedBytes; - } - - private static void copyInts(byte[] bytes, int i, int[] ints) { - int offset = i; - int count = ints.length; - for (int a = 0; a < count; ++a, offset += 4) { - int value = (((int) bytes[offset] & 0xff)) | - (((int) bytes[offset+1] & 0xff) << 8) | - (((int) bytes[offset+2] & 0xff) << 16) | - (((int) bytes[offset+3] & 0xff) << 24); - ints[a] = value; - } - } - - private static void copyLongs(byte[] bytes, int i, long[] longs) { - int offset = i; - int count = longs.length; - for (int a = 0; a < count; ++a, offset += 8) { - long value = (((long) bytes[offset] & 0xff)) | - (((long) bytes[offset+1] & 0xff) << 8) | - (((long) bytes[offset+2] & 0xff) << 16) | - (((long) bytes[offset+3] & 0xff) << 24) | - (((long) bytes[offset+4] & 0xff) << 32) | - (((long) bytes[offset+5] & 0xff) << 40) | - (((long) bytes[offset+6] & 0xff) << 48) | - (((long) bytes[offset+7] & 0xff) << 56); - longs[a] = value; - } - } - - private static int readInt(byte[] array, int offset) { - return (((int) array[offset] & 0xff)) | - (((int) array[offset+1] & 0xff) << 8) | - (((int) array[offset+2] & 0xff) << 16) | - (((int) array[offset+3] & 0xff) << 24); - } - -} +package org.simantics.db.server.internal; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +import org.simantics.fastlz.FastLZ; +import org.simantics.fastlz.FastLZJava; + + +/** + * @author Tuukka Lehtonen + */ +public class ClusterDecompressor { + + private byte[] inflateBuffer; + + public Object[] inflateCluster(int inflateSize, ByteBuffer deflatedCluster) + throws CompressionException { + int deflatedSize = deflatedCluster.limit(); + Object[] arrays = new Object[3]; + int inflated = decompressCluster(deflatedCluster, deflatedSize, inflateSize, arrays); + if (inflated != inflateSize) + throw new CompressionException("decompression error, inflated " + + inflated + " bytes when " + inflateSize + " expected."); + return arrays; + } + + /** + * Wrapper for the old native direct byte buffer version of cluster + * decompression. + * + * @param deflated + * @param deflatedSize + * @param inflatedSize + * @param arrays + * expects an array of 3 elements. The decompression result will + * be stored in here. [0] = cluster long array (long[]), [1] = + * cluster int array (int[]), [2] = cluster byte array (byte[]). + * @return the amount of bytes inflated from the deflated cluster. Matches + * inflatedSize when successful. + * + * @see FastLZ#decompressCluster(ByteBuffer, int, int, Object[]) + */ + public int decompressCluster(ByteBuffer deflated, int deflatedSize, int inflatedSize, Object[] arrays) { + if (deflated.isDirect()) { + if (FastLZ.isNativeInitialized()) { + FastLZ.decompressCluster(deflated, deflatedSize, inflatedSize, arrays); + return inflatedSize; + } + // REALLY SLOW FALLBACK: java code for direct byte buffers + } + byte[] array = null; + if (deflated.hasArray()) { + array = deflated.array(); + } else { + // SLOW FALLBACK: read-only heap byte buffer + array = new byte[deflatedSize]; + int pos = deflated.position(); + deflated.position(0); + deflated.get(array, 0, deflatedSize); + deflated.position(pos); + } + return decompressCluster(array, deflatedSize, inflatedSize, arrays); + } + + /** + * @param deflated + * @param deflatedSize + * @param inflatedSize + * @param arrays + * @return + */ + public synchronized int decompressCluster(byte[] deflated, int deflatedSize, int inflatedSize, Object[] arrays) { + if (inflateBuffer == null) { + inflateBuffer = new byte[inflatedSize]; + } else if (inflateBuffer.length < inflatedSize) { + inflateBuffer = new byte[inflatedSize]; + } + return decompressCluster(deflated, deflatedSize, inflateBuffer, inflatedSize, arrays); + } + + /** + * @param deflated + * @param deflatedSize + * @param inflated + * @param inflatedSize + * @param arrays + * @return amount of bytes inflated from the original deflated buffer. + * Should match inflatedSize if everything went ok, otherwise will + * not. + */ + public static int decompressCluster(byte[] deflated, int deflatedSize, byte[] inflated, int inflatedSize, Object[] arrays) { + if (inflated.length < inflatedSize) + throw new IllegalArgumentException("inflate buffer size (" + inflated.length + ") is smaller than inflated size (" + inflatedSize + ")"); + + int decompressedBytes = FastLZJava.decompress(deflated, 0, deflatedSize, inflated, 0, inflatedSize); + if (decompressedBytes != inflatedSize) + return decompressedBytes; + + int offset = 0; + + int longCount = readInt(inflated, offset); + long[] longs = new long[longCount]; + copyLongs(inflated, offset + 4, longs); + offset += 4 + 8*longCount; + + int intCount = readInt(inflated, offset); + int[] ints = new int[intCount]; + copyInts(inflated, offset + 4, ints); + offset += 4 + 4*intCount; + + int byteCount = readInt(inflated, offset); + byte[] bytes = Arrays.copyOfRange(inflated, offset + 4, offset + 4 + byteCount); + + arrays[0] = longs; + arrays[1] = ints; + arrays[2] = bytes; + + return decompressedBytes; + } + + private static void copyInts(byte[] bytes, int i, int[] ints) { + int offset = i; + int count = ints.length; + for (int a = 0; a < count; ++a, offset += 4) { + int value = (((int) bytes[offset] & 0xff)) | + (((int) bytes[offset+1] & 0xff) << 8) | + (((int) bytes[offset+2] & 0xff) << 16) | + (((int) bytes[offset+3] & 0xff) << 24); + ints[a] = value; + } + } + + private static void copyLongs(byte[] bytes, int i, long[] longs) { + int offset = i; + int count = longs.length; + for (int a = 0; a < count; ++a, offset += 8) { + long value = (((long) bytes[offset] & 0xff)) | + (((long) bytes[offset+1] & 0xff) << 8) | + (((long) bytes[offset+2] & 0xff) << 16) | + (((long) bytes[offset+3] & 0xff) << 24) | + (((long) bytes[offset+4] & 0xff) << 32) | + (((long) bytes[offset+5] & 0xff) << 40) | + (((long) bytes[offset+6] & 0xff) << 48) | + (((long) bytes[offset+7] & 0xff) << 56); + longs[a] = value; + } + } + + private static int readInt(byte[] array, int offset) { + return (((int) array[offset] & 0xff)) | + (((int) array[offset+1] & 0xff) << 8) | + (((int) array[offset+2] & 0xff) << 16) | + (((int) array[offset+3] & 0xff) << 24); + } + +}