Upgrade structure of code base

This commit is contained in:
h z
2024-07-03 12:20:08 +08:00
parent 5a94c716e3
commit dd68bede47

View File

@@ -1,5 +1,3 @@
using System.Diagnostics;
namespace Skeleton.DataStructure; namespace Skeleton.DataStructure;
/// <summary> /// <summary>
@@ -8,16 +6,12 @@ namespace Skeleton.DataStructure;
public class CacheItem public class CacheItem
{ {
public CacheItem(Func<CacheItem, object> cal) => ProxyCalculator = cal;
public static readonly CacheItem Null = new CacheItem<bool>(x => false);
/// <summary> /// <summary>
/// if the item needs update /// if the item needs update
/// </summary> /// </summary>
public bool Expired { get; protected set; } = true; public bool Expired { get; protected set; } = true;
internal HashSet<CacheItem> References { get; set; } = new(); public HashSet<CacheItem> References { get; set; } = new();
internal HashSet<CacheItem> Dependencies { get; set; } = new(); public HashSet<CacheItem> Dependencies { get; set; } = new();
private Func<object> Calculator => () => ProxyCalculator(this);
/// <summary> /// <summary>
/// tag the item and all dependencies as out dated /// tag the item and all dependencies as out dated
/// </summary> /// </summary>
@@ -29,76 +23,48 @@ public class CacheItem
c.Expire(); c.Expire();
} }
public TObject Get<TObject>() => (this as CacheItem<TObject>)!.Get;
private object? Value { get; set; }
public void Assign(object o) => UpdateCalculation(x => o);
public object Get()
{
if (Expired)
{
Value = Calculator();
Expired = false;
}
return Value!;
}
public TObject GetFrom<TObject>(CacheItem item) => (this as CacheItem<TObject>)!.GetFrom(item);
public object GetFrom(CacheItem item)
{
References.Add(item);
item.Dependencies.Add(this);
return Get();
}
public Func<CacheItem, object> ProxyCalculator { get; internal set; }
public void UpdateCalculation(Func<CacheItem, object> a) => ProxyCalculator = a;
} }
/// <inheritdoc /> /// <inheritdoc />
public class CacheItem<TObject> : CacheItem public class CacheItem<TObject> : CacheItem
{ {
public static readonly CacheItem<TObject> Null = new();
/// <summary> /// <summary>
/// construct by provide a method to update the value /// construct by provide a method to update the value
/// </summary> /// </summary>
/// <param name="rec"></param> /// <param name="rec"></param>
public CacheItem(Func<CacheItem, TObject> rec) : base(x => rec(x)) public CacheItem(Func<CacheItem?, TObject> rec) => ProxyCalculator = rec;
{
}
private TObject? Value { get; set; } public CacheItem() => ProxyCalculator = c => default;
protected TObject? Value { get; set; }
/// <summary> /// <summary>
/// return cached/updated value when reference is not used to calculate another cache item /// return cached/updated value when reference is not used to calculate another cache item
/// </summary> /// </summary>
public new TObject Get public virtual TObject? Get
{ {
get get
{ {
if (Expired) if (Expired)
{ {
Value = Calculator(); Value = ProxyCalculator(this);
Expired = false; Expired = false;
} }
return Value!; return Value;
} }
} }
private Func<TObject> Calculator => () => ProxyCalculator(this);
/// <summary> /// <summary>
/// provide trace information while calculating /// provide trace information while calculating
/// </summary> /// </summary>
public new Func<CacheItem, TObject> ProxyCalculator public Func<CacheItem, TObject?> ProxyCalculator { get; set; }
{
get => x => (TObject)base.ProxyCalculator(x);
set => base.ProxyCalculator = x => value(x)!;
}
/// <summary> /// <summary>
/// trace the dependency and return cached value/updated value /// trace the dependency and return cached value/updated value
/// </summary> /// </summary>
/// <param name="d"></param> /// <param name="d"></param>
/// <returns></returns> /// <returns></returns>
public new TObject GetFrom(CacheItem d) public TObject? GetFrom(CacheItem d)
{ {
References.Add(d); References.Add(d);
d.Dependencies.Add(this); d.Dependencies.Add(this);
@@ -108,7 +74,7 @@ public class CacheItem<TObject> : CacheItem
/// update the formula of item value /// update the formula of item value
/// </summary> /// </summary>
/// <param name="val"></param> /// <param name="val"></param>
public void UpdateCalculation(Func<CacheItem, TObject> val) public void UpdateCalculation(Func<CacheItem, TObject?> val)
{ {
Expire(); Expire();
foreach (CacheItem item in Dependencies) foreach (CacheItem item in Dependencies)
@@ -117,7 +83,6 @@ public class CacheItem<TObject> : CacheItem
ProxyCalculator = val; ProxyCalculator = val;
} }
public void Assign(TObject b) => UpdateCalculation(x => b); public void Assign(TObject b) => UpdateCalculation(x => b);
} }