예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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;
                }
            }
        }
예제 #3
0
        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;
                }
            }
        }