// Copyright (C) Stichting Deltares 2022. 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;
}
}
}
}
}