public void MakeNonSparse(int index, IEnumerable<DataRun> rawRuns) { if (index < _firstDirty) { _firstDirty = index; } if (index > _lastDirty) { _lastDirty = index; } long prevLcn = index == 0 ? 0 : _runs[index - 1].StartLcn; CookedDataRun run = _runs[index]; if (!run.IsSparse) { throw new ArgumentException("Run is already non-sparse", "index"); } _runs.RemoveAt(index); int insertIdx = run.AttributeExtent.RemoveRun(run.DataRun); CookedDataRun lastNewRun = null; long lcn = prevLcn; long vcn = run.StartVcn; foreach (var rawRun in rawRuns) { CookedDataRun newRun = new CookedDataRun(rawRun, vcn, lcn, run.AttributeExtent); _runs.Insert(index, newRun); run.AttributeExtent.InsertRun(insertIdx, rawRun); vcn += rawRun.RunLength; lcn += rawRun.RunOffset; lastNewRun = newRun; insertIdx++; index++; } for (int i = index; i < _runs.Count; ++i) { if (_runs[i].IsSparse) { _runs[i].StartLcn = lastNewRun.StartLcn; } else { _runs[i].DataRun.RunOffset = _runs[i].StartLcn - lastNewRun.StartLcn; break; } } }
public void SplitRun(int runIdx, long vcn) { if (runIdx < _firstDirty) { _firstDirty = runIdx; } if (runIdx > _lastDirty) { _lastDirty = runIdx; } CookedDataRun run = _runs[runIdx]; if (run.StartVcn >= vcn || run.StartVcn + run.Length <= vcn) { throw new ArgumentException("Attempt to split run outside of it's range", "vcn"); } long distance = vcn - run.StartVcn; long offset = run.IsSparse ? 0 : distance; CookedDataRun newRun = new CookedDataRun(new DataRun(offset, run.Length - distance, run.IsSparse), vcn, run.StartLcn, run.AttributeExtent); run.Length = distance; _runs.Insert(runIdx + 1, newRun); run.AttributeExtent.InsertRun(run.DataRun, newRun.DataRun); for (int i = runIdx + 2; i < _runs.Count; ++i) { if (_runs[i].IsSparse) { _runs[i].StartLcn += offset; } else { _runs[i].DataRun.RunOffset -= offset; break; } } }
public void MakeSparse(int index) { if (index < _firstDirty) { _firstDirty = index; } if (index > _lastDirty) { _lastDirty = index; } long prevLcn = index == 0 ? 0 : _runs[index - 1].StartLcn; CookedDataRun run = _runs[index]; if (run.IsSparse) { throw new ArgumentException("Run is already sparse", "index"); } _runs[index] = new CookedDataRun(new DataRun(0, run.Length, true), run.StartVcn, prevLcn, run.AttributeExtent); run.AttributeExtent.ReplaceRun(run.DataRun, _runs[index].DataRun); for (int i = index + 1; i < _runs.Count; ++i) { if (!_runs[i].IsSparse) { _runs[i].DataRun.RunOffset += run.StartLcn - prevLcn; break; } } }