Ejemplo n.º 1
0
 /// <summary>
 /// AppendTo writes a binary-encoded version of IndexEntry to b.
 /// </summary>
 /// <param name="b"></param>
 public void AppendTo(ByteWriter b)
 {
     b.Write(MinTime);
     b.Write(MaxTime);
     b.Write(Offset);
     b.Write(Size);
 }
Ejemplo n.º 2
0
            public long WriteTo(ByteWriter w)
            {
                long         N    = 0;
                List <ulong> sids = new List <ulong>(blocks.Keys);

                sids.Sort();
                foreach (ulong sid in sids)
                {
                    IndexEntries entries = blocks[sid];
                    if (entries.Len() > Constants.maxIndexEntries)
                    {
                        throw new ArgumentOutOfRangeException(
                                  string.Format("sid {0} exceeds max index entries: {1} > {2}",
                                                sid, entries.Len(), Constants.maxIndexEntries));
                    }
                    entries.Entries.Sort();
                    w.Write(sid);
                    N += 8;
                    w.Write(entries.Type);
                    N += 1;
                    w.Write((ushort)entries.Len());
                    N += 2;
                    N += entries.WriteTo(w);
                }
                return(N);
            }
Ejemplo n.º 3
0
        public (ByteWriter, string) EncodingAll(Span <bool> src_span)
        {
            int        srclen = src_span.Length;
            int        sz     = 1 + 8 + (srclen + 7) / 8;//header+num bools+bool data
            ByteWriter result = new ByteWriter(sz);

            // Store the encoding type in the 4 high bits of the first byte
            result.Write((byte)(booleanCompressedBitPacked << 4));
            // Encode the number of booleans written.
            result.Write(Varint.GetBytes(srclen));
            int         bitcount    = result.Length * 8;                  // Current bit in current byte.
            Span <byte> result_span = new Span <byte>(result.EndWrite()); //取出数组

            for (int i = 0; i < srclen; i++)
            {
                bool v = src_span[i];
                if (v)
                {
                    result_span[n >> 3] |= (byte)(128 >> (bitcount & 7));
                }// Set current bit on current byte.
                else
                {
                    result_span[n >> 3] = (byte)(result_span[n >> 3] & ~(byte)(128 >> (bitcount & 7)));
                }// Clear current bit on current byte.
                bitcount++;
            }
            int length = bitcount >> 3;

            if ((bitcount & 7) > 0)
            {
                length++;// Add an extra byte to capture overflowing bits.
            }
            result.Length = length;
            return(result, null);
        }
Ejemplo n.º 4
0
        // Bytes returns a copy of the underlying buffer.
        public (ByteWriter, string) Bytes()
        {
            // Compress the currently appended bytes using snappy and prefix with
            // a 1 byte header for future extension
            ByteWriter result = new ByteWriter(bytes.Count + 1);

            result.Write((byte)(stringCompressedSnappy << 4));
            //TODO: ToArray 多了一次拷贝,怎么避免?
            result.Write(SnappyPI.SnappyCodec.Compress(bytes.ToArray(), 0, bytes.Count));
            return(result, null);
        }
Ejemplo n.º 5
0
        private (ByteWriter, string error) encodeRaw()
        {
            int sz = 1 + len * 8;

            ByteWriter b = new ByteWriter(sz);

            b.Write((byte)(timeUncompressed << 4));
            for (int i = 0; i < len; i++)
            {
                b.Write(ts[i]);
            }
            return(b, null);
        }
Ejemplo n.º 6
0
        public ByteWriter Marshal(out string err)
        {
            err = null;
            int        size   = MarshalSize();
            ByteWriter writer = new ByteWriter(size);

            writer.Write(Min);
            writer.Write(Max);
            foreach (ulong sid in Sids)
            {
                writer.Write(sid);
            }
            return(writer);
        }
