using System; using System.Collections.Generic; using System.Linq; using Skeleton.DataStructure; namespace Skeleton.Test.tests; public static class CacheItemTest { private class TestClass { public TestClass(int v) => Value = v; public int UpdateCount { get; private set; } = 0; public int ReferenceCount { get; private set; } = 0; private int InnerValue { get; set; } = 0; public int Value { get { ReferenceCount += 1; return InnerValue; } set { UpdateCount += 1; InnerValue = value; } } public static TestClass operator +(TestClass self, TestClass other) => new (self.Value + other.Value); public static TestClass operator *(TestClass self, TestClass other) => new(self.Value * other.Value); public static TestClass operator *(TestClass self, int other) => new(self.Value * other); public static TestClass operator +(TestClass self, int other) => new(self.Value + other); public static TestClass operator *(int other, TestClass self) => self * other; public static TestClass operator +(int other, TestClass self) => self + other; public static implicit operator TestClass(int x) => new (x); } private class TestClass2 { public TestClass2() { BA = new(x => Childs.Count); BB = new(x => Childs.Select(c => c.BA.GetFrom(x)).Sum()); } public HashSet Childs { get; set; } = new(); public int A { get; set; } public CacheItem BA { get; set; } public CacheItem BB { get; set; } public void Add(TestClass2 x) { BA.Expire(); BB.Expire(); Childs.Add(x); } public void Remove(TestClass2 x) { BA.Expire(); BB.Expire(); Childs.Remove(x); } } [Test] public static void Test() { CacheItem t0 = new CacheItem(_ => 0); CacheItem a = new CacheItem(_ => 1); CacheItem b = new CacheItem(x => a.GetFrom(x).Value * 2); CacheItem c = new CacheItem(x => b.GetFrom(x).Value * b.GetFrom(x).Value); CacheItem d = new CacheItem(x => b.GetFrom(x).Value - a.GetFrom(x).Value + t0.GetFrom(x)); Assert.IsTrue(a.Expired); Assert.IsTrue(b.Expired); Assert.IsTrue(c.Expired); Assert.IsTrue(d.Expired); Assert.That(a.Get.Value, Is.EqualTo(1)); Assert.That(b.Get.Value, Is.EqualTo(2)); Assert.That(c.Get.Value, Is.EqualTo(4)); Assert.That(d.Get.Value, Is.EqualTo(1)); a.UpdateCalculation(_ => 3); Assert.IsTrue(a.Expired); Assert.IsTrue(b.Expired); Assert.IsTrue(c.Expired); Assert.IsTrue(d.Expired); Assert.That(a.Get.Value, Is.EqualTo(3)); Assert.That(b.Get.Value, Is.EqualTo(6)); Assert.That(c.Get.Value, Is.EqualTo(36)); Assert.That(d.Get.Value, Is.EqualTo(3)); b.UpdateCalculation(_ => 9); Assert.IsFalse(a.Expired); Assert.IsTrue(b.Expired); Assert.IsTrue(c.Expired); Assert.IsTrue(d.Expired); Assert.That(a.Get.Value, Is.EqualTo(3)); Assert.That(b.Get.Value, Is.EqualTo(9)); Assert.That(c.Get.Value, Is.EqualTo(81)); Assert.That(d.Get.Value, Is.EqualTo(6)); c.UpdateCalculation(x => a.GetFrom(x) * b.GetFrom(x)); Assert.IsFalse(a.Expired); Assert.IsFalse(b.Expired); Assert.IsTrue(c.Expired); Assert.IsFalse(d.Expired); Assert.That(a.Get.Value, Is.EqualTo(3)); Assert.That(b.Get.Value, Is.EqualTo(9)); Assert.That(c.Get.Value, Is.EqualTo(27)); Assert.That(d.Get.Value, Is.EqualTo(6)); d.UpdateCalculation(x => a.GetFrom(x) + b.GetFrom(x) + c.GetFrom(x)); Assert.IsFalse(a.Expired); Assert.IsFalse(b.Expired); Assert.IsFalse(c.Expired); Assert.IsTrue(d.Expired); Assert.That(a.Get.Value, Is.EqualTo(3)); Assert.That(b.Get.Value, Is.EqualTo(9)); Assert.That(c.Get.Value, Is.EqualTo(27)); Assert.That(d.Get.Value, Is.EqualTo(39)); Assert.That(t0.Get.UpdateCount, Is.EqualTo(1)); Assert.That(t0.Get.ReferenceCount, Is.EqualTo(3)); int noUse = d.Get.Value; noUse += d.Get.Value; noUse += d.Get.Value; Assert.That(noUse, Is.EqualTo(117)); Assert.That(t0.Get.ReferenceCount, Is.EqualTo(3)); } [Test] public static void Test2() { CacheItem a = new (_ => 1); CacheItem b = new (_ => 3); CacheItem c = new(x => a.GetFrom(x) + b.GetFrom(x)); Assert.IsTrue(a.Expired); Assert.IsTrue(b.Expired); Assert.IsTrue(c.Expired); Assert.That(a.Get, Is.EqualTo(1)); Assert.That(b.Get, Is.EqualTo(3)); Assert.That(c.Get, Is.EqualTo(4)); Assert.IsFalse(a.Expired); Assert.IsFalse(b.Expired); Assert.IsFalse(c.Expired); } [Test] public static void Test3() { TestClass2 a = new(); TestClass2 b = new(); TestClass2 c = new(); a.Add(b); a.Add(c); b.Add(c); Assert.That(a.BA.Get, Is.EqualTo(2)); Assert.That(a.BB.Get, Is.EqualTo(1)); a.Remove(b); Assert.That(a.BA.Get, Is.EqualTo(1)); Assert.That(a.BB.Get, Is.EqualTo(0)); Assert.That(b.BA.Get, Is.EqualTo(1)); } [Test] public static void Test4() { CacheItem x = new CacheItem(s => 1); CacheItem w = new CacheItem(a => x.GetFrom(a) + x.GetFrom(a)); CacheItem g = new CacheItem(a => w.GetFrom(a) + w.GetFrom(a) + x.GetFrom(a)); Assert.That(g.Get, Is.EqualTo(5)); x.Assign(2); Console.WriteLine(g.Get); Assert.That(g.Get, Is.EqualTo(10)); } [Test] public static void Test5() { CacheItem x1 = new CacheItem(x => 1); CacheItem x2 = new CacheItem(x => x1.GetFrom(x)); CacheItem x3 = new CacheItem(x => x2.GetFrom(x)); CacheItem x4 = new CacheItem(x => x3.GetFrom(x)); Console.WriteLine(x4.Get); x1.Assign(3); Assert.IsTrue(x2.Expired); Assert.IsTrue(x3.Expired); Assert.IsTrue(x4.Expired); Console.WriteLine(x4.Get); } }