All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.lemire.integercompression.DeltaZigzagVariableByte Maven / Gradle / Ivy

Go to download

It is a library to compress and uncompress arrays of integers very fast. The assumption is that most (but not all) values in your array use less than 32 bits.

There is a newer version: 0.2.1
Show newest version
/*
 * This code is released under the
 * Apache License Version 2.0 http://www.apache.org/licenses/.
 */

package me.lemire.integercompression;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

/**
 * VariableByte with Delta+Zigzag Encoding.
 * 
 * @author MURAOKA Taro http://github.com/koron
 */
public final class DeltaZigzagVariableByte implements IntegerCODEC {

        @Override
        public String toString() {
                return DeltaZigzagVariableByte.class.getSimpleName();
        }

        @Override
        public void compress(int[] inBuf, IntWrapper inPos, int inLen,
                int[] outBuf, IntWrapper outPos) {
                if (inLen == 0) {
                        return;
                }

                ByteBuffer byteBuf = ByteBuffer.allocateDirect(inLen * 5 + 3);
                DeltaZigzagEncoding.Encoder ctx = new DeltaZigzagEncoding.Encoder(0);

                // Delta+Zigzag+VariableByte encoding.
                int ip = inPos.get();
                final int inPosLast = ip + inLen;
                for (; ip < inPosLast; ++ip) {
                        // Filter with delta+zigzag encoding.
                        int n = ctx.encodeInt(inBuf[ip]);
                        // Variable byte encoding.
                        switch (Integer.numberOfLeadingZeros(n)) {
                        case 0:
                        case 1:
                        case 2:
                        case 3:
                                byteBuf.put((byte) (((n >>> 28) & 0x7F) | 0x80));
                                // through.
                                //$FALL-THROUGH$
                        case 4:
                        case 5:
                        case 6:
                        case 7:
                        case 8:
                        case 9:
                        case 10:
                                byteBuf.put((byte) (((n >>> 21) & 0x7F) | 0x80));
                                // through.
                                //$FALL-THROUGH$
                        case 11:
                        case 12:
                        case 13:
                        case 14:
                        case 15:
                        case 16:
                        case 17:
                                byteBuf.put((byte) (((n >>> 14) & 0x7F) | 0x80));
                                // through.
                                //$FALL-THROUGH$
                        case 18:
                        case 19:
                        case 20:
                        case 21:
                        case 22:
                        case 23:
                        case 24:
                                byteBuf.put((byte) (((n >>> 7) & 0x7F) | 0x80));
                                // through.
                                //$FALL-THROUGH$
                        default:
                                byteBuf.put((byte) (n & 0x7F));
                        }
                }

                // Padding buffer to considerable as IntBuffer.
                for (int i = (4 - (byteBuf.position() % 4)) % 4; i > 0; --i) {
                        byteBuf.put((byte) (0x80));
                }

                int outLen = byteBuf.position() / 4;
                byteBuf.flip();
                IntBuffer intBuf = byteBuf.asIntBuffer();
                /*
                 * System.out.println(String.format(
                 * "inLen=%d pos=%d limit=%d outLen=%d outBuf.len=%d", inLen,
                 * intBuf.position(), intBuf.limit(), outLen, outBuf.length));
                 */
                intBuf.get(outBuf, outPos.get(), outLen);
                inPos.add(inLen);
                outPos.add(outLen);
        }

        @Override
        public void uncompress(int[] inBuf, IntWrapper inPos, int inLen,
                int[] outBuf, IntWrapper outPos) {
                DeltaZigzagEncoding.Decoder ctx = new DeltaZigzagEncoding.Decoder(0);

                int ip = inPos.get();
                int op = outPos.get();
                int vbcNum = 0, vbcShift = 24; // Varialbe Byte Context.
                final int inPosLast = ip + inLen;
                while (ip < inPosLast) {
                        // Fetch a byte value.
                        int n = (inBuf[ip] >>> vbcShift) & 0xFF;
                        if (vbcShift > 0) {
                                vbcShift -= 8;
                        } else {
                                vbcShift = 24;
                                ip++;
                        }
                        // Decode variable byte and delta+zigzag.
                        vbcNum = (vbcNum << 7) + (n & 0x7F);
                        if ((n & 0x80) == 0) {
                                outBuf[op++] = ctx.decodeInt(vbcNum);
                                vbcNum = 0;
                        }
                }

                outPos.set(op);
                inPos.set(inPosLast);
        }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy