// Copyright (C) Stichting Deltares 2019. All rights reserved. // // This file is part of Riskeer. // // Riskeer is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.Linq; using BruTile.Cache; using Core.Components.BruTile.Data; namespace Core.Components.BruTile { /// /// Class that manages the file caches. /// public class FileCacheManager { private static FileCacheManager instance; private readonly List registeredFileCaches; private FileCacheManager() { registeredFileCaches = new List(); } /// /// The singleton instance of . /// public static FileCacheManager Instance { get { return instance ?? (instance = new FileCacheManager()); } } /// /// Gets the for a given . /// /// The path to get the file cache for. /// A for the given . /// When a for the given /// already exists, this one is returned. A new is created otherwise. /// Thrown when is null. public FileCache GetFileCache(string cacheDirectoryPath) { if (cacheDirectoryPath == null) { throw new ArgumentNullException(nameof(cacheDirectoryPath)); } foreach (RegisteredFileCache registeredFileCache in registeredFileCaches) { if (registeredFileCache.CacheDirectoryPath == cacheDirectoryPath) { registeredFileCache.CallCount++; return registeredFileCache.FileCache; } } var fileCache = new FileCache(cacheDirectoryPath, BruTileSettings.PersistentCacheFormat, TimeSpan.FromDays(BruTileSettings.PersistentCacheExpireInDays)); registeredFileCaches.Add(new RegisteredFileCache(fileCache, cacheDirectoryPath)); return fileCache; } /// /// Unsubscribes the file cache for the given . /// /// The to unsubscribe from. /// Thrown when /// is null. public void UnsubscribeFileCache(FileCache fileCache) { if (fileCache == null) { throw new ArgumentNullException(nameof(fileCache)); } var fileCachesToRemove = new List(); foreach (RegisteredFileCache registeredFileCache in registeredFileCaches) { if (registeredFileCache.FileCache.Equals(fileCache)) { registeredFileCache.CallCount--; if (registeredFileCache.CallCount == 0) { fileCachesToRemove.Add(registeredFileCache); } } } if (fileCachesToRemove.Any()) { foreach (RegisteredFileCache fileCacheToRemove in fileCachesToRemove) { registeredFileCaches.Remove(fileCacheToRemove); fileCacheToRemove.Dispose(); } } } /// /// Lookup class for administration related to file caches that are used. /// private class RegisteredFileCache : IDisposable { /// /// Creates a new . /// /// The to register. /// The directory path used by the . public RegisteredFileCache(FileCache fileCache, string cacheDirectoryPath) { FileCache = fileCache; CacheDirectoryPath = cacheDirectoryPath; CallCount = 1; } /// /// Gets or sets the number of times this registered file cache is used. /// public int CallCount { get; set; } /// /// Gets the . /// public FileCache FileCache { get; private set; } /// /// Gets the directory path used by the . /// public string CacheDirectoryPath { get; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { FileCache = null; } } } } }