internal void Expand(OptimizationContext context) { if (!Optimized) { return; } Starts.ExpandData(context); Lengths.ExpandData(context); SharedIndices.ExpandData(context); if (!StartsExpanded) { ExpandStarts(); } ExpandLists(context); if (FullLength == 0) { var end = Starts[Starts.Count - 1] + Lengths[Lengths.Count - 1]; FullLength = end - Starts.MinValue + 1; } Optimized = false; }
private void OptimizeStarts(OptimizationContext context) { Contract.Assert(Lengths.CompressedData == null, "Lengths must be decompressed prior to optimizing starts"); //var starts = Starts.GetReadOnlyList().ToList(); context.Stream.Position = 0; var startsDataLength = Starts.Data.Length; context.Stream.Write(Starts.Data, 0, startsDataLength); var count = Starts.Count; int priorStart = Starts.MinValue; int priorLength = 0; int max = 0; for (int i = 0; i < count; i++) { int start = Starts[i]; int newValue; if (start == priorStart) { newValue = 0; } else { // If not equal to prior start // We store the delta from the end of the prior span + 1 (0 is reserved for starting at the same position as the prior segment) // NOTE: This must be non-negative. var priorEnd = priorStart + priorLength; var priorEndOffset = start - priorEnd; if (priorEndOffset < 0) { throw new InvalidOperationException( $"priorEndOffset: {priorEndOffset} priorStart: {priorStart} priorLength: {priorLength} start: {start}"); } newValue = priorEndOffset + 1; } Starts.SetIndexDirect(i, newValue); priorStart = start; priorLength = Lengths[i]; max = Math.Max(newValue, max); } var newStartsMinByteWidth = NumberUtils.GetByteWidth(max); if (newStartsMinByteWidth > Starts.ValueByteWidth) { context.Stream.Position = 0; context.Stream.Read(Starts.Data, 0, startsDataLength); StartsExpanded = true; } }
public void OnSerializing(StreamingContext context) { if (Optimize) { var optimizationContext = new OptimizationContext(); foreach (var segment in Segments) { segment.Optimize(optimizationContext); } } }
internal void ExpandData(OptimizationContext context) { Data = Convert.FromBase64String(CompressedData); if (DecompressedLength != 0) { var compressedData = Data; Data = new byte[DecompressedLength]; using (var compressedStream = new DeflateStream(new MemoryStream(compressedData), CompressionMode.Decompress)) { compressedStream.Read(Data, 0, DecompressedLength); } } CompressedData = null; DecompressedLength = 0; CompressedLength = 0; }
internal void Optimize(OptimizationContext context) { if (CompressedData == null && Data != null) { var compressedData = context.Compress(Data); if (compressedData.Length < Data.Length) { DecompressedLength = Data.Length; CompressedLength = compressedData.Length; CompressedData = Convert.ToBase64String(compressedData); } else { CompressedData = Convert.ToBase64String(Data); } Data = null; } }
internal void Optimize(OptimizationContext context) { if (Optimized) { return; } if (FullLength == 0) { var end = Starts[Starts.Count - 1] + Lengths[Lengths.Count - 1]; FullLength = end - Starts.MinValue + 1; } OptimizeStarts(context); Starts.Optimize(context); Lengths.Optimize(context); SharedIndices.Optimize(context); OptimizeLists(context); Optimized = true; }
internal override void ExpandLists(OptimizationContext context) { LocalSymbolGroupIds?.ExpandData(context); base.ExpandLists(context); }
internal override void OptimizeLists(OptimizationContext context) { LocalSymbolGroupIds?.Optimize(context); base.OptimizeLists(context); }
internal virtual void ExpandLists(OptimizationContext context) { }
internal virtual void OptimizeLists(OptimizationContext context) { }