public CookedDataRun(DataRun raw, long startVcn, long prevLcn, NonResidentAttributeRecord attributeExtent) { _raw = raw; _startVcn = startVcn; _startLcn = prevLcn + raw.RunOffset; _attributeExtent = attributeExtent; if (startVcn < 0) { throw new ArgumentOutOfRangeException("startVcn", startVcn, "VCN must be >= 0"); } if (_startLcn < 0) { throw new ArgumentOutOfRangeException("prevLcn", prevLcn, "LCN must be >= 0"); } }
public override void ExpandToClusters(long numVirtualClusters, NonResidentAttributeRecord extent, bool allocate) { _rawStream.ExpandToClusters(CompressionStart(numVirtualClusters), extent, false); }
public override void ExpandToClusters(long numVirtualClusters, NonResidentAttributeRecord extent, bool allocate) { _rawStream.ExpandToClusters(Utilities.RoundUp(numVirtualClusters, _attr.CompressionUnitSize), extent, false); }
private bool SplitAttribute(FileRecord record, NonResidentAttributeRecord targetAttr, bool atStart) { if (targetAttr.DataRuns.Count <= 1) { return false; } int splitIndex = 1; if (!atStart) { List<DataRun> runs = targetAttr.DataRuns; splitIndex = runs.Count - 1; int saved = runs[splitIndex].Size; while (splitIndex > 1 && record.Size - saved > record.AllocatedSize) { --splitIndex; saved += runs[splitIndex].Size; } } AttributeRecord newAttr = targetAttr.Split(splitIndex); // Find a home for the new attribute record FileRecord newAttrHome = null; foreach (var targetRecord in _records) { if (!targetRecord.IsMftRecord && _mft.RecordSize - targetRecord.Size >= newAttr.Size) { targetRecord.AddAttribute(newAttr); newAttrHome = targetRecord; } } if (newAttrHome == null) { newAttrHome = _mft.AllocateRecord(_records[0].Flags & (~FileRecordFlags.InUse), record.IsMftRecord); newAttrHome.BaseFile = record.BaseFile.IsNull ? record.Reference : record.BaseFile; _records.Add(newAttrHome); newAttrHome.AddAttribute(newAttr); } // Add the new attribute record as an extent on the attribute it split from bool added = false; foreach (var attr in _attributes) { foreach (var existingRecord in attr.Extents) { if (existingRecord.Key.File == record.Reference && existingRecord.Key.AttributeId == targetAttr.AttributeId) { attr.AddExtent(newAttrHome.Reference, newAttr); added = true; break; } } if (added) { break; } } UpdateAttributeList(); return true; }
public override void ExpandToClusters(long numVirtualClusters, NonResidentAttributeRecord extent, bool allocate) { long totalVirtualClusters = _cookedRuns.NextVirtualCluster; if (totalVirtualClusters < numVirtualClusters) { NonResidentAttributeRecord realExtent = extent; if (realExtent == null) { realExtent = _cookedRuns.Last.AttributeExtent; } DataRun newRun = new DataRun(0, numVirtualClusters - totalVirtualClusters, true); realExtent.DataRuns.Add(newRun); _cookedRuns.Append(newRun, extent); realExtent.LastVcn = numVirtualClusters - 1; } if (allocate) { AllocateClusters(totalVirtualClusters, (int)(numVirtualClusters - totalVirtualClusters)); } }
public NonResidentDataBuffer(INtfsContext context, NonResidentAttributeRecord record) : this(context, new CookedDataRuns(record.DataRuns, record), false) { }
public abstract void ExpandToClusters(long numVirtualClusters, NonResidentAttributeRecord extent, bool allocate);
public CookedDataRuns(IEnumerable<DataRun> rawRuns, NonResidentAttributeRecord attributeExtent) { _runs = new List<CookedDataRun>(); Append(rawRuns, attributeExtent); }
public void Append(IEnumerable<DataRun> rawRuns, NonResidentAttributeRecord attributeExtent) { long vcn = NextVirtualCluster; long lcn = 0; foreach (var run in rawRuns) { _runs.Add(new CookedDataRun(run, vcn, lcn, attributeExtent)); vcn += run.RunLength; lcn += run.RunOffset; } }
public void Append(DataRun rawRun, NonResidentAttributeRecord attributeExtent) { CookedDataRun last = Last; _runs.Add(new CookedDataRun(rawRun, NextVirtualCluster, last == null ? 0 : last.StartLcn, attributeExtent)); }