Пример #1
0
        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;
            }
        }