Ejemplo n.º 7
0
        private (ByteWriter, string error) encodeUncompressed()
        {
            if (len == 0)
            {
                return(null, null);
            }
            ByteWriter b = new ByteWriter(1 + len * 8);

            b.Write((byte)(intUncompressed << 4));
            for (int i = 0; i < len; i++)
            {
                b.Write(values[i]);
            }
            return(b, null);
        }
Ejemplo n.º 8
0
        private (ByteWriter, string error) encodePacked(ulong div, ulong[] dts)
        {
            // Only apply the divisor if it's greater than 1 since division is expensive.
            if (div > 1)
            {
                for (int i = 1; i < len; i++)
                {
                    ulong  v     = dts[i];
                    string error = enc.Write(v / div);
                    if (error != null)
                    {
                        return(null, error);
                    }
                }
            }
            else
            {
                for (int i = 1; i < len; i++)
                {
                    ulong  v     = dts[i];
                    string error = enc.Write(v);
                    if (error != null)
                    {
                        return(null, error);
                    }
                }
            }

            // The compressed deltas
            var deltas = enc.Bytes();

            if (deltas.error != null)
            {
                return(null, deltas.error);
            }
            int sz = 8 + 1 + deltas.len;

            ByteWriter b = new ByteWriter(sz);

            // 4 high bits used for the encoding type,4 low bits are the log10 divisor
            b.Write((byte)((timeCompressedPackedSimple << 4) | (byte)Math.Log10(div)));

            // The first delta value
            b.Write(dts[0]);

            b.Write(deltas.Item1, 0, deltas.len);
            return(b, null);
        }
Ejemplo n.º 9
0
        private (ByteWriter, string error) encodeRLE()
        {
            // Large varints can take up to 10 bytes.  We're storing 3 + 1
            // type byte.
            ByteWriter b = new ByteWriter(31);

            // 4 high bits used for the encoding type
            b.Write((byte)(intCompressedRLE << 4));
            // The first value
            b.Write(values[0]);
            // The first delta
            b.Write(Varint.GetBytes(values[1]));
            // The number of times the delta is repeated
            b.Write(Varint.GetBytes((ulong)(len - 1)));
            return(b, null);
        }
Ejemplo n.º 10
0
        private string flush()
        {
            if (tail == 0)
            {
                return(null);
            }

            // encode as many values into one as we can
            int n;
            var encoded = Encode(buf, head, tail, out n);

            if (encoded.error != null)
            {
                return(encoded.error);
            }
            len = ByteWriter.Write(bytes, len, encoded.Item1);
            //Move the head forward since we encoded those values
            head += n;
            // If we encoded them all, reset the head/tail pointers to the beginning
            if (head == tail)
            {
                head = 0;
                tail = 0;
            }
            return(null);
        }
Ejemplo n.º 11
0
        public (ByteWriter, string) Bytes()
        {
            ByteWriter byteWriter = new ByteWriter(bw.Len);

            byteWriter.Write(buf, 0, bw.Len);
            return(byteWriter, err);
        }
Ejemplo n.º 12
0
        // Bytes returns a new byte slice containing the encoded booleans from previous calls to Write.
        public (ByteWriter, string) Bytes()
        {
            // Ensure the current byte is flushed
            flush();

            ByteWriter result = new ByteWriter(1 + Varint.MaxVarintLen64 + len);

            // Store the encoding type in the 4 high bits of the first byte
            result.Write((byte)(booleanCompressedBitPacked << 4));
            // Encode the number of booleans written
            result.Write(Varint.GetBytes((ulong)n));
            // Append the packed booleans
            result.Write(bytes, 0, len);

            return(result, null);
        }
