From 77c2169999abf601faaa184680ec947f9a134a8b Mon Sep 17 00:00:00 2001 From: Clemens Date: Fri, 2 Jul 2021 15:57:01 +0200 Subject: [PATCH] Replaced ImageCacheItem by Tuple --- FileDbCache/Shared/FileDbCache.cs | 8 +++---- FileDbCache/UWP/FileDbCache.UWP.cs | 12 ++++------ FileDbCache/WPF/FileDbCache.WPF.cs | 16 +++++-------- FileDbCache/WPF/FileDbCache.WPF.csproj | 4 ---- MapControl/Shared/ImageFileCache.cs | 2 +- MapControl/Shared/TileImageLoader.cs | 9 -------- MapControl/UWP/ImageFileCache.UWP.cs | 22 ++++++------------ MapControl/UWP/TileImageLoader.UWP.cs | 20 ++++++---------- MapControl/WPF/ImageFileCache.WPF.cs | 23 +++++++------------ MapControl/WPF/TileImageLoader.WPF.cs | 20 +++++++--------- SQLiteCache/UWP/SQLiteCache.UWP.cs | 18 +++++---------- SQLiteCache/WPF/SQLiteCache.WPF.cs | 22 +++++++----------- SQLiteCache/WPF/SQLiteCache.WPF.csproj | 4 ---- .../WpfApplication/WpfApplication.csproj | 2 ++ 14 files changed, 60 insertions(+), 122 deletions(-) diff --git a/FileDbCache/Shared/FileDbCache.cs b/FileDbCache/Shared/FileDbCache.cs index f4014cd3..5b4f0bc4 100644 --- a/FileDbCache/Shared/FileDbCache.cs +++ b/FileDbCache/Shared/FileDbCache.cs @@ -19,7 +19,7 @@ namespace MapControl.Caching private const string valueField = "Value"; private const string expiresField = "Expires"; - private readonly FileDb fileDb = new FileDb() { AutoFlush = true }; + private readonly FileDb fileDb = new FileDb { AutoFlush = true }; public FileDbCache(string path) { @@ -91,7 +91,7 @@ namespace MapControl.Caching } catch (Exception ex) { - Debug.WriteLine("FileDbCache.GetRecordByKey(\"{0}\"): {1}", key, ex.Message); + Debug.WriteLine("FileDbCache.GetRecordByKey({0}): {1}", key, ex.Message); } return null; @@ -114,12 +114,10 @@ namespace MapControl.Caching fieldValues.Add(keyField, key); fileDb.AddRecord(fieldValues); } - - //Debug.WriteLine("FileDbCache: Writing \"{0}\", Expires {1}", key, imageCacheItem.Expiration.ToLocalTime()); } catch (Exception ex) { - Debug.WriteLine("FileDbCache.AddOrUpdateRecord(\"{0}\"): {1}", key, ex.Message); return; + Debug.WriteLine("FileDbCache.AddOrUpdateRecord({0}): {1}", key, ex.Message); return; } } } diff --git a/FileDbCache/UWP/FileDbCache.UWP.cs b/FileDbCache/UWP/FileDbCache.UWP.cs index a01e9f50..1c1d5f5f 100644 --- a/FileDbCache/UWP/FileDbCache.UWP.cs +++ b/FileDbCache/UWP/FileDbCache.UWP.cs @@ -9,7 +9,7 @@ namespace MapControl.Caching { public partial class FileDbCache : IImageCache { - public Task GetAsync(string key) + public Task> GetAsync(string key) { return Task.Run(() => { @@ -20,17 +20,13 @@ namespace MapControl.Caching return null; } - return new ImageCacheItem - { - Buffer = (byte[])record[0], - Expiration = (DateTime)record[1] - }; + return Tuple.Create((byte[])record[0], (DateTime)record[1]); }); } - public Task SetAsync(string key, ImageCacheItem cacheItem) + public Task SetAsync(string key, byte[] buffer, DateTime expiration) { - return Task.Run(() => AddOrUpdateRecord(key, cacheItem.Buffer, cacheItem.Expiration)); + return Task.Run(() => AddOrUpdateRecord(key, buffer, expiration)); } } } diff --git a/FileDbCache/WPF/FileDbCache.WPF.cs b/FileDbCache/WPF/FileDbCache.WPF.cs index 387d0fdb..ab057eb5 100644 --- a/FileDbCache/WPF/FileDbCache.WPF.cs +++ b/FileDbCache/WPF/FileDbCache.WPF.cs @@ -75,7 +75,7 @@ namespace MapControl.Caching } catch (Exception ex) { - Debug.WriteLine("FileDbCache.Contains(\"{0}\"): {1}", key, ex.Message); + Debug.WriteLine("FileDbCache.Contains({0}): {1}", key, ex.Message); } return false; @@ -100,11 +100,7 @@ namespace MapControl.Caching return null; } - return new ImageCacheItem - { - Buffer = (byte[])record[0], - Expiration = (DateTime)record[1] - }; + return Tuple.Create((byte[])record[0], (DateTime)record[1]); } public override CacheItem GetCacheItem(string key, string regionName = null) @@ -131,12 +127,12 @@ namespace MapControl.Caching throw new ArgumentNullException(nameof(key)); } - if (!(value is ImageCacheItem imageCacheItem)) + if (!(value is Tuple cacheItem)) { - throw new ArgumentException("The value argument must be a MapControl.Caching.ImageCacheItem instance.", nameof(value)); + throw new ArgumentException("The value argument must be a Tuple.", nameof(value)); } - AddOrUpdateRecord(key, imageCacheItem.Buffer, imageCacheItem.Expiration); + AddOrUpdateRecord(key, cacheItem.Item1, cacheItem.Item2); } public override void Set(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null) @@ -184,7 +180,7 @@ namespace MapControl.Caching } catch (Exception ex) { - Debug.WriteLine("FileDbCache.Remove(\"{0}\"): {1}", key, ex.Message); + Debug.WriteLine("FileDbCache.Remove({0}): {1}", key, ex.Message); } } diff --git a/FileDbCache/WPF/FileDbCache.WPF.csproj b/FileDbCache/WPF/FileDbCache.WPF.csproj index 94cb2cea..c90769c7 100644 --- a/FileDbCache/WPF/FileDbCache.WPF.csproj +++ b/FileDbCache/WPF/FileDbCache.WPF.csproj @@ -46,8 +46,4 @@ - - - - diff --git a/MapControl/Shared/ImageFileCache.cs b/MapControl/Shared/ImageFileCache.cs index 23833650..f1a69e08 100644 --- a/MapControl/Shared/ImageFileCache.cs +++ b/MapControl/Shared/ImageFileCache.cs @@ -13,7 +13,7 @@ namespace MapControl.Caching { /// /// Image Cache implementation based on local image files. - /// The only valid data type for cached values is ImageCacheItem. + /// The only valid data type for cached values is Tuple. /// public partial class ImageFileCache { diff --git a/MapControl/Shared/TileImageLoader.cs b/MapControl/Shared/TileImageLoader.cs index 5b633fb6..4a737ddf 100644 --- a/MapControl/Shared/TileImageLoader.cs +++ b/MapControl/Shared/TileImageLoader.cs @@ -13,15 +13,6 @@ using System.Threading.Tasks; namespace MapControl { - namespace Caching - { - public class ImageCacheItem - { - public byte[] Buffer { get; set; } - public DateTime Expiration { get; set; } - } - } - #if NETFRAMEWORK static class ConcurrentQueueEx { diff --git a/MapControl/UWP/ImageFileCache.UWP.cs b/MapControl/UWP/ImageFileCache.UWP.cs index d5395165..77c63595 100644 --- a/MapControl/UWP/ImageFileCache.UWP.cs +++ b/MapControl/UWP/ImageFileCache.UWP.cs @@ -11,9 +11,9 @@ namespace MapControl.Caching { public partial class ImageFileCache : IImageCache { - public async Task GetAsync(string key) + public async Task> GetAsync(string key) { - ImageCacheItem cacheItem = null; + Tuple cacheItem = null; var path = GetPath(key); try @@ -23,13 +23,7 @@ namespace MapControl.Caching var buffer = await File.ReadAllBytesAsync(path); var expiration = ReadExpiration(ref buffer); - cacheItem = new ImageCacheItem - { - Buffer = buffer, - Expiration = expiration - }; - - //Debug.WriteLine("ImageFileCache: Read {0}, Expires {1}", path, expiration.ToLocalTime()); + cacheItem = Tuple.Create(buffer, expiration); } } catch (Exception ex) @@ -40,11 +34,11 @@ namespace MapControl.Caching return cacheItem; } - public async Task SetAsync(string key, ImageCacheItem cacheItem) + public async Task SetAsync(string key, byte[] buffer, DateTime expiration) { var path = GetPath(key); - if (cacheItem.Buffer != null && cacheItem.Buffer.Length > 0 && path != null) + if (buffer != null && buffer.Length > 0 && path != null) { try { @@ -52,11 +46,9 @@ namespace MapControl.Caching using (var stream = File.Create(path)) { - await stream.WriteAsync(cacheItem.Buffer, 0, cacheItem.Buffer.Length); - await WriteExpirationAsync(stream, cacheItem.Expiration); + await stream.WriteAsync(buffer, 0, buffer.Length); + await WriteExpirationAsync(stream, expiration); } - - //Debug.WriteLine("ImageFileCache: Wrote {0}, Expires {1}", path, expiration.ToLocalTime()); } catch (Exception ex) { diff --git a/MapControl/UWP/TileImageLoader.UWP.cs b/MapControl/UWP/TileImageLoader.UWP.cs index df53e869..0e20a1a2 100644 --- a/MapControl/UWP/TileImageLoader.UWP.cs +++ b/MapControl/UWP/TileImageLoader.UWP.cs @@ -4,7 +4,6 @@ using System; using System.Threading.Tasks; -using MapControl.Caching; #if WINDOWS_UWP using Windows.UI.Core; using Windows.UI.Xaml.Media; @@ -19,9 +18,9 @@ namespace MapControl { public interface IImageCache { - Task GetAsync(string key); + Task> GetAsync(string key); - Task SetAsync(string key, ImageCacheItem cacheItem); + Task SetAsync(string key, byte[] buffer, DateTime expiration); } } @@ -39,15 +38,15 @@ namespace MapControl /// /// The IImageCache implementation used to cache tile images. The default is null. /// - public static IImageCache Cache { get; set; } + public static Caching.IImageCache Cache { get; set; } private static async Task LoadCachedTileAsync(Tile tile, Uri uri, string cacheKey) { var cacheItem = await Cache.GetAsync(cacheKey).ConfigureAwait(false); - var buffer = cacheItem?.Buffer; + var buffer = cacheItem?.Item1; - if (cacheItem == null || cacheItem.Expiration < DateTime.UtcNow) + if (cacheItem == null || cacheItem.Item2 < DateTime.UtcNow) { var response = await ImageLoader.GetHttpResponseAsync(uri).ConfigureAwait(false); @@ -55,15 +54,10 @@ namespace MapControl { buffer = response.Buffer; // may be null or empty when no tile available, but still be cached - cacheItem = new ImageCacheItem - { - Buffer = buffer, - Expiration = GetExpiration(response.MaxAge) - }; - - await Cache.SetAsync(cacheKey, cacheItem).ConfigureAwait(false); + await Cache.SetAsync(cacheKey, buffer, GetExpiration(response.MaxAge)).ConfigureAwait(false); } } + else System.Diagnostics.Debug.WriteLine("Cached: " + cacheKey); if (buffer != null && buffer.Length > 0) { diff --git a/MapControl/WPF/ImageFileCache.WPF.cs b/MapControl/WPF/ImageFileCache.WPF.cs index 0fec63ba..62c92753 100644 --- a/MapControl/WPF/ImageFileCache.WPF.cs +++ b/MapControl/WPF/ImageFileCache.WPF.cs @@ -95,7 +95,7 @@ namespace MapControl.Caching throw new ArgumentNullException(nameof(key)); } - var cacheItem = memoryCache.Get(key) as ImageCacheItem; + var cacheItem = memoryCache.Get(key) as Tuple; if (cacheItem == null) { @@ -108,15 +108,9 @@ namespace MapControl.Caching var buffer = File.ReadAllBytes(path); var expiration = ReadExpiration(ref buffer); - cacheItem = new ImageCacheItem - { - Buffer = buffer, - Expiration = expiration - }; + cacheItem = new Tuple(buffer, expiration); memoryCache.Set(key, cacheItem, new CacheItemPolicy { AbsoluteExpiration = expiration }); - - //Debug.WriteLine("ImageFileCache: Read {0}, Expires {1}", path, cacheItem.Expiration.ToLocalTime()); } } catch (Exception ex) @@ -152,16 +146,17 @@ namespace MapControl.Caching throw new ArgumentNullException(nameof(key)); } - if (!(value is ImageCacheItem cacheItem)) + if (!(value is Tuple cacheItem)) { - throw new ArgumentException("The value argument must be a MapControl.Caching.ImageCacheItem instance.", nameof(value)); + throw new ArgumentException("The value argument must be a Tuple.", nameof(value)); } memoryCache.Set(key, cacheItem, policy); + var buffer = cacheItem.Item1; var path = GetPath(key); - if (cacheItem.Buffer != null && cacheItem.Buffer.Length > 0 && path != null) + if (buffer != null && buffer.Length > 0 && path != null) { try { @@ -169,16 +164,14 @@ namespace MapControl.Caching using (var stream = File.Create(path)) { - stream.Write(cacheItem.Buffer, 0, cacheItem.Buffer.Length); - WriteExpiration(stream, cacheItem.Expiration); + stream.Write(buffer, 0, buffer.Length); + WriteExpiration(stream, cacheItem.Item2); } var fileInfo = new FileInfo(path); var fileSecurity = fileInfo.GetAccessControl(); fileSecurity.AddAccessRule(fullControlRule); fileInfo.SetAccessControl(fileSecurity); - - //Debug.WriteLine("ImageFileCache: Wrote {0}, Expires {1}", path, cacheItem.Expiration.ToLocalTime()); } catch (Exception ex) { diff --git a/MapControl/WPF/TileImageLoader.WPF.cs b/MapControl/WPF/TileImageLoader.WPF.cs index 73e812a4..5152a20a 100644 --- a/MapControl/WPF/TileImageLoader.WPF.cs +++ b/MapControl/WPF/TileImageLoader.WPF.cs @@ -6,7 +6,6 @@ using System; using System.IO; using System.Runtime.Caching; using System.Threading.Tasks; -using MapControl.Caching; namespace MapControl { @@ -21,7 +20,7 @@ namespace MapControl } /// - /// An ObjectCache instance used to cache tile image data (i.e. ImageCacheItem objects). + /// An ObjectCache instance used to cache tile image data, i.e. (byte[],DateTime) tuples. /// The default ObjectCache value is MemoryCache.Default. /// public static ObjectCache Cache { get; set; } = MemoryCache.Default; @@ -29,26 +28,23 @@ namespace MapControl private static async Task LoadCachedTileAsync(Tile tile, Uri uri, string cacheKey) { - var cacheItem = Cache.Get(cacheKey) as ImageCacheItem; - var buffer = cacheItem?.Buffer; + var cacheItem = Cache.Get(cacheKey) as Tuple; + var buffer = cacheItem?.Item1; - if (cacheItem == null || cacheItem.Expiration < DateTime.UtcNow) + if (cacheItem == null || cacheItem.Item2 < DateTime.UtcNow) { var response = await ImageLoader.GetHttpResponseAsync(uri).ConfigureAwait(false); if (response != null) // download succeeded { - buffer = response.Buffer; + buffer = response.Buffer; // may be null or empty when no tile available, but still be cached - cacheItem = new ImageCacheItem - { - Buffer = buffer, // may be null or empty when no tile available, but still be cached - Expiration = GetExpiration(response.MaxAge) - }; + cacheItem = Tuple.Create(buffer, GetExpiration(response.MaxAge)); - Cache.Set(cacheKey, cacheItem, new CacheItemPolicy { AbsoluteExpiration = cacheItem.Expiration }); + Cache.Set(cacheKey, cacheItem, new CacheItemPolicy { AbsoluteExpiration = cacheItem.Item2 }); } } + else System.Diagnostics.Debug.WriteLine("Cached: " + cacheKey); if (buffer != null && buffer.Length > 0) { diff --git a/SQLiteCache/UWP/SQLiteCache.UWP.cs b/SQLiteCache/UWP/SQLiteCache.UWP.cs index 34add4f1..bbedd92c 100644 --- a/SQLiteCache/UWP/SQLiteCache.UWP.cs +++ b/SQLiteCache/UWP/SQLiteCache.UWP.cs @@ -10,7 +10,7 @@ namespace MapControl.Caching { public partial class SQLiteCache : IImageCache { - public async Task GetAsync(string key) + public async Task> GetAsync(string key) { try { @@ -20,36 +20,30 @@ namespace MapControl.Caching if (await reader.ReadAsync()) { - return new ImageCacheItem - { - Expiration = new DateTime((long)reader["expiration"]), - Buffer = (byte[])reader["buffer"] - }; + return Tuple.Create((byte[])reader["buffer"], new DateTime((long)reader["expiration"])); } } } catch (Exception ex) { - Debug.WriteLine("SQLiteCache.GetAsync(\"{0}\"): {1}", key, ex.Message); + Debug.WriteLine("SQLiteCache.GetAsync({0}): {1}", key, ex.Message); } return null; } - public async Task SetAsync(string key, ImageCacheItem cacheItem) + public async Task SetAsync(string key, byte[] buffer, DateTime expiration) { try { - using (var command = SetItemCommand(key, cacheItem.Expiration, cacheItem.Buffer)) + using (var command = SetItemCommand(key, expiration, buffer)) { await command.ExecuteNonQueryAsync(); } - - //Debug.WriteLine("SQLiteCache.SetAsync(\"{0}\"): expires {1}", key, cacheItem.Expiration.ToLocalTime()); } catch (Exception ex) { - Debug.WriteLine("SQLiteCache.SetAsync(\"{0}\"): {1}", key, ex.Message); + Debug.WriteLine("SQLiteCache.SetAsync({0}): {1}", key, ex.Message); } } } diff --git a/SQLiteCache/WPF/SQLiteCache.WPF.cs b/SQLiteCache/WPF/SQLiteCache.WPF.cs index f0dc771b..bc88fa55 100644 --- a/SQLiteCache/WPF/SQLiteCache.WPF.cs +++ b/SQLiteCache/WPF/SQLiteCache.WPF.cs @@ -82,7 +82,7 @@ namespace MapControl.Caching } catch (Exception ex) { - Debug.WriteLine("SQLiteCache.Contains(\"{0}\"): {1}", key, ex.Message); + Debug.WriteLine("SQLiteCache.Contains({0}): {1}", key, ex.Message); } return false; @@ -108,17 +108,13 @@ namespace MapControl.Caching if (reader.Read()) { - return new ImageCacheItem - { - Expiration = new DateTime((long)reader["expiration"]), - Buffer = (byte[])reader["buffer"] - }; + return Tuple.Create((byte[])reader["buffer"], new DateTime((long)reader["expiration"])); } } } catch (Exception ex) { - Debug.WriteLine("SQLiteCache.Get(\"{0}\"): {1}", key, ex.Message); + Debug.WriteLine("SQLiteCache.Get({0}): {1}", key, ex.Message); } return null; @@ -148,23 +144,21 @@ namespace MapControl.Caching throw new ArgumentNullException(nameof(key)); } - if (!(value is ImageCacheItem imageCacheItem)) + if (!(value is Tuple cacheItem)) { - throw new ArgumentException("The value argument must be a MapControl.Caching.ImageCacheItem instance.", nameof(value)); + throw new ArgumentException("The value argument must be a Tuple.", nameof(value)); } try { - using (var command = SetItemCommand(key, imageCacheItem.Expiration, imageCacheItem.Buffer)) + using (var command = SetItemCommand(key, cacheItem.Item2, cacheItem.Item1)) { command.ExecuteNonQuery(); } - - //Debug.WriteLine("SQLiteCache.Set(\"{0}\"): expires {1}", key, expiration.ToLocalTime()); } catch (Exception ex) { - Debug.WriteLine("SQLiteCache.Set(\"{0}\"): {1}", key, ex.Message); + Debug.WriteLine("SQLiteCache.Set({0}): {1}", key, ex.Message); } } @@ -216,7 +210,7 @@ namespace MapControl.Caching } catch (Exception ex) { - Debug.WriteLine("SQLiteCache.Remove(\"{0}\"): {1}", key, ex.Message); + Debug.WriteLine("SQLiteCache.Remove({0}): {1}", key, ex.Message); } } diff --git a/SQLiteCache/WPF/SQLiteCache.WPF.csproj b/SQLiteCache/WPF/SQLiteCache.WPF.csproj index 17eb6f2f..3321e7e3 100644 --- a/SQLiteCache/WPF/SQLiteCache.WPF.csproj +++ b/SQLiteCache/WPF/SQLiteCache.WPF.csproj @@ -48,8 +48,4 @@ - - - - diff --git a/SampleApps/WpfApplication/WpfApplication.csproj b/SampleApps/WpfApplication/WpfApplication.csproj index 2e576f1d..5afc6221 100644 --- a/SampleApps/WpfApplication/WpfApplication.csproj +++ b/SampleApps/WpfApplication/WpfApplication.csproj @@ -24,7 +24,9 @@ + +