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); } }
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; }
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)); } }
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)); } }
public TimeDecoder() { ts = new List <ulong>(); dec = new Simple8bDecoder(); }