Ejemplo n.º 1
0
            public static Helper Deserialize(BinaryReader reader)
            {
                Helper helper = new Helper();

                byte b = reader.ReadByte();

                helper.Sign           = (b & 0x80) != 0;
                helper.IsReady        = (b & 0x40) != 0;
                helper.AlwaysUseDelta = (b & 0x20) != 0;
                helper.Type           = (HelperType)(b & 0x1f);

                if (helper.Type == HelperType.Raw)
                {
                    return(helper);
                }

                if (helper.Type == HelperType.OneStep)
                {
                    helper.Delta = CountCompression.Deserialize(reader);
                    return(helper);
                }

                helper.DeltaBits = reader.ReadByte();
                helper.Delta     = (1UL << helper.DeltaBits) - 1;

                return(helper);
            }
Ejemplo n.º 2
0
        public static IList <long> CoreDecompress(BinaryReader reader)
        {
            int          resLength = (int)CountCompression.Deserialize(reader);
            IList <long> res       = new List <long>(resLength);

            if (resLength < 2)
            {
                if (resLength == 1)
                {
                    res.Add(reader.ReadInt64());
                }
                return(res);
            }

            //read the first element
            res.Add(reader.ReadInt64());

            int bytesCount = (int)CountCompression.Deserialize(reader);

            ulong[] tmpData = new ulong[(int)Math.Ceiling(bytesCount / 8.0)];
            for (int j = 0; j < tmpData.Length; j++)
            {
                tmpData[j] = reader.ReadUInt64();
            }

            int bitIndex = 0, i;

            //is data monote?
            ulong monotoneFlag = GetBits(tmpData, bitIndex, 2);

            bitIndex += 2;

            //have we only one delta?
            bool useOneDelta = GetBits(tmpData, bitIndex, 1) == 1;

            bitIndex++;

            int   smallDeltaBits = 0, bigDeltaBits = 0;
            long  delta = 0;
            ulong useOneDeltaType = 0, sign;

            if (useOneDelta)
            {
                //how many bits is the delta, what is it value?
                bigDeltaBits = (int)GetBits(tmpData, bitIndex, 7);
                bitIndex    += 7;

                delta     = (long)GetBits(tmpData, bitIndex, bigDeltaBits);
                bitIndex += bigDeltaBits;
            }
            else
            {
                //how many types of delta we use - one or two. What are they?
                useOneDeltaType = GetBits(tmpData, bitIndex, 1);
                bitIndex++;

                bigDeltaBits = (int)GetBits(tmpData, bitIndex, 7);
                bitIndex    += 7;

                if (useOneDeltaType == 0)
                {
                    smallDeltaBits = (int)GetBits(tmpData, bitIndex, 7);
                    bitIndex      += 7;
                }
            }

            if (useOneDelta)
            {
                sign = monotoneFlag & 1;
                if (sign == 0)
                {
                    for (i = 1; i < resLength; i++)
                    {
                        res.Add(res[i - 1] + delta);
                    }
                }
                else
                {
                    for (i = 1; i < resLength; i++)
                    {
                        res.Add(res[i - 1] - delta);
                    }
                }
            }
            else
            {
                for (i = 1; i < resLength; i++)
                {
                    int actualDeltaBits = bigDeltaBits;
                    if (useOneDeltaType == 0)
                    {
                        ulong deltaType = GetBits(tmpData, bitIndex, 1);
                        bitIndex++;
                        if (deltaType == 0)
                        {
                            actualDeltaBits = smallDeltaBits;
                        }
                    }

                    if (monotoneFlag == 0)
                    {
                        sign = GetBits(tmpData, bitIndex, 1);
                        bitIndex++;
                    }
                    else
                    {
                        sign = monotoneFlag & 1;
                    }

                    delta     = (long)GetBits(tmpData, bitIndex, actualDeltaBits);
                    bitIndex += actualDeltaBits;
                    res.Add(res[i - 1] + ((sign == 0) ? delta : -delta));
                }
            }

            return(res);
        }
Ejemplo n.º 3
0
        public static void Decompress(BinaryReader reader, Action <int, long> values, int count)
        {
            if (reader.ReadByte() != VERSION)
            {
                throw new Exception("Invalid delta compression version.");
            }

            if (count == 0)
            {
                return;
            }

            int index = 0;

            long value = (long)CountCompression.Deserialize(reader);

            values(index, value);
            if (count == 1)
            {
                return;
            }

            var helper = Helper.Deserialize(reader);

            index++;
            count--;
            int maxIndex = index + count - 1;

            if (helper.Type == HelperType.Raw)
            {
                while (index <= maxIndex)
                {
                    values(index++, reader.ReadInt64());
                }

                return;
            }

            if (helper.Type == HelperType.OneStep)
            {
                long step = (long)helper.Delta;

                if (helper.Sign == false)
                {
                    while (index <= maxIndex)
                    {
                        values(index++, (value += step));
                    }
                }
                else
                {
                    while (index <= maxIndex)
                    {
                        values(index++, (value -= step));
                    }
                }

                return;
            }

            bool  readSign       = helper.Type == HelperType.Delta;
            ulong maxDelta       = helper.Delta;
            bool  alwaysUseDelta = helper.AlwaysUseDelta;
            bool  sign           = helper.Sign;
            int   bitCount       = helper.DeltaBits;

            CommonArray common     = new CommonArray();
            int         bytesCount = (int)CountCompression.Deserialize(reader);

            common.ByteArray = reader.ReadBytes(bytesCount);
            ulong[] data     = common.UInt64Array;
            int     bitIndex = 0;

            for (; index <= maxIndex; index++)
            {
                long newValue;
                bool useDelta = alwaysUseDelta || GetFlag(data, bitIndex++);

                if (useDelta)
                {
                    if (readSign)
                    {
                        sign = GetFlag(data, bitIndex);
                        bitIndex++;
                    }

                    long delta = (long)GetBits(data, bitIndex, bitCount);
                    bitIndex += bitCount;

                    newValue = sign ? value - delta : value + delta;
                }
                else
                {
                    newValue  = (long)GetValue(data, bitIndex);
                    bitIndex += 64;
                }

                values(index, newValue);
                value = newValue;
            }
        }