public static ClockValues Decode(byte[] bytes, int startindex, long start, long end) { Span <byte> span = new Span <byte>(bytes); byte datatype = bytes[startindex]; span = span.Slice(1); //解析时标段; int nn = Varint.Read(span, out int tsLen); Span <byte> ts_src_span = span.Slice(nn, tsLen); ulong[] ts = ArrayPool <ulong> .Shared.Rent(Constants.DefaultMaxPointsPerBlock); Span <ulong> ts_to_span = new Span <ulong>(ts, 0, Constants.DefaultMaxPointsPerBlock); BatchTimeStamp tdec = (BatchTimeStamp)CoderFactory.Get(DataTypeEnum.DateTime); (int tscount, string tserror) = tdec.DecodeAll(ts_src_span, ts_to_span); CoderFactory.Put(DataTypeEnum.DateTime, tdec); if (tscount == 0 || tserror != null) { ArrayPool <ulong> .Shared.Return(ts); return(null); } span = span.Slice(nn + tsLen); //读取数值段. nn = Varint.Read(span, out int vsLen); Span <byte> vs_src_span = span.Slice(nn, vsLen); span = span.Slice(nn + vsLen); //解析质量段. nn = Varint.Read(span, out int qsLen); Span <byte> qs_src_span = span.Slice(nn, qsLen); BatchInt64 qdec = (BatchInt64)CoderFactory.Get(DataTypeEnum.Integer); long[] qs = ArrayPool <long> .Shared.Rent(tscount); Span <long> qs_to_span = new Span <long>(qs, 0, tscount); (int qscount, string qserror) = qdec.DecodeAll(qs_src_span, qs_to_span); CoderFactory.Put(DataTypeEnum.Integer, qdec); if (qscount != tscount || qserror != null) { ArrayPool <long> .Shared.Return(qs); return(null); } //解析数据段. ClockValues result = null; if (datatype == DataTypeEnum.Double) { BatchDouble decoder = (BatchDouble)CoderFactory.Get(datatype); double[] vs = ArrayPool <double> .Shared.Rent(tscount + 1); Span <double> vs_to_span = new Span <double>(vs, 0, tscount + 1); (int vscount, string vserror) = decoder.DecodeAll(vs_src_span, vs_to_span); CoderFactory.Put(datatype, decoder); if (vscount >= tscount && vserror == null) { result = new ClockValues(tscount); for (int i = 0; i < tscount; i++) { long clock = (long)ts_to_span[i]; if (clock > end) { break; } if (clock >= start) { result.Append(new ClockDouble(clock, vs_to_span[i], (int)qs_to_span[i])); } } } ArrayPool <double> .Shared.Return(vs); } else if (datatype == DataTypeEnum.Boolean) { BatchBoolean decoder = (BatchBoolean)CoderFactory.Get(datatype); bool[] vs = ArrayPool <bool> .Shared.Rent(tscount); Span <bool> vs_to_span = new Span <bool>(vs, 0, tscount); (int vscount, string vserror) = decoder.DecodeAll(vs_src_span, vs_to_span); CoderFactory.Put(datatype, decoder); if (vscount == tscount && vserror == null) { result = new ClockValues(tscount); for (int i = 0; i < tscount; i++) { long clock = (long)ts_to_span[i]; if (clock > end) { break; } if (clock >= start) { result.Append(new ClockBoolean(clock, vs_to_span[i], (int)qs_to_span[i])); } } } ArrayPool <bool> .Shared.Return(vs); } else if (datatype == DataTypeEnum.Integer) { BatchInt64 decoder = (BatchInt64)CoderFactory.Get(datatype); long[] vs = ArrayPool <long> .Shared.Rent(tscount); Span <long> vs_to_span = new Span <long>(vs, 0, tscount); (int vscount, string vserror) = decoder.DecodeAll(vs_src_span, vs_to_span); CoderFactory.Put(datatype, decoder); if (vscount == tscount && vserror == null) { result = new ClockValues(tscount); for (int i = 0; i < tscount; i++) { long clock = (long)ts_to_span[i]; if (clock > end) { break; } if (clock >= start) { result.Append(new ClockInt64(clock, vs_to_span[i], (int)qs_to_span[i])); } } } ArrayPool <long> .Shared.Return(vs); } else if (datatype == DataTypeEnum.String) { BatchString decoder = (BatchString)CoderFactory.Get(datatype); string[] vs = ArrayPool <string> .Shared.Rent(tscount); Span <string> vs_to_span = new Span <string>(vs, 0, tscount); (int vscount, string vserror) = decoder.DecodeAll(vs_src_span, vs_to_span); CoderFactory.Put(datatype, decoder); if (vscount == tscount && vserror == null) { result = new ClockValues(tscount); for (int i = 0; i < tscount; i++) { long clock = (long)ts_to_span[i]; if (clock > end) { break; } if (clock >= start) { result.Append(new ClockString(clock, vs_to_span[i], (int)qs_to_span[i])); } } } ArrayPool <string> .Shared.Return(vs); } return(result); }
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); }