Ejemplo n.º 13
0
        private (ByteWriter, string error) encodeRLE(ulong first, ulong delta, ulong div, int n)
        {
            // Large varints can take up to 10 bytes, we're encoding 3 + 1 byte type
            int        sz = 31;
            ByteWriter b  = new ByteWriter(sz);

            // 4 high bits used for the encoding type,4 low bits are the log10 divisor
            b.Write((byte)((timeCompressedRLE << 4) | (byte)Math.Log10(div)));

            // The first timestamp
            b.Write(first);
            // The first delta
            b.Write(Varint.GetBytes(delta / div));
            // The number of times the delta is repeated
            b.Write(Varint.GetBytes(n));

            return(b, null);
        }
Ejemplo n.º 14
0
        private (ByteWriter, string error) encodePacked()
        {
            if (len == 0)
            {
                return(null, null);
            }
            // Encode all but the first value.  Fist value is written unencoded
            // using 8 bytes.
            ByteWriter b = new ByteWriter(1 + 8 * len);

            // 4 high bits of first byte store the encoding type for the block
            b.Write((byte)(intCompressedSimple << 4));
            // Write the first value since it's not part of the encoded values
            b.Write(values[0]);
            var error = Simple8bEncoder.EncodeAll(values, 1, len, b);

            if (error != null)
            {
                b.Release();
                return(null, error);
            }
            return(b, null);
        }
Ejemplo n.º 15
0
        public (ByteWriter, string) EncodingAll(Span <string> src)
        {
            int srcSz = 2 + src.Length * Varint.MaxVarintLen32;// strings should't be longer than 64kb

            for (int i = 0; i < src.Length; i++)
            {
                srcSz += src[i].Length;
            }
            // determine the maximum possible length needed for the buffer, which
            // includes the compressed size
            var compressSz = 0;

            if (src.Length > 0)
            {
                compressSz = SnappyMaxEncodedLen(srcSz) + 1;//header
            }
            int        totSz  = srcSz + compressSz;
            ByteWriter result = new ByteWriter(totSz);

            // Shortcut to snappy encoding nothing.
            if (src.Length == 0)
            {
                result.Write((byte)(stringCompressedSnappy << 4));
                return(result, null);
            }
            for (int i = 0; i < src.Length; i++)
            {
                result.Write(Varint.GetBytes(src[i].Length));
                result.Write(System.Text.Encoding.Default.GetBytes(src[i]));
            }
            byte[] compressed = SnappyPI.SnappyCodec.Compress(result.EndWrite(), 0, result.Length);
            result.Length = 0;
            result.Write((byte)(stringCompressedSnappy << 4));
            result.Write(compressed);
            return(result, null);
        }
Ejemplo n.º 16
0
 public void WriteIndex()
 {
     lock (lockthis)
     {
         if (index.SidCount == 0)
         {
             throw new Exception(Constants.ErrNoValues);
         }
         int        size   = 8 + (int)index.Size;//8 for n
         ByteWriter writer = new ByteWriter(size);
         index.WriteTo(writer);
         writer.Write(blocksize);
         wrapped.Write(writer.EndWrite(), 0, writer.Length);
         writer.Release();
     }
 }
Ejemplo n.º 17
0
 private void writeHeader(ByteWriter w)
 {
     w.Write(Constants.MagicNumber);
     w.Write(Constants.Version);
     blocksize = 5;
 }
Ejemplo n.º 18
0
        public (ByteWriter, string) EncodingAll(Span <long> src)
        {
            int   srclen = src.Length;
            ulong max    = 0;

            ulong[] deltasarray = ArrayPool <ulong> .Shared.Rent(srclen);

            Span <ulong> deltas = new Span <ulong>(deltasarray);

            for (int i = srclen - 1; i > 0; i--)
            {
                long  l     = src[i] - src[i - 1];
                ulong delta = Encoding.ZigZagEncode(l);
                deltas[i] = delta;
                if (delta > max)
                {
                    max = delta;
                }
            }
            deltas[0] = Encoding.ZigZagEncode(src[0]);
            ByteWriter result;

            if (srclen > 2)
            {
                var rle = true;
                for (int i = 2; i < srclen; i++)
                {
                    if (deltas[1] != deltas[i])
                    {
                        rle = false;
                        break;
                    }
                }
                if (rle)
                {
                    // Large varints can take up to 10 bytes.  We're storing 3 + 1
                    // type byte.
                    result = new ByteWriter(31);
                    // 4 high bits used for the encoding type
                    result.Write((byte)(intCompressedRLE << 4));
                    // The first value
                    result.Write(deltas[0]);
                    // The first delta
                    result.Write(Varint.GetBytes(deltas[1]));
                    // The number of times the delta is repeated
                    result.Write(Varint.GetBytes(srclen - 1));
                    ArrayPool <ulong> .Shared.Return(deltasarray);

                    return(result, null);
                }
            }
            if (max > Simple8bEncoder.MaxValue)// There is an encoded value that's too big to simple8b encode.
            {
                // Encode uncompressed.
                int sz = 1 + srclen * 8;
                result = new ByteWriter(sz);
                result.Write((byte)(intUncompressed << 4));
                for (int i = 0; i < srclen; i++)
                {
                    result.Write(deltas[i]);
                }
                ArrayPool <ulong> .Shared.Return(deltasarray);

                return(result, null);
            }
            result = new ByteWriter(1 + srclen * 8);
            result.Write((byte)(intCompressedSimple << 4));
            // Write the first value since it's not part of the encoded values
            result.Write(deltas[0]);
            var error = Simple8bEncoder.EncodeAll(deltasarray, 1, srclen, result);

            ArrayPool <ulong> .Shared.Return(deltasarray);

            if (error != null)
            {
                result.Release();
                return(null, error);
            }
            return(result, null);
        }
Ejemplo n.º 19
0
        public (ByteWriter, string) EncodingAll(Span <ulong> src)
        {
            int srclen = src.Length;

            if (srclen == 0)
            {
                return(null, null);  // Nothing to do
            }
            ulong max = 0, div = (ulong)1e12;

            ulong[] deltaarray = ArrayPool <ulong> .Shared.Rent(srclen);

            Span <ulong> deltas = new Span <ulong>(deltaarray);

            deltas[0] = src[0];
            ByteWriter result;

            if (srclen > 1)
            {
                for (int i = srclen - 1; i > 0; i--)
                {
                    deltas[i] = src[i] - src[i - 1];
                    if (deltas[i] > max)
                    {
                        max = deltas[i];
                    }
                }
                bool rle    = true;
                var  delta1 = deltas[1];
                for (int i = 2; i < srclen; i++)
                {
                    if (delta1 != deltas[i])
                    {
                        rle = false;
                        break;
                    }
                }
                // Deltas are the same - encode with RLE
                if (rle)
                {
                    // Large varints can take up to 10 bytes.  We're storing 3 + 1
                    // type byte.
                    result = new ByteWriter(31);
                    // 4 high bits used for the encoding type
                    result.Write((byte)(timeCompressedRLE << 4));
                    // The first value
                    result.Write(deltas[0]);
                    // The first delta, checking the divisor
                    // given all deltas are the same, we can do a single check for the divisor
                    ulong v = deltas[1];
                    while (div > 1 && v % div != 0)
                    {
                        div /= 10;
                    }
                    if (div > 1)
                    {
                        // 4 low bits are the log10 divisor
                        result.EndWrite()[0] |= (byte)Math.Log10(div);
                        result.Write(Varint.GetBytes(deltas[1] / div));
                    }
                    else
                    {
                        result.Write(Varint.GetBytes(deltas[1]));
                    }
                    // The number of times the delta is repeated
                    result.Write(Varint.GetBytes(srclen));
                    ArrayPool <ulong> .Shared.Return(deltaarray);

                    return(result, null);
                }
            }
            // We can't compress this time-range, the deltas exceed 1 << 60
            if (max > Simple8bEncoder.MaxValue)
            {
                // Encode uncompressed.
                int sz = 1 + srclen * 8;
                result = new ByteWriter(sz);
                result.Write((byte)(timeUncompressed << 4));
                for (int i = 0; i < srclen; i++)
                {
                    result.Write(deltas[i]);
                }
                ArrayPool <ulong> .Shared.Return(deltaarray);

                return(result, null);
            }
            // find divisor only if we're compressing with simple8b
            for (int i = 1; i < srclen && div > 1; i++)
            {
                // If our value is divisible by 10, break.  Otherwise, try the next smallest divisor.
                var v = deltaarray[i];
                while (div > 1 && v % div != 0)
                {
                    div /= 10;
                }
            }
            // Only apply the divisor if it's greater than 1 since division is expensive.
            if (div > 1)
            {
                for (int i = 1; i < srclen; i++)
                {
                    deltas[i] /= div;
                }
            }
            result = new ByteWriter(1 + srclen * 8);
            result.Write((byte)((timeCompressedPackedSimple << 4) | (byte)Math.Log10(div)));
            // Write the first value since it's not part of the encoded values
            result.Write(deltas[0]);
            // Encode with simple8b - fist value is written unencoded using 8 bytes.
            var error = Simple8bEncoder.EncodeAll(deltaarray, 1, srclen, result);

            if (error != null)
            {
                result.Release();
                return(null, error);
            }
            return(result, null);
        }
Ejemplo n.º 20
0
        // Encode converts the WriteWALEntry into a byte stream using dst if it
        // is large enough.  If dst is too small, the slice will be grown to fit the
        // encoded entry.
        public ByteWriter Marshal(out string err)
        {
            // The entries values are encode as follows:
            //
            // For each key and slice of values, first a 1 byte type for the []Values
            // slice is written.  Following the type, the length and key bytes are written.
            // Following the key, a 4 byte count followed by each value as a 8 byte time
            // and N byte value.  The value is dependent on the type being encoded.  float64,
            // int64, use 8 bytes, boolean uses 1 byte, and string is similar to the key encoding,
            // except that string values have a 4-byte length, and keys only use 2 bytes.
            //
            // This structure is then repeated for each key an value slices.
            //
            // ┌────────────────────────────────────────────────────────────────────┐
            // │                           WriteWALEntry                            │
            // ├──────┬─────────┬────────┬───────┬─────────┬─────────┬───┬──────┬───┤
            // │ Type │ Key Len │   Key  │ Count │  Time   │  Value  │...│ Type │...│
            // │1 byte│ 2 bytes │ N bytes│4 bytes│ 8 bytes │ N bytes │   │1 byte│   │
            // └──────┴─────────┴────────┴───────┴─────────┴─────────┴───┴──────┴───┘
            err = null;
            int        encLen = MarshalSize();
            ByteWriter writer = new ByteWriter(encLen);
            // Finally, encode the entry
            byte curType = 0x00;

            foreach (KeyValuePair <ulong, ClockValues> pair in Values)
            {
                ClockValues v = pair.Value;
                curType = v[0].DataType;
                writer.Write(curType);
                writer.Write(pair.Key);
                writer.Write(v.Count);
                foreach (IClockValue vv in v)
                {
                    writer.Write(vv.Clock);
                    if (vv.DataType != curType)
                    {
                        err = string.Format("incorrect value found in {0} slice: {1}", curType, vv.OValue);
                        return(null);
                    }
                    switch (vv.DataType)
                    {
                    case DataTypeEnum.Double:
                        writer.Write(((ClockDouble)vv).Value);
                        break;

                    case DataTypeEnum.Integer:
                        writer.Write(((ClockInt64)vv).Value);
                        break;

                    case DataTypeEnum.Boolean:
                        writer.Write(((ClockBoolean)vv).Value);
                        break;

                    case DataTypeEnum.String:
                        writer.Write(((ClockString)vv).Value);
                        break;

                    default:
                        err = string.Format("unsupported value found in {0} slice: {1}", curType, vv.OValue);
                        return(null);
                    }
                    writer.Write(vv.Quality);
                }
            }
            return(writer);
        }
Ejemplo n.º 21
0
        // EncodeAll returns a packed slice of the values from src.  if(a value is over
        // 1 << 60, an error is returned. .
        public static string EncodeAll(ulong[] src, int index, int end, ByteWriter dst)
        {
            int i = 0;
            ReadOnlySpan <ulong> src_span = new ReadOnlySpan <ulong>(src, index, end - index);

            while (i < src_span.Length)
            {
                bool continu_nextvalue         = false;
                ReadOnlySpan <ulong> remaining = src_span.Slice(i);
                if (remaining.Length > 120)
                {
                    // Invariant: len(a) is fixed to 120 or 240 values
                    ReadOnlySpan <ulong> a;
                    if (remaining.Length >= 240)
                    {
                        a = remaining.Slice(0, 240);
                    }
                    else
                    {
                        a = remaining.Slice(0, 120);
                    }
                    // search for the longest sequence of 1s in a
                    // Postcondition: k equals the index of the last 1 or -1
                    int k = 0;
                    for (; k < a.Length; k++)
                    {
                        if (a[k] != 1)
                        {
                            k--;
                            break;
                        }
                    }
                    ulong v = 0;
                    if (k == 239)
                    {
                        i += 240;
                    }// 240 1s
                    else if (k >= 119)
                    {
                        v  = (ulong)1 << 60;
                        i += 120;
                    }// at least 120 1s
                    else
                    {
                        goto CODES;
                    }
                    dst.Write(v);
                    continue;
                }
CODES:
                for (int s = 0; s < LEN; s++)
                {
                    int  n    = arr_n2[s];
                    byte bits = arr_bits[s];
                    if (n > remaining.Length)
                    {
                        continue;
                    }
                    ulong maxVal         = (ulong)1 << (bits & 0x3F);
                    ulong val            = (ulong)(s + 2) << S8B_BIT_SIZE;
                    bool  continue_codes = false;
                    for (int k = 0; k < remaining.Length; k++)
                    {
                        ulong inV = remaining[k];
                        if (k < n)
                        {
                            if (inV >= maxVal)
                            {
                                continue_codes = true;
                                break;//continue CODES
                            }
                            val |= inV << (((byte)k * bits) & 0x3f);
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (!continue_codes)
                    {
                        dst.Write(val);
                        i += n;
                        continu_nextvalue = true;
                        break;
                    }
                }
                if (!continu_nextvalue)
                {
                    return("value out of bounds");
                }
            }
            return(null);
        }
Ejemplo n.º 22
0
        public static (ByteWriter, string error) Encode(IList <IClockValue> values, int startIndex, int count)
        {
            if (values == null || values.Count == 0)
            {
                return(null, null);
            }
            IClockValue value0   = values[0];
            byte        datatype = value0.DataType;

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

            Span <ulong> ts_span = new Span <ulong>(ts, 0, count);

            long[] qs = ArrayPool <long> .Shared.Rent(count);

            Span <long> qs_span = new Span <long>(qs, 0, count);

            ByteWriter tswriter = null, vswriter = null, qswriter = null;
            string     tserror = null, vserror = null, qserror = null;

            if (datatype == DataTypeEnum.Double)
            {
                double[] vs = ArrayPool <double> .Shared.Rent(count);

                Span <double> vs_span = new Span <double>(vs, 0, count);
                int           j       = 0;
                for (int i = startIndex; i < startIndex + count; i++, j++)
                {
                    ClockDouble value = (ClockDouble)values[i];
                    ts_span[j] = (ulong)value.Clock;
                    vs_span[j] = value.Value;
                    qs_span[j] = value.Quality;
                }
                BatchDouble encoder = (BatchDouble)CoderFactory.Get(datatype);
                (vswriter, vserror) = encoder.EncodingAll(vs_span);
                ArrayPool <double> .Shared.Return(vs);

                CoderFactory.Put(datatype, encoder);
            }
            else if (datatype == DataTypeEnum.Boolean)
            {
                bool[] vs = ArrayPool <bool> .Shared.Rent(count);

                Span <bool> vs_span = new Span <bool>(vs, 0, count);
                int         j       = 0;
                for (int i = startIndex; i < startIndex + count; i++, j++)
                {
                    ClockBoolean value = (ClockBoolean)values[i];
                    ts_span[j] = (ulong)value.Clock;
                    vs_span[j] = value.Value;
                    qs_span[j] = value.Quality;
                }
                BatchBoolean encoder = (BatchBoolean)CoderFactory.Get(datatype);
                (vswriter, vserror) = encoder.EncodingAll(vs_span);
                ArrayPool <bool> .Shared.Return(vs);

                CoderFactory.Put(datatype, encoder);
            }
            else if (datatype == DataTypeEnum.Integer)
            {
                long[] vs = ArrayPool <long> .Shared.Rent(count);

                Span <long> vs_span = new Span <long>(vs, 0, count);
                int         j       = 0;
                for (int i = startIndex; i < startIndex + count; i++, j++)
                {
                    ClockInt64 value = (ClockInt64)values[i];
                    ts_span[j] = (ulong)value.Clock;
                    vs_span[j] = value.Value;
                    qs_span[j] = value.Quality;
                }
                BatchInt64 encoder = (BatchInt64)CoderFactory.Get(datatype);
                (vswriter, vserror) = encoder.EncodingAll(vs_span);
                ArrayPool <long> .Shared.Return(vs);

                CoderFactory.Put(datatype, encoder);
            }
            else if (datatype == DataTypeEnum.String)
            {
                string[] vs = ArrayPool <string> .Shared.Rent(count);

                Span <string> vs_span = new Span <string>(vs, 0, count);
                int           j       = 0;
                for (int i = startIndex; i < startIndex + count; i++, j++)
                {
                    ClockString value = (ClockString)values[i];
                    ts_span[j] = (ulong)value.Clock;
                    vs_span[j] = value.Value;
                    qs_span[j] = value.Quality;
                }
                BatchString encoder = (BatchString)CoderFactory.Get(datatype);
                (vswriter, vserror) = encoder.EncodingAll(vs_span);
                ArrayPool <string> .Shared.Return(vs);

                CoderFactory.Put(datatype, encoder);
            }
            bool good = (vserror == null && vswriter != null);

            if (good)
            {
                BatchTimeStamp tenc = (BatchTimeStamp)CoderFactory.Get(DataTypeEnum.DateTime);
                (tswriter, tserror) = tenc.EncodingAll(ts_span);
                CoderFactory.Put(DataTypeEnum.DateTime, tenc);
                good = (tswriter != null && tserror == null);
                if (good)
                {
                    BatchInt64 qenc = (BatchInt64)CoderFactory.Get(DataTypeEnum.Integer);
                    (qswriter, qserror) = qenc.EncodingAll(qs_span);
                    CoderFactory.Put(DataTypeEnum.Integer, qenc);
                    good = (qswriter != null && qserror == null);
                }
            }
            ArrayPool <ulong> .Shared.Return(ts);

            ArrayPool <long> .Shared.Return(qs);

            if (good)
            {
                ByteWriter result = new ByteWriter(1 + Varint.MaxVarintLen64 + tswriter.Length + vswriter.Length + qswriter.Length);
                result.Write(datatype); //first byte valuetype
                result.Write(Varint.GetBytes(tswriter.Length));
                result.Write(tswriter.EndWrite(), 0, tswriter.Length);
                result.Write(Varint.GetBytes(vswriter.Length));
                result.Write(vswriter.EndWrite(), 0, vswriter.Length);
                result.Write(Varint.GetBytes(qswriter.Length));
                result.Write(qswriter.EndWrite(), 0, qswriter.Length);
                return(result, null);
            }
            if (tswriter != null)
            {
                tswriter.Release();
            }
            if (vswriter != null)
            {
                vswriter.Release();
            }
            if (qswriter != null)
            {
                qswriter.Release();
            }
            return(null, vserror != null ? vserror : tserror != null ? tserror : qserror);
        }
Ejemplo n.º 23
0
        public static (ByteWriter, string error) Encode2(IList <IClockValue> values, int startIndex, int count)
        {
            if (values == null || values.Count == 0)
            {
                return(null, null);
            }
            IClockValue    value0   = values[0];
            byte           datatype = value0.DataType;
            TimeEncoder    tenc     = (TimeEncoder)EncoderFactory.Get(DataTypeEnum.DateTime, count);
            IntegerEncoder qenc     = (IntegerEncoder)EncoderFactory.Get(DataTypeEnum.Integer, count);
            IEncoder       venc     = EncoderFactory.Get(datatype, count);

            if (datatype == DataTypeEnum.Double)
            {
                FloatEncoder encoder = (FloatEncoder)venc;
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    ClockDouble value = (ClockDouble)values[i];
                    tenc.Write(value.Clock);
                    qenc.Write(value.Quality);
                    encoder.Write(value.Value);
                }
            }
            else if (datatype == DataTypeEnum.Boolean)
            {
                BooleanEncoder encoder = (BooleanEncoder)venc;
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    ClockBoolean value = (ClockBoolean)values[i];
                    tenc.Write(value.Clock);
                    qenc.Write(value.Quality);
                    encoder.Write(value.Value);
                }
            }
            else if (datatype == DataTypeEnum.Integer)
            {
                IntegerEncoder encoder = (IntegerEncoder)venc;
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    ClockInt64 value = (ClockInt64)values[i];
                    tenc.Write(value.Clock);
                    qenc.Write(value.Quality);
                    encoder.Write(value.Value);
                }
            }
            else if (datatype == DataTypeEnum.String)
            {
                StringEncoder encoder = (StringEncoder)venc;
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    ClockString value = (ClockString)values[i];
                    tenc.Write(value.Clock);
                    qenc.Write(value.Quality);
                    encoder.Write(value.Value);
                }
            }
            var ts = tenc.Bytes();

            venc.Flush();//for floatencoder
            var qs = qenc.Bytes();
            var vs = venc.Bytes();

            EncoderFactory.Put(DataTypeEnum.DateTime, tenc);
            EncoderFactory.Put(DataTypeEnum.Integer, qenc);
            EncoderFactory.Put(datatype, venc);
            if (ts.Item2 != null)
            {
                return(null, ts.Item2);
            }
            if (vs.Item2 != null)
            {
                return(null, vs.Item2);
            }
            if (qs.Item2 != null)
            {
                return(null, qs.Item2);
            }
            ByteWriter tswriter = ts.Item1;
            ByteWriter vswriter = vs.Item1;
            ByteWriter qswriter = qs.Item1;
            ByteWriter result   = new ByteWriter(1 + Varint.MaxVarintLen64 + tswriter.Length + vswriter.Length + qswriter.Length);

            result.Write(datatype); //first byte valuetype
            result.Write(Varint.GetBytes(tswriter.Length));
            result.Write(tswriter.EndWrite(), 0, tswriter.Length);
            tswriter.Release();
            result.Write(Varint.GetBytes(vswriter.Length));
            result.Write(vswriter.EndWrite(), 0, vswriter.Length);
            vswriter.Release();
            result.Write(qswriter.EndWrite(), 0, qswriter.Length);
            qswriter.Release();
            return(result, null);
        }