public static int decompress(byte dataType, int valCount, long inputAddr, long outputAddr, int outputLimit) {
        int dictEntryCount = getInt(inputAddr);
        boolean isDictEntryCompressed = getByte(inputAddr + 4) != 0;
        Codec dictEntryCodec = isDictEntryCompressed ? new DeltaCodec() : new PlainCodec();
        setInt(outputAddr, dictEntryCount);
        int dictEntryConsumedSize;
        int dictSize;
        switch (dataType) {
            case DataType.INT:
                dictEntryConsumedSize = dictEntryCodec.decodeInts(
                        dictEntryCount,
                        inputAddr + (4 + 1),
                        outputAddr + 4,
                        outputLimit - 4);
                dictSize = dictEntryCount << 2;
                break;
            case DataType.LONG:
                dictEntryConsumedSize = dictEntryCodec.decodeLongs(
                        dictEntryCount,
                        inputAddr + (4 + 1),
                        outputAddr + 4,
                        outputLimit - 4);
                dictSize = dictEntryCount << 3;
                break;
            case DataType.FLOAT:
                dictEntryConsumedSize = dictEntryCodec.decodeFloats(
                        dictEntryCount,
                        inputAddr + (4 + 1),
                        outputAddr + 4,
                        outputLimit - 4);
                dictSize = dictEntryCount << 2;
                break;
            case DataType.DOUBLE:
                dictEntryConsumedSize = dictEntryCodec.decodeDoubles(
                        dictEntryCount,
                        inputAddr + (4 + 1),
                        outputAddr + 4,
                        outputLimit - 4);
                dictSize = dictEntryCount << 3;
                break;
            case DataType.STRING:
                dictEntryConsumedSize = dictEntryCodec.decodeStrings(
                        dictEntryCount,
                        inputAddr + (4 + 1),
                        outputAddr + 4,
                        outputLimit - 4);
                dictSize = new StringsStruct(dictEntryCount, outputAddr + 4).totalLen();
                break;
            default:
                throw new RuntimeException("Illegal type: " + dataType);
        }
        Codec dataCodec = new RLEPackingHybridCodec(VarInteger.bitWidth(dictEntryCount - 1));
        setInt(outputAddr + 4 + dictSize, valCount << 2);
        int dataConsumedSize = dataCodec.decodeInts(
                valCount,
                inputAddr + (4 + 1) + dictEntryConsumedSize,
                outputAddr + 4 + dictSize + 4,
                outputLimit - (4 + dictSize + 4));
        return 4 + 1 + dictEntryConsumedSize + dataConsumedSize;
    }
<pre>
|  dictEntryCount | isDictEntryCompressed | dictEntryData | compressed value data(entry ids) |
         4                   1                  size?                size?
</pre>
indexr-vlt-segment/src/main/java/io/indexr/vlt/codec/dict/DictStructUtil.java