// private void MarkDirty(int lineIndex) { if (lineIndex > metrics[0].Count) { throw new System.ArgumentOutOfRangeException(); } int lineLength = console.output[lineIndex].Length; var indexByTier = new List <int>(); for (var lineIndexDigest = lineIndex; lineIndexDigest != 0; lineIndexDigest >>= listScalingBits) { indexByTier.Add(lineIndexDigest); } indexByTier.Add(0); if (indexByTier.Count == metrics.Count + 1) { metrics.Add(new List <OutputMetric>()); } for (int i = 0; i < metrics.Count; i++) { int index = indexByTier[i]; List <OutputMetric> metricTier = metrics[i]; OutputMetric metric; if (index == metricTier.Count) { metricTier.Add(metric = new OutputMetric()); } else if (index > metricTier.Count) { throw new System.InvalidOperationException("Data structure has gaps"); } else { metric = metricTier[index]; } metric.cachedColumnDim = -1; } lastLineIndex = metrics[0].Count - 1; }
private int RowsInRegion(int tier, int regionIndex) { OutputMetric metric = metrics[tier][regionIndex]; if (metric.cachedColumnDim != Columns) { metric.cachedColumnDim = Columns; if (tier == 0) { int len = console.output[regionIndex].Length; metric.rowCountWhenCachedColumnDim = RowsForStrLen(len); } else { tier--; regionIndex <<= listScalingBits; int regionSize = Math.Min(1 << listScalingBits, metrics[tier].Count - regionIndex); var regionIndices = Enumerable.Range(regionIndex, regionSize); metric.rowCountWhenCachedColumnDim = regionIndices.Sum(i => RowsInRegion(tier, i)); } } return(metric.rowCountWhenCachedColumnDim); }