|
1 | 1 | using System; |
2 | | -using System.Collections.Generic; |
3 | 2 | using System.Runtime.CompilerServices; |
4 | | -using System.Text; |
5 | 3 | using CacheTower.Internal; |
6 | 4 |
|
7 | | -namespace CacheTower |
| 5 | +namespace CacheTower; |
| 6 | + |
| 7 | +/// <summary> |
| 8 | +/// Container for the cache entry expiry date. |
| 9 | +/// </summary> |
| 10 | +public interface ICacheEntry |
8 | 11 | { |
9 | 12 | /// <summary> |
10 | | - /// Container for the cache entry expiry date. |
| 13 | + /// The expiry date for the cache entry. |
11 | 14 | /// </summary> |
12 | | - public abstract class CacheEntry |
13 | | - { |
14 | | - /// <summary> |
15 | | - /// The expiry date for the cache entry. |
16 | | - /// </summary> |
17 | | - public DateTime Expiry { get; } |
18 | | - |
19 | | - /// <summary> |
20 | | - /// Creates a new <see cref="CacheEntry"/> with the given expiry date. |
21 | | - /// </summary> |
22 | | - /// <param name="expiry">The expiry date of the cache entry. This will be rounded down to the second.</param> |
23 | | - protected CacheEntry(DateTime expiry) |
24 | | - { |
25 | | - //Force the resolution of the expiry date to be to the second |
26 | | - Expiry = new DateTime( |
27 | | - expiry.Year, expiry.Month, expiry.Day, expiry.Hour, expiry.Minute, expiry.Second, DateTimeKind.Utc |
28 | | - ); |
29 | | - } |
| 15 | + DateTime Expiry { get; } |
| 16 | +} |
30 | 17 |
|
31 | | - /// <summary> |
32 | | - /// Calculates the stale date for the cache entry using the provided <paramref name="cacheSettings"/>. |
33 | | - /// </summary> |
34 | | - /// <remarks> |
35 | | - /// If <see cref="CacheSettings.StaleAfter"/> is not configured, the stale date is the expiry date. |
36 | | - /// </remarks> |
37 | | - /// <param name="cacheSettings">The cache settings to use for the calculation.</param> |
38 | | - /// <returns>The date that the cache entry can be considered stale.</returns> |
39 | | - [MethodImpl(MethodImplOptions.AggressiveInlining)] |
40 | | - public DateTime GetStaleDate(CacheSettings cacheSettings) |
41 | | - { |
42 | | - if (cacheSettings.StaleAfter.HasValue) |
43 | | - { |
44 | | - return Expiry - cacheSettings.TimeToLive + cacheSettings.StaleAfter!.Value; |
45 | | - } |
46 | | - else |
47 | | - { |
48 | | - return Expiry; |
49 | | - } |
50 | | - } |
51 | | - } |
| 18 | +/// <summary> |
| 19 | +/// Container for the cached value and its expiry date. |
| 20 | +/// </summary> |
| 21 | +/// <typeparam name="T"></typeparam> |
| 22 | +public interface ICacheEntry<T> : ICacheEntry |
| 23 | +{ |
| 24 | + /// <summary> |
| 25 | + /// The cached value. |
| 26 | + /// </summary> |
| 27 | + T? Value { get; } |
| 28 | +} |
52 | 29 |
|
| 30 | +/// <summary> |
| 31 | +/// Extension methods for <see cref="ICacheEntry"/>. |
| 32 | +/// </summary> |
| 33 | +public static class CacheEntryExtensions |
| 34 | +{ |
53 | 35 | /// <summary> |
54 | | - /// Container for both the cached value and its expiry date. |
| 36 | + /// Calculates the stale date for an <see cref="ICacheEntry"/> based on the <paramref name="cacheEntry"/>'s expiry and <paramref name="cacheSettings"/>. |
55 | 37 | /// </summary> |
56 | | - /// <typeparam name="T"></typeparam> |
57 | | - public class CacheEntry<T> : CacheEntry, IEquatable<CacheEntry<T?>?> |
| 38 | + /// <remarks> |
| 39 | + /// When <see cref="CacheSettings.StaleAfter"/> is <see langword="null"/>, this will return the <paramref name="cacheEntry"/>'s expiry. |
| 40 | + /// </remarks> |
| 41 | + /// <param name="cacheEntry">The cache entry to get the stale date for.</param> |
| 42 | + /// <param name="cacheSettings">The cache settings to use as part of the stale date calculation.</param> |
| 43 | + /// <returns></returns> |
| 44 | + [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| 45 | + public static DateTime GetStaleDate(this ICacheEntry cacheEntry, CacheSettings cacheSettings) |
58 | 46 | { |
59 | | - /// <summary> |
60 | | - /// The cached value. |
61 | | - /// </summary> |
62 | | - public T? Value { get; } |
63 | | - |
64 | | - /// <summary> |
65 | | - /// Creates a new <see cref="CacheEntry"/> with the given <paramref name="value"/> and an expiry adjusted to the <paramref name="timeToLive"/>. |
66 | | - /// </summary> |
67 | | - /// <param name="value">The value to cache.</param> |
68 | | - /// <param name="timeToLive">The amount of time before the cache entry expires.</param> |
69 | | - internal CacheEntry(T? value, TimeSpan timeToLive) : this(value, DateTimeProvider.Now + timeToLive) { } |
70 | | - /// <summary> |
71 | | - /// Creates a new <see cref="CacheEntry"/> with the given <paramref name="value"/> and <paramref name="expiry"/>. |
72 | | - /// </summary> |
73 | | - /// <param name="value">The value to cache.</param> |
74 | | - /// <param name="expiry">The expiry date of the cache entry. This will be rounded down to the second.</param> |
75 | | - public CacheEntry(T? value, DateTime expiry) : base(expiry) |
| 47 | + if (cacheSettings.StaleAfter.HasValue) |
76 | 48 | { |
77 | | - Value = value; |
| 49 | + return cacheEntry.Expiry - cacheSettings.TimeToLive + cacheSettings.StaleAfter!.Value; |
78 | 50 | } |
79 | | - |
80 | | - /// <inheritdoc/> |
81 | | - public bool Equals(CacheEntry<T?>? other) |
| 51 | + else |
82 | 52 | { |
83 | | - if (other == null) |
84 | | - { |
85 | | - return false; |
86 | | - } |
87 | | - |
88 | | - return Equals(Value, other.Value) && |
89 | | - Expiry == other.Expiry; |
| 53 | + return cacheEntry.Expiry; |
90 | 54 | } |
| 55 | + } |
| 56 | +} |
91 | 57 |
|
92 | | - /// <inheritdoc/> |
93 | | - public override bool Equals(object? obj) |
94 | | - { |
95 | | - if (obj is CacheEntry<T?> objOfType) |
96 | | - { |
97 | | - return Equals(objOfType); |
98 | | - } |
| 58 | +/// <summary> |
| 59 | +/// Container for both the cached value and its expiry date. |
| 60 | +/// </summary> |
| 61 | +/// <typeparam name="T"></typeparam> |
| 62 | +/// <param name="Value">The value to cache.</param> |
| 63 | +/// <param name="Expiry">The expiry date of the cache entry. This will be rounded down to the second.</param> |
| 64 | +public sealed record CacheEntry<T>(T? Value, DateTime Expiry) : ICacheEntry<T> |
| 65 | +{ |
| 66 | + /// <summary> |
| 67 | + /// The cached value. |
| 68 | + /// </summary> |
| 69 | + public T? Value { get; } = Value; |
99 | 70 |
|
100 | | - return false; |
101 | | - } |
| 71 | + /// <summary> |
| 72 | + /// The expiry date for the cache entry. |
| 73 | + /// </summary> |
| 74 | + public DateTime Expiry { get; } = new DateTime( |
| 75 | + Expiry.Year, Expiry.Month, Expiry.Day, Expiry.Hour, Expiry.Minute, Expiry.Second, DateTimeKind.Utc |
| 76 | + ); |
102 | 77 |
|
103 | | - /// <inheritdoc/> |
104 | | - public override int GetHashCode() |
105 | | - { |
106 | | - return (Value?.GetHashCode() ?? 1) ^ Expiry.GetHashCode(); |
107 | | - } |
108 | | - } |
| 78 | + /// <summary> |
| 79 | + /// Creates a new <see cref="ICacheEntry"/> with the given <paramref name="value"/> and an expiry adjusted to the <paramref name="timeToLive"/>. |
| 80 | + /// </summary> |
| 81 | + /// <param name="value">The value to cache.</param> |
| 82 | + /// <param name="timeToLive">The amount of time before the cache entry expires.</param> |
| 83 | + internal CacheEntry(T? value, TimeSpan timeToLive) : this(value, DateTimeProvider.Now + timeToLive) { } |
109 | 84 | } |
0 commit comments