예제 #1
0
        public static int CountTimestamps(byte[] b, int startindex, int len)
        {
            if (b == null || b.Length < startindex + len)
            {
                return(0);
            }

            // Encoding type is stored in the 4 high bits of the first byte
            byte encoding = (byte)(b[startindex] >> 4);

            switch (encoding)
            {
            case TimeEncoder.timeUncompressed:
                // Uncompressed timestamps are just 8 bytes each
                return((len - 1) / 8);

            case TimeEncoder.timeCompressedRLE:
                // First 9 bytes are the starting timestamp and scaling factor, skip over them
                int j = startindex + 9;
                // Next 1-10 bytes is our (scaled down by factor of 10) run length values
                ulong value;
                j += Varint.Read(b, j, out value);
                // Last 1-10 bytes is how many times the value repeats
                Varint.Read(b, j, out value);
                return((int)value);

            case TimeEncoder.timeCompressedPackedSimple:
                // First 9 bytes are the starting timestamp and scaling factor, skip over them
                var count = Simple8bDecoder.CountBytes(b, startindex + 9, len - 9);
                return(count.Item1 + 1);    // +1 is for the first uncompressed timestamp, starting timestamep in b[1:9]

            default:
                return(0);
            }
        }
예제 #2
0
        private void decodePacked()
        {
            if (bytes == null || byteIndex >= endIndex)
            {
                return;
            }

            if (endIndex - byteIndex < 8)
            {
                err = "IntegerDecoder: not enough data to decode packed value";
                return;
            }

            ulong v = BitConverter.ToUInt64(bytes, byteIndex);

            // The first value is always unencoded
            if (first)
            {
                first     = false;
                n         = 1;
                values[0] = v;
            }
            else
            {
                var m = Simple8bDecoder.Decode(values, v);
                if (m.error != null)
                {
                    // Should never happen, only error that could be returned is if the the value to be decoded was not
                    // actually encoded by simple8b encoder.
                    err = string.Format("failed to decode value {0}: {1}", v, m.error);
                }
                n = m.Item1;
            }
            i          = 0;
            byteIndex += 8;
        }
예제 #3
0
        public (int, string) DecodeAll(Span <byte> b, Span <ulong> dst)
        {
            if (b.Length == 0)
            {
                return(0, null);
            }
            byte  encoding = (byte)(b[0] >> 4);
            ulong div      = (ulong)Math.Pow(10, b[0] & 0xF);

            b = b.Slice(1);
            if (encoding == timeUncompressed)
            {
                if ((b.Length & 0x7) != 0)
                {
                    return(0, "timeArrayDecodeAll: expected multiple of 8 bytes");
                }
                int   count = b.Length / 8;
                ulong prev  = 0;
                for (int i = 0; i < count; i++)
                {
                    prev  += BitConverter.ToUInt64(b);
                    dst[i] = prev;
                    b      = b.Slice(8);
                }
                return(count, null);
            }//uncompressed
            else if (encoding == timeCompressedPackedSimple)
            {
                if (b.Length < 8)
                {
                    return(0, "timeArrayDecodeAll: not enough data to decode packed value");
                }
                (int count, string err) = Simple8bDecoder.CountBytes(b.Slice(8));
                if (err != null)
                {
                    return(0, err);
                }
                count++;
                ulong[] bufarray = ArrayPool <ulong> .Shared.Rent(count);

                Span <ulong> buf = new Span <ulong>(bufarray, 0, count);
                //first value
                dst[0] = BitConverter.ToUInt64(b);
                var nerr = Simple8bDecoder.DecodeAll(buf.Slice(1), b.Slice(8));
                if (nerr.error != null)
                {
                    ArrayPool <ulong> .Shared.Return(bufarray);

                    return(0, err);
                }
                if (nerr.Item1 != count - 1)
                {
                    ArrayPool <ulong> .Shared.Return(bufarray);

                    return(0, String.Format("timeArrayDecodeAll: unexpected number of values decoded; got={0}, exp={1}", nerr.Item1, count - 1));
                }
                // Compute the prefix sum and scale the deltas back up
                var last = dst[0];
                if (div > 1)
                {
                    for (int i = 1; i < count; i++)
                    {
                        var dgap = buf[i] * div;
                        dst[i] = last + dgap;
                        last   = dst[i];
                    }
                }
                else
                {
                    for (int i = 1; i < count; i++)
                    {
                        dst[i] = buf[i] + last;
                        last   = dst[i];
                    }
                }
                ArrayPool <ulong> .Shared.Return(bufarray);

                return(count, null);
            }//simple.
            else if (encoding == timeCompressedRLE)
            {
                if (b.Length < 8)
                {
                    return(0, "timeArrayDecodeAll: not enough data to decode RLE starting value");
                }
                // Lower 4 bits hold the 10 based exponent so we can scale the values back up
                var   mod   = div;
                ulong first = BitConverter.ToUInt64(b);
                b = b.Slice(8);
                // Next 1-10 bytes is our (scaled down by factor of 10) run length delta
                int n = Varint.Read(b, out ulong delta);
                if (n <= 0)
                {
                    return(0, "timeArrayDecodeAll: invalid RLE delta value");
                }
                b = b.Slice(n);
                // Scale the delta back up
                delta *= mod;
                // Last 1-10 bytes is how many times the value repeats
                n = Varint.Read(b, out int count);
                if (n <= 0)
                {
                    return(0, "timeDecoder: invalid repeat value in decodeRLE");
                }

                var acc = first;
                for (int i = 0; i < count; i++)
                {
                    dst[i] = acc;
                    acc   += delta;
                }
                return(count, null);
            }//rle
            else
            {
                return(0, string.Format("unknown encoding {0:X2}", encoding));
            }
        }
예제 #4
0
        public (int, string) DecodeAll(Span <byte> b, Span <long> dst)
        {
            if (b.Length == 0)
            {
                return(0, null);
            }
            byte encoding = (byte)(b[0] >> 4);

            b = b.Slice(1);
            if (encoding == intUncompressed)
            {
                if ((b.Length & 0x7) != 0)
                {
                    return(0, "integerArrayDecodeAll: expected multiple of 8 bytes");
                }
                int  count = b.Length / 8;
                long prev  = 0;
                for (int i = 0; i < count; i++)
                {
                    prev  += Encoding.ZigZagDecode(BitConverter.ToUInt64(b));
                    dst[i] = prev;
                    b      = b.Slice(8);
                }
                return(count, null);
            }//uncompressed
            else if (encoding == intCompressedSimple)
            {
                if (b.Length < 8)
                {
                    return(0, "integerArrayDecodeAll: not enough data to decode packed value");
                }
                (int count, string err) = Simple8bDecoder.CountBytes(b.Slice(8));
                if (err != null)
                {
                    return(0, err);
                }
                count++;
                //first value
                dst[0] = Encoding.ZigZagDecode(BitConverter.ToUInt64(b));

                ulong[] bufarray = ArrayPool <ulong> .Shared.Rent(count);

                Span <ulong> buf  = new Span <ulong>(bufarray, 0, count);
                var          nerr = Simple8bDecoder.DecodeAll(buf.Slice(1), b.Slice(8));
                if (nerr.error != null)
                {
                    ArrayPool <ulong> .Shared.Return(bufarray);

                    return(0, err);
                }
                if (nerr.Item1 != count - 1)
                {
                    ArrayPool <ulong> .Shared.Return(bufarray);

                    return(0, String.Format("integerArrayDecodeAll: unexpected number of values decoded; got={0}, exp={1}", nerr.Item1, count - 1));
                }
                // calculate prefix sum
                var prev = dst[0];
                for (int i = 1; i < count; i++)
                {
                    prev  += Encoding.ZigZagDecode(buf[i]);
                    dst[i] = prev;
                }
                ArrayPool <ulong> .Shared.Return(bufarray);

                return(count, null);
            }//simple.
            else if (encoding == intCompressedRLE)
            {
                if (b.Length < 8)
                {
                    return(0, "integerArrayDecodeAll: not enough data to decode RLE starting value");
                }
                long first = Encoding.ZigZagDecode(BitConverter.ToUInt64(b));
                b = b.Slice(8);
                // Next 1-10 bytes is the delta value
                int n = Varint.Read(b, out ulong value);
                if (n <= 0)
                {
                    return(0, "integerArrayDecodeAll: invalid RLE delta value");
                }
                b = b.Slice(n);
                long delta = Encoding.ZigZagDecode(value);
                // Last 1-10 bytes is how many times the value repeats
                n = Varint.Read(b, out int count);
                if (n <= 0)
                {
                    return(0, "integerArrayDecodeAll: invalid RLE repeat value");
                }
                count++;
                if (delta == 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        dst[i] = first;
                    }
                }
                else
                {
                    long acc = first;
                    for (int i = 0; i < count; i++)
                    {
                        dst[i] = acc;
                        acc   += delta;
                    }
                }
                return(count, null);
            }//rle
            else
            {
                return(0, string.Format("unknown encoding {0:X2}", encoding));
            }
        }
예제 #5
0
 public TimeDecoder()
 {
     ts  = new List <ulong>();
     dec = new Simple8bDecoder();
 }