/// <summary> /// GC safe dispose wrapper /// </summary> /// <param name="disposing">truth check</param> protected virtual void Dispose(bool disposing) { if (Disposed) { return; } Hasher?.Dispose(); Prefetch.Dispose(); foreach (var(_, cache) in CacheFiles) { cache?.Dispose(); } if (disposing) { CacheFiles.Clear(); CacheFiles = default; FileMap.Clear(); FileMap = default; Prefetch = default; } Disposed = true; }
/// <summary> /// Generate file lookup for finding files in multiple cache bins /// </summary> public void GenerateFileMap() { var comparer = new FileMapComparer(); foreach (var(hash, cache) in CacheFiles.OrderBy(x => x.Value.Header.LoadOrder)) { FileMap = FileMap.Union(cache.RecordTable.ToDictionary(x => x.Hash, x => hash), comparer).ToDictionary(x => x.Key, x => x.Value); } }
/// <summary> /// Load specific cache file. /// </summary> /// <param name="filename"></param> /// <returns>success</returns> // ReSharper disable once UnusedMethodReturnValue.Global public bool LoadCache(string filename) { try { var hash = GetFileHash(Path.GetFileNameWithoutExtension(filename)); if (CacheFiles.ContainsKey(hash)) { return(true); } var cache = new DecimaCache(filename); CacheFiles[hash] = cache; return(true); } catch (InvalidDataException) { return(false); } }
private static bool FreeCacheSpace(long current, long required) { var released = 0L; var spare = MaxCacheSize - current; var files = CacheFiles.OrderBy(f => f.LastAccessTime).Reverse().ToList(); while (spare + released < required) { if (files.Count == 0) { return(false); } var index = files.Count - 1; var file = files[index]; released += file.Length; files.RemoveAt(index); File.Delete(Path.Combine(CachePathname, file.Name)); } return(true); }