public static DiskNode LoadNode(LockedNodeFileStream backingStream, long offset, bool memoryManaged = false) { if (offset == 0) { return(null); } if (!CacheNodes) { if (RootNode is null) { RootNode = new DiskNode(backingStream, DiskNode.HEADER_BYTES); foreach (long l in RootNode.ChildOffsets) { SmallCache.Add(l); } } if (offset == DiskNode.HEADER_BYTES) { return(RootNode); } if (!RootNodes.TryGetValue(offset, out DiskNode thisNode)) { thisNode = new DiskNode(backingStream, offset); if (SmallCache.Contains(offset) || SmallCache.Contains(thisNode.ParentOffset)) { RootNodes.TryAdd(offset, thisNode); } } return(thisNode); } if (MemoryManaged.TryGetValue(offset, out DiskNode dn)) { return(dn); } else if (memoryManaged && CurrentCacheCount < MaxCacheCount) { dn = new DiskNode(_backingStream, offset); CurrentCacheCount++; MemoryManaged.Add(offset, dn); return(dn); } if (!Cache.TryGetValue(offset, out DiskNode toReturn)) { toReturn = new DiskNode(backingStream, offset); if (CurrentCacheCount < MaxCacheCount && Cache.TryAdd(offset, toReturn)) { CurrentCacheCount++; } } return(toReturn ?? new DiskNode(_backingStream, offset)); }
internal static void DisposeAll() { try { MemoryManaged.Clear(); } catch (Exception) { } try { Cache.Clear(); } catch (Exception) { } try { _backingStream.Dispose(); } catch (Exception) { } _backingStream = null; }
public DiskNode(LockedNodeFileStream fileStream, long offset) { if (fileStream is null) { throw new ArgumentNullException(nameof(fileStream)); } this.Offset = offset; this.BackingDataOffset = offset; this.BackingData = fileStream.ReadBlock(offset); this.ChildOffsets = new long[this.ChildCount]; for (int i = 0; i < this.ChildOffsets.Length; i++) { int oset = NODE_SIZE + (i * NEXT_SIZE) + (offset == 16 ? 4 : 2); this.ChildOffsets[i] = this.BackingData.GetInt40(oset); } _backingStream = _backingStream ?? fileStream ?? throw new ArgumentNullException(nameof(fileStream)); }
public async Task Preload(string FilePath) { await Task.Run(() => { try { Dictionary <long, NodeBlock> nodeblocks = new Dictionary <long, NodeBlock>(); for (int header = 0; header < next.Length; header++) { for (int value = 0; value < next[header].Length; value++) { foreach (INodeBlock inb in next[header][value]) { if (inb is NodeBlock nb) { nodeblocks.Add(nb.Offset, nb); } } } } using (LockedNodeFileStream ns = new LockedNodeFileStream(new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.RandomAccess))) { using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.RandomAccess)) { using (FileStream fsn = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.RandomAccess)) { byte[] offsetBytes = new byte[DiskNode.HEADER_BYTES]; fs.Read(offsetBytes, 0, offsetBytes.Length); long JsonOffset = offsetBytes.GetLong(0); long SortOffset = offsetBytes.GetLong(8); fs.Seek(SortOffset, SeekOrigin.Begin); ulong freeMem = SystemInterop.Memory.Status.ullAvailPhys; while (freeMem > this.Settings.MinFreeMemory + this.Settings.RangeFreeMemory) { for (int i = 0; i < this.Settings.PreloadChunkSize / 2; i++) { if (fs.Position >= JsonOffset) { return; } byte[] thisNodeBytes = new byte[5]; fs.Read(thisNodeBytes, 0, thisNodeBytes.Length); long offset = thisNodeBytes.GetInt40(); if (!NoCache.Contains(offset)) { if (!nodeblocks.TryGetValue(offset, out NodeBlock nb)) { continue; } DiskNode dn = new DiskNode(ns, offset); if (dn.NextOffset != 0) { long bLength = dn.NextOffset - dn.Offset; ByteCache cachedBytes = new ByteCache() { Data = new byte[bLength] }; fsn.Seek(dn.Offset, SeekOrigin.Begin); fsn.Read(cachedBytes.Data, 0, (int)bLength); CachedBytes[nb.Index] = cachedBytes; freeMem -= (ulong)cachedBytes.Data.Length; } } if (freeMem < this.Settings.MinFreeMemory + this.Settings.RangeFreeMemory) { return; } } freeMem = SystemInterop.Memory.Status.ullAvailPhys; } } } } } catch (Exception ex) { if (Debugger.IsAttached) { Debugger.Break(); } } }); }