diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 79b5e5a..34d4c8f 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -42,7 +42,7 @@ jobs:
with:
testProject: ${{env.TESTS_PROJECT}}
output: 'lcov.info'
- threshold: 50
+ threshold: 30
outputFormat: 'lcov'
excludes: '[ConsoleTests]*'
- name: coveralls
diff --git a/.gitignore b/.gitignore
index f5e07c3..705d05d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@
**/Bin/*
**/obj/*
**/Obj/*
+**/*.user
+**/lcov.info
diff --git a/DictionaryGenerator/DictionaryGenerator.csproj b/DictionaryGenerator/DictionaryGenerator.csproj
new file mode 100644
index 0000000..b9de063
--- /dev/null
+++ b/DictionaryGenerator/DictionaryGenerator.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/DictionaryGenerator/ExpirationalGenerator.cs b/DictionaryGenerator/ExpirationalGenerator.cs
new file mode 100644
index 0000000..c5365a7
--- /dev/null
+++ b/DictionaryGenerator/ExpirationalGenerator.cs
@@ -0,0 +1,481 @@
+using System.Text;
+
+namespace DictionaryGenerator;
+
+public class ExpirationalGenerator
+{
+
+ private static string GenerateTypeParameters(int start, int count, bool withValue = true)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = start; i < count + 1; i++)
+ {
+ builder.Append($"K{i}");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ if (withValue)
+ {
+ builder.Append(", V");
+ }
+ return builder.ToString();
+ }
+
+ private static string GenerateParametersDeclaration(int start, int count)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = start; i < count + 1; i++)
+ {
+ builder.Append($"K{i} k{i}");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ return builder.ToString();
+ }
+
+ private static string GenerateParameters(int start, int count, bool withValue = false)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = start; i < count + 1; i++)
+ {
+ builder.Append($"k{i}");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ if (withValue)
+ {
+ builder.Append(", value");
+ }
+ return builder.ToString();
+ }
+
+ private static string GenerateUsingsAndNamespace()
+ {
+ var header = $@"
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace multiDimensionalDictionary {{";
+ return header;
+ }
+
+
+ private static string GenerateExpirations(int count)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i <= count; i++)
+ {
+ builder.AppendLine($"TimeSpan ExpirationSpan{i};");
+ }
+
+ return builder.ToString();
+ }
+
+
+ private static string GenerateConstructorMillis(int count)
+ {
+ var builder = new StringBuilder();
+ builder.Append("public ExpirationalMultiDimensionDictionary(");
+ for (int i = 1; i <= count; i++)
+ {
+ builder.Append($"long expiration{i}");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ builder.Append(") : this(");
+ for (int i = 1; i <= count; i++)
+ {
+ builder.Append($"TimeSpan.FromMilliseconds(expiration{i})");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ builder.Append(")");
+ builder.Append(@"
+{
+ }");
+ return builder.ToString();
+ }
+
+ private static string GenerateConstructorTimeSpan(int count)
+ {
+ var builder = new StringBuilder();
+ builder.Append("public ExpirationalMultiDimensionDictionary(");
+ for (int i = 1; i <= count; i++)
+ {
+ builder.Append($"TimeSpan expiration{i}");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ builder.AppendLine(") ");
+ builder.Append("{");
+ for (int i = 1; i <= count; i++)
+ {
+ builder.Append($"ExpirationSpan{i} = expiration{i};");
+ }
+
+ builder.AppendLine(
+ $"Data = new ConcurrentDictionary subData)>();");
+ builder.Append("}");
+ return builder.ToString();
+ }
+
+ private static string GenerateConstructors(int count)
+ {
+ return $@"
+{GenerateConstructorTimeSpan(count)}
+
+{GenerateConstructorMillis(count)}";
+ }
+
+ private static string GenerateClassDeclarationGenerateHeader(int count)
+ {
+ var header = $@"
+
+public class ExpirationalMultiDimensionDictionary<{GenerateTypeParameters(1, count)}>
+ {{
+ {GenerateExpirations(count)}
+
+ {GenerateConstructors(count)}
+
+ protected ConcurrentDictionary subData)> Data{{ get;set; }}
+
+ public ExpirationalMultiDimensionDictionary() : base()
+ {{
+ Data = new ConcurrentDictionary subData)>();
+ }}
+
+
+";
+
+
+
+ return header;
+ }
+
+ private static string GenerateContains(int count)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < count + 1; i++)
+ {
+ builder.AppendLine(GenerateContainsKey(count, i));
+ builder.AppendLine();
+ }
+
+ return builder.ToString();
+ }
+
+
+
+ private static string GenerateContainsKey(int count, int level)
+ {
+ if (level == 1)
+ {
+ return @"public bool ContainsKey(K1 k1) {
+Invalidate();
+return Data.ContainsKey(k1);
+}";
+ }
+ else
+ {
+ return
+ $@"public bool ContainsKey({GenerateParametersDeclaration(1, level)}) {{
+Invalidate();
+return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey({GenerateParameters(2, level)});
+}}";
+ }
+ }
+
+ private static string GenerateGetKeys(int count)
+ {
+
+ var parameterTypes = count == 2 ? "K2" : $"({GenerateTypeParameters(2, count, false)})";
+
+ var get = $@"public List<({GenerateTypeParameters(1, count, false)})> GetKeys()
+ {{
+Invalidate();
+ var keys = new List<({GenerateTypeParameters(1, count, false)})>();
+ foreach (var kvp in Data)
+ {{
+ List<{parameterTypes}> subkeys = kvp.Value.subData.GetKeys();
+ foreach (var subkey in subkeys)
+ {{
+ keys.Add((kvp.Key, ";
+ for (int i = 1; i < count; i++)
+ {
+ if (count == 2)
+ {
+ get += "subkey";
+ }
+ else
+ {
+ get += $"subkey.Item{i}";
+ }
+
+ if (i < count-1)
+ {
+ get += ", ";
+ }
+ }
+
+ get += "));";
+
+ get+=$@"}}
+ }}
+ return keys;
+}}";
+ return get;
+ }
+
+
+ private static string GenerateAssert(string type, string name)
+ {
+ return $@"DictionaryAssertions.AssertNotNull<{type}>({name}, ""{name}"");";
+ }
+
+ private static string GenerateAsserts(int count, bool withValue = true)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < count + 1; i++)
+ {
+ builder.AppendLine(GenerateAssert($"K{i}", $"k{i}"));
+ builder.AppendLine();
+ }
+
+ if (withValue)
+ {
+ builder.AppendLine(GenerateAssert($"V", "value"));
+ }
+ builder.AppendLine();
+ return builder.ToString();
+ }
+
+ private static string GenerateExpirationParameters(int start, int count)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = start; i < count + 1; i++)
+ {
+ builder.Append($"ExpirationSpan{i}");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ return builder.ToString();
+ }
+
+ private static string GeneratePut(int count)
+ {
+ var put = $@"public void Put({GenerateParametersDeclaration(1, count)}, V value)
+ {{
+Invalidate();
+ {GenerateAsserts(count)}
+
+ var secondDimentionData = new ExpirationalMultiDimensionDictionary<{GenerateTypeParameters(2,count,true)}>({GenerateExpirationParameters(2,count)});
+
+ if (Data.ContainsKey(k1))
+ {{
+ secondDimentionData = Data[k1].subData;
+ }}
+
+ secondDimentionData.Put({GenerateParameters(2,count,true)});
+
+ Data[k1] = (DateTime.Now, secondDimentionData);
+ }}";
+ return put;
+ }
+
+ private static string GenerateGet(int count, int level)
+ {
+ if (level == count)
+ {
+ var get = $@"public V Get({GenerateParametersDeclaration(1, level)})
+ {{
+Invalidate();
+{GenerateAsserts(count, false)}
+
+ if (Data.TryGetValue(k1, out var secondDimensionData))
+ {{
+ return secondDimensionData.subData.Get({GenerateParameters(2, count, false)});
+ }}
+
+ throw new KeyNotFoundException();
+ }}";
+ return get;
+ }
+
+ if (level == 1)
+ {
+ return $@"public ExpirationalMultiDimensionDictionary<{GenerateTypeParameters(2,count, true)}> Get(K1 k1)
+ {{
+ return Data[k1].subData;
+ }}";
+ }
+
+ return $@"public ExpirationalMultiDimensionDictionary<{GenerateTypeParameters(level+1,count,true)}> Get({GenerateParametersDeclaration(1,level)})
+ {{
+ return Data[k1].subData.Get({GenerateParameters(2,level,false)});
+ }}";
+ }
+
+ private static string GenerateGets(int count)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < count + 1; i++)
+ {
+ builder.AppendLine(GenerateGet(count, i));
+ builder.AppendLine();
+ }
+
+ return builder.ToString();
+ }
+
+
+ public static string GenerateClass(int count)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ builder.AppendLine(GenerateClassDeclarationGenerateHeader(count))
+ .AppendLine()
+ .AppendLine("#region ContainsKey")
+ .AppendLine(GenerateContains(count))
+ .AppendLine("#endregion")
+ .AppendLine()
+ .AppendLine("#region getKeys")
+ .AppendLine(GenerateGetKeys(count))
+ .AppendLine("#endregion")
+ .AppendLine()
+ .AppendLine("#region Put")
+ .AppendLine(GeneratePut(count))
+ .AppendLine("#endregion")
+ .AppendLine()
+ .AppendLine("#region Get")
+ .AppendLine(GenerateGets(count))
+ .AppendLine("#endregion")
+ .AppendLine("#region Remove")
+ .AppendLine(GenerateRemoves(count))
+ .AppendLine("#endregion")
+ .AppendLine(GenerateInvalidate(count))
+ .AppendLine("}");
+ return builder.ToString();
+ }
+
+ public static string GenerateRemove(int count, int level)
+ {
+ if (level == 1)
+ {
+ return @"public new void Remove(K1 k1)
+ {
+Invalidate();
+ Data.Remove(k1, out var ignore);
+ }";
+ }
+ else
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.AppendLine($"public void Remove({GenerateParametersDeclaration(1, level)})")
+ .AppendLine("{")
+ .AppendLine("Invalidate();")
+ .Append("Data[k1].subData");
+ for (int i = 2; i < level; i++)
+ {
+ builder.Append($".Get(k{i})");
+ }
+
+ builder.AppendLine($".Remove(k{level});")
+ .AppendLine("}");
+ return builder.ToString();
+ }
+ }
+
+
+
+ public static string GenerateRemoves(int count)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < count + 1; i++)
+ {
+ builder.AppendLine(GenerateRemove(count, i));
+ builder.AppendLine();
+ }
+
+ return builder.ToString();
+ }
+
+ public static string GenerateInvalidate(int count)
+ {
+ string invalidate = $@"
+
+public void _Remove(K1 k1)
+ {{
+ (DateTime date, ExpirationalMultiDimensionDictionary<{GenerateTypeParameters(2,count,true)}> subData) ignore = default;
+ Data.TryRemove(k1, out ignore);
+ }}
+
+public void Invalidate()
+ {{
+ DateTime now = DateTime.Now;
+ List toRemove = new List();
+ foreach (var entry in Data)
+ {{
+ var age = now - entry.Value.date;
+ if (age > ExpirationSpan1)
+ {{
+ toRemove.Add(entry.Key);
+ }}
+ }}
+
+ if (toRemove.Any())
+ {{
+ foreach (var k1 in toRemove)
+ {{
+ _Remove(k1);
+ }}
+ }}
+ }}";
+ return invalidate;
+ }
+
+ public static string Generate(int count)
+ {
+ if (count <= 1)
+ {
+ throw new InvalidOperationException("NO ! You can't do so !");
+ }
+ StringBuilder builder = new StringBuilder();
+ builder
+ .AppendLine(GenerateUsingsAndNamespace())
+ .AppendLine(GenerateClass(count))
+ .AppendLine("}");
+
+
+
+ return builder.ToString();
+ }
+
+}
\ No newline at end of file
diff --git a/DictionaryGenerator/Generator.cs b/DictionaryGenerator/Generator.cs
new file mode 100644
index 0000000..cc2531f
--- /dev/null
+++ b/DictionaryGenerator/Generator.cs
@@ -0,0 +1,331 @@
+using System.Text;
+
+namespace DictionaryGenerator;
+
+public class Generator
+{
+
+ private static string GenerateTypeParameters(int start, int count, bool withValue = true)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = start; i < count + 1; i++)
+ {
+ builder.Append($"K{i}");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ if (withValue)
+ {
+ builder.Append(", V");
+ }
+ return builder.ToString();
+ }
+
+ private static string GenerateParametersDeclaration(int start, int count)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = start; i < count + 1; i++)
+ {
+ builder.Append($"K{i} k{i}");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ return builder.ToString();
+ }
+
+ private static string GenerateParameters(int start, int count, bool withValue = false)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = start; i < count + 1; i++)
+ {
+ builder.Append($"k{i}");
+ if (i < count)
+ {
+ builder.Append(", ");
+ }
+ }
+
+ if (withValue)
+ {
+ builder.Append(", value");
+ }
+ return builder.ToString();
+ }
+
+ private static string GenerateUsingsAndNamespace()
+ {
+ var header = $@"
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using multiDimensionalDictionary;
+
+namespace multiDimensionalDictionary {{";
+ return header;
+ }
+
+ private static string GenerateClassDeclarationGenerateHeader(int count)
+ {
+ var header = $@"
+
+public class Multi<{GenerateTypeParameters(1, count)}>
+ {{
+ protected ConcurrentDictionary> Data{{ get;set; }}
+
+ public Multi() : base()
+ {{
+ Data = new ConcurrentDictionary>();
+ }}";
+ return header;
+ }
+
+ private static string GenerateContains(int count)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < count + 1; i++)
+ {
+ builder.AppendLine(GenerateContainsKey(count, i));
+ builder.AppendLine();
+ }
+
+ return builder.ToString();
+ }
+
+
+
+ private static string GenerateContainsKey(int count, int level)
+ {
+ if (level == 1)
+ {
+ return "public bool ContainsKey(K1 k1) => Data.ContainsKey(k1);";
+ }
+ else
+ {
+ return
+ $"public bool ContainsKey({GenerateParametersDeclaration(1, level)}) => Data.ContainsKey(k1) && Data[k1].ContainsKey({GenerateParameters(2, level)});";
+ }
+ }
+
+ private static string GenerateGetKeys(int count)
+ {
+
+ var parameterTypes = count == 2 ? "K2" : $"({GenerateTypeParameters(2, count, false)})";
+
+ var get = $@"public List<({GenerateTypeParameters(1, count, false)})> GetKeys()
+ {{
+ var keys = new List<({GenerateTypeParameters(1, count, false)})>();
+ foreach (var kvp in Data)
+ {{
+ List<{parameterTypes}> subkeys = kvp.Value.GetKeys();
+ foreach (var subkey in subkeys)
+ {{
+ keys.Add((kvp.Key, ";
+ for (int i = 1; i < count; i++)
+ {
+ if (count == 2)
+ {
+ get += "subkey";
+ }
+ else
+ {
+ get += $"subkey.Item{i}";
+ }
+
+ if (i < count-1)
+ {
+ get += ", ";
+ }
+ }
+
+ get += "));";
+
+ get+=$@"}}
+ }}
+ return keys;
+}}";
+ return get;
+ }
+
+
+ private static string GenerateAssert(string type, string name)
+ {
+ return $@"DictionaryAssertions.AssertNotNull<{type}>({name}, ""{name}"");";
+ }
+
+ private static string GenerateAsserts(int count, bool withValue = true)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < count + 1; i++)
+ {
+ builder.AppendLine(GenerateAssert($"K{i}", $"k{i}"));
+ builder.AppendLine();
+ }
+
+ if (withValue)
+ {
+ builder.AppendLine(GenerateAssert($"V", "value"));
+ }
+ builder.AppendLine();
+ return builder.ToString();
+ }
+
+ private static string GeneratePut(int count)
+ {
+ var put = $@"public void Put({GenerateParametersDeclaration(1, count)}, V value)
+ {{
+
+ {GenerateAsserts(count)}
+
+ var secondDimentionData = new Multi<{GenerateTypeParameters(2,count,true)}>();
+
+ if (Data.ContainsKey(k1))
+ {{
+ secondDimentionData = Data[k1];
+ }}
+
+ secondDimentionData.Put({GenerateParameters(2,count,true)});
+
+ Data[k1] = secondDimentionData;
+ }}";
+ return put;
+ }
+
+ private static string GenerateGet(int count, int level)
+ {
+ if (level == count)
+ {
+ var get = $@"public V Get({GenerateParametersDeclaration(1, level)})
+ {{
+{GenerateAsserts(count, false)}
+
+ if (Data.TryGetValue(k1, out Multi<{GenerateTypeParameters(2, count, true)}> secondDimensionData))
+ {{
+ return secondDimensionData.Get({GenerateParameters(2, count, false)});
+ }}
+
+ throw new KeyNotFoundException();
+ }}";
+ return get;
+ }
+
+ if (level == 1)
+ {
+ return $@"public Multi<{GenerateTypeParameters(2,count, true)}> Get(K1 k1)
+ {{
+ return Data[k1];
+ }}";
+ }
+
+ return $@"public Multi<{GenerateTypeParameters(level+1,count,true)}> Get({GenerateParametersDeclaration(1,level)})
+ {{
+ return Data[k1].Get({GenerateParameters(2,level,false)});
+ }}";
+ }
+
+ private static string GenerateGets(int count)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < count + 1; i++)
+ {
+ builder.AppendLine(GenerateGet(count, i));
+ builder.AppendLine();
+ }
+
+ return builder.ToString();
+ }
+
+
+ public static string GenerateClass(int count)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ builder.AppendLine(GenerateClassDeclarationGenerateHeader(count))
+ .AppendLine()
+ .AppendLine("#region ContainsKey")
+ .AppendLine(GenerateContains(count))
+ .AppendLine("#endregion")
+ .AppendLine()
+ .AppendLine("#region getKeys")
+ .AppendLine(GenerateGetKeys(count))
+ .AppendLine("#endregion")
+ .AppendLine()
+ .AppendLine("#region Put")
+ .AppendLine(GeneratePut(count))
+ .AppendLine("#endregion")
+ .AppendLine()
+ .AppendLine("#region Get")
+ .AppendLine(GenerateGets(count))
+ .AppendLine("#endregion")
+ .AppendLine("#region Remove")
+ .AppendLine(GenerateRemoves(count))
+ .AppendLine("#endregion")
+
+ .AppendLine("}");
+ return builder.ToString();
+ }
+
+ public static string GenerateRemove(int count, int level)
+ {
+ if (level == 1)
+ {
+ return @"public new void Remove(K1 k1)
+ {
+ Data.Remove(k1, out var ignore);
+ }";
+ }
+ else
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.AppendLine($"public void Remove({GenerateParametersDeclaration(1, level)})")
+ .AppendLine("{")
+ .Append("Data[k1]");
+ for (int i = 2; i < level; i++)
+ {
+ builder.Append($".Get(k{i})");
+ }
+
+ builder.AppendLine($".Remove(k{level});")
+ .AppendLine("}");
+ return builder.ToString();
+ }
+ }
+
+ public static string GenerateRemoves(int count)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < count + 1; i++)
+ {
+ builder.AppendLine(GenerateRemove(count, i));
+ builder.AppendLine();
+ }
+
+ return builder.ToString();
+ }
+
+ public static string Generate(int count)
+ {
+ if (count <= 1)
+ {
+ throw new InvalidOperationException("NO ! You can't do so !");
+ }
+ StringBuilder builder = new StringBuilder();
+ builder
+ .AppendLine(GenerateUsingsAndNamespace())
+ .AppendLine(GenerateClass(count))
+ .AppendLine("}");
+
+
+
+ return builder.ToString();
+ }
+
+}
\ No newline at end of file
diff --git a/DictionaryGenerator/Program.cs b/DictionaryGenerator/Program.cs
new file mode 100644
index 0000000..f5dcdeb
--- /dev/null
+++ b/DictionaryGenerator/Program.cs
@@ -0,0 +1,16 @@
+// See https://aka.ms/new-console-template for more information
+
+using System.Text;
+using DictionaryGenerator;
+
+for (int i = 2; i <= 10; i++)
+{
+
+ string g = ExpirationalGenerator.Generate(i);
+
+ File.WriteAllText(
+ $@"C:\Users\olduh\dev\MultiDimensionDictionary\MultiDimensionDictionary\expirationalMultiDimensionDictionary\expirationalMulti{i}.cs", g);
+}
+
+
+
diff --git a/MultiDimensionDictionary.sln b/MultiDimensionDictionary.sln
index 68b5982..0da8f93 100644
--- a/MultiDimensionDictionary.sln
+++ b/MultiDimensionDictionary.sln
@@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleTests", "ConsoleTest
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiDimensionTests", "MultiDimensionTests\MultiDimensionTests.csproj", "{4DEEF201-423C-45EF-9FA9-BCF596DC8BCF}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DictionaryGenerator", "DictionaryGenerator\DictionaryGenerator.csproj", "{D0CB6C84-4C66-47F5-98DE-F7CF2ACD1E3E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -24,5 +26,9 @@ Global
{4DEEF201-423C-45EF-9FA9-BCF596DC8BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4DEEF201-423C-45EF-9FA9-BCF596DC8BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4DEEF201-423C-45EF-9FA9-BCF596DC8BCF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0CB6C84-4C66-47F5-98DE-F7CF2ACD1E3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0CB6C84-4C66-47F5-98DE-F7CF2ACD1E3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0CB6C84-4C66-47F5-98DE-F7CF2ACD1E3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0CB6C84-4C66-47F5-98DE-F7CF2ACD1E3E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/MultiDimensionDictionary/DictionaryAssertions.cs b/MultiDimensionDictionary/DictionaryAssertions.cs
index 73a414a..821556d 100644
--- a/MultiDimensionDictionary/DictionaryAssertions.cs
+++ b/MultiDimensionDictionary/DictionaryAssertions.cs
@@ -13,8 +13,9 @@ public static void AssertNotNull(T val, string name)
throw new ArgumentNullException(name);
}
}
-
- public static ICheckLink>> ContainsKey(this ICheck> context, K key)
+
+ public static ICheckLink>> ContainsKey(
+ this ICheck> context, K key)
{
ExtensibilityHelper.BeginCheck(context)
.FailWhen(sut => !sut.ContainsKey(key), "dictionary does not contains key {expected}.")
@@ -23,8 +24,9 @@ public static void AssertNotNull(T val, string name)
.EndCheck();
return ExtensibilityHelper.BuildCheckLink(context);
}
-
- public static ICheckLink>> ContainsKey(this ICheck> context, K1 key1, K2 key2)
+
+ public static ICheckLink>> ContainsKey(
+ this ICheck> context, K1 key1, K2 key2)
{
ExtensibilityHelper.BeginCheck(context)
.FailWhen(sut => !sut.ContainsKey(key1, key2), "dictionary does not contains key {expected}.")
@@ -33,8 +35,9 @@ public static void AssertNotNull(T val, string name)
.EndCheck();
return ExtensibilityHelper.BuildCheckLink(context);
}
-
- public static ICheckLink>> ContainsKey(this ICheck> context, K1 key1, K2 key2, K3 key3)
+
+ public static ICheckLink>> ContainsKey(
+ this ICheck> context, K1 key1, K2 key2, K3 key3)
{
ExtensibilityHelper.BeginCheck(context)
.FailWhen(sut => !sut.ContainsKey(key1, key2, key3), "dictionary does not contains key {expected}.")
@@ -43,22 +46,43 @@ public static void AssertNotNull(T val, string name)
.EndCheck();
return ExtensibilityHelper.BuildCheckLink(context);
}
-
- public static ICheckLink>> ContainsKey(this ICheck> context, K1 key1, K2 key2, K3 key3, K4 key4)
+
+ public static ICheckLink>> ContainsKey(
+ this ICheck> context, K1 key1, K2 key2, K3 key3, K4 key4)
{
ExtensibilityHelper.BeginCheck(context)
- .FailWhen(sut => !sut.ContainsKey(key1, key2, key3, key4), "dictionary does not contains key {expected}.")
+ .FailWhen(sut => !sut.ContainsKey(key1, key2, key3, key4),
+ "dictionary does not contains key {expected}.")
.DefineExpectedValue($"{key1.ToString()}.{key2.ToString()}.{key3.ToString()}.{key4.ToString()}")
.OnNegate("dictionary contains key {expected}.")
.EndCheck();
return ExtensibilityHelper.BuildCheckLink(context);
}
-
- public static ICheckLink>> ContainsKey(this ICheck> context, K1 key1, K2 key2, K3 key3, K4 key4, K5 key5)
+
+ public static ICheckLink>>
+ ContainsKey(this ICheck> context,
+ K1 key1, K2 key2, K3 key3, K4 key4, K5 key5)
+ {
+ ExtensibilityHelper.BeginCheck(context)
+ .FailWhen(sut => !sut.ContainsKey(key1, key2, key3, key4, key5),
+ "dictionary does not contains key {expected}.")
+ .DefineExpectedValue(
+ $"{key1.ToString()}.{key2.ToString()}.{key3.ToString()}.{key4.ToString()}.{key5.ToString()}")
+ .OnNegate("dictionary contains key {expected}.")
+ .EndCheck();
+ return ExtensibilityHelper.BuildCheckLink(context);
+ }
+
+ public static ICheckLink>>
+ ContainsKey(
+ this ICheck> context, K1 key1, K2 key2, K3 key3,
+ K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9, K10 key10)
{
ExtensibilityHelper.BeginCheck(context)
- .FailWhen(sut => !sut.ContainsKey(key1, key2, key3, key4,key5), "dictionary does not contains key {expected}.")
- .DefineExpectedValue($"{key1.ToString()}.{key2.ToString()}.{key3.ToString()}.{key4.ToString()}.{key5.ToString()}")
+ .FailWhen(sut => !sut.ContainsKey(key1, key2, key3, key4, key5, key6, key7, key8, key9, key10),
+ "dictionary does not contains key {expected}.")
+ .DefineExpectedValue(
+ $"{key1.ToString()}.{key2.ToString()}.{key3.ToString()}.{key4.ToString()}.{key5.ToString()}")
.OnNegate("dictionary contains key {expected}.")
.EndCheck();
return ExtensibilityHelper.BuildCheckLink(context);
diff --git a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary.cs b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMulti1.cs
similarity index 86%
rename from MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary.cs
rename to MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMulti1.cs
index dff2a27..0947dfc 100644
--- a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary.cs
+++ b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMulti1.cs
@@ -9,17 +9,19 @@ public class ExpirationalMultiDimensionDictionary
{
private TimeSpan ExpirationSpan;
- protected ConcurrentDictionary Data { get; set; }
+ protected ConcurrentDictionary Data { get; set; }
-
- public ExpirationalMultiDimensionDictionary(long expiration1MMillis) : this (TimeSpan.FromMilliseconds(expiration1MMillis))
+
+ public ExpirationalMultiDimensionDictionary(long expiration1MMillis) : this(
+ TimeSpan.FromMilliseconds(expiration1MMillis))
{
-
+
}
+
public ExpirationalMultiDimensionDictionary(TimeSpan expirationSpan)
{
ExpirationSpan = expirationSpan;
- Data = new ConcurrentDictionary();
+ Data = new ConcurrentDictionary();
}
public void Invalidate()
@@ -73,10 +75,10 @@ public void Remove(K1 k1)
Invalidate();
_Remove(k1);
}
-
+
public void _Remove(K1 k1)
{
- (DateTime,V) ignore;
+ (DateTime, V) ignore;
Data.TryRemove(k1, out ignore);
}
@@ -91,5 +93,5 @@ public void Clear()
-
+
}
\ No newline at end of file
diff --git a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti10.cs b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti10.cs
new file mode 100644
index 0000000..dc28a7d
--- /dev/null
+++ b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti10.cs
@@ -0,0 +1,391 @@
+
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace multiDimensionalDictionary
+{
+
+
+ public class ExpirationalMultiDimensionDictionary
+ {
+ TimeSpan ExpirationSpan1;
+ TimeSpan ExpirationSpan2;
+ TimeSpan ExpirationSpan3;
+ TimeSpan ExpirationSpan4;
+ TimeSpan ExpirationSpan5;
+ TimeSpan ExpirationSpan6;
+ TimeSpan ExpirationSpan7;
+ TimeSpan ExpirationSpan8;
+ TimeSpan ExpirationSpan9;
+ TimeSpan ExpirationSpan10;
+
+
+
+ public ExpirationalMultiDimensionDictionary(TimeSpan expiration1, TimeSpan expiration2, TimeSpan expiration3,
+ TimeSpan expiration4, TimeSpan expiration5, TimeSpan expiration6, TimeSpan expiration7,
+ TimeSpan expiration8, TimeSpan expiration9, TimeSpan expiration10)
+ {
+ ExpirationSpan1 = expiration1;
+ ExpirationSpan2 = expiration2;
+ ExpirationSpan3 = expiration3;
+ ExpirationSpan4 = expiration4;
+ ExpirationSpan5 = expiration5;
+ ExpirationSpan6 = expiration6;
+ ExpirationSpan7 = expiration7;
+ ExpirationSpan8 = expiration8;
+ ExpirationSpan9 = expiration9;
+ ExpirationSpan10 = expiration10;
+ Data =
+ new ConcurrentDictionary subData)>();
+ }
+
+ public ExpirationalMultiDimensionDictionary(long expiration1, long expiration2, long expiration3,
+ long expiration4, long expiration5, long expiration6, long expiration7, long expiration8, long expiration9,
+ long expiration10) : this(TimeSpan.FromMilliseconds(expiration1), TimeSpan.FromMilliseconds(expiration2),
+ TimeSpan.FromMilliseconds(expiration3), TimeSpan.FromMilliseconds(expiration4),
+ TimeSpan.FromMilliseconds(expiration5), TimeSpan.FromMilliseconds(expiration6),
+ TimeSpan.FromMilliseconds(expiration7), TimeSpan.FromMilliseconds(expiration8),
+ TimeSpan.FromMilliseconds(expiration9), TimeSpan.FromMilliseconds(expiration10))
+ {
+ }
+
+ protected ConcurrentDictionary subData)> Data { get; set; }
+
+ public ExpirationalMultiDimensionDictionary() : base()
+ {
+ Data =
+ new ConcurrentDictionary subData)>();
+ }
+
+
+
+
+ #region ContainsKey
+
+ public bool ContainsKey(K1 k1)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6, k7);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6, k7, k8);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8, K9 k9)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6, k7, k8, k9);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8, K9 k9, K10 k10)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6, k7, k8, k9, k10);
+ }
+
+
+ #endregion
+
+ #region getKeys
+
+ public List<(K1, K2, K3, K4, K5, K6, K7, K8, K9, K10)> GetKeys()
+ {
+ Invalidate();
+ var keys = new List<(K1, K2, K3, K4, K5, K6, K7, K8, K9, K10)>();
+ foreach (var kvp in Data)
+ {
+ List<(K2, K3, K4, K5, K6, K7, K8, K9, K10)> subkeys = kvp.Value.subData.GetKeys();
+ foreach (var subkey in subkeys)
+ {
+ keys.Add((kvp.Key, subkey.Item1, subkey.Item2, subkey.Item3, subkey.Item4, subkey.Item5,
+ subkey.Item6, subkey.Item7, subkey.Item8, subkey.Item9));
+ }
+ }
+
+ return keys;
+ }
+
+ #endregion
+
+ #region Put
+
+ public void Put(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8, K9 k9, K10 k10, V value)
+ {
+ Invalidate();
+ DictionaryAssertions.AssertNotNull(k1, "k1");
+
+ DictionaryAssertions.AssertNotNull(k2, "k2");
+
+ DictionaryAssertions.AssertNotNull(k3, "k3");
+
+ DictionaryAssertions.AssertNotNull(k4, "k4");
+
+ DictionaryAssertions.AssertNotNull(k5, "k5");
+
+ DictionaryAssertions.AssertNotNull(k6, "k6");
+
+ DictionaryAssertions.AssertNotNull(k7, "k7");
+
+ DictionaryAssertions.AssertNotNull(k8, "k8");
+
+ DictionaryAssertions.AssertNotNull(k9, "k9");
+
+ DictionaryAssertions.AssertNotNull(k10, "k10");
+
+ DictionaryAssertions.AssertNotNull(value, "value");
+
+
+
+ var secondDimentionData = new ExpirationalMultiDimensionDictionary(
+ ExpirationSpan2, ExpirationSpan3, ExpirationSpan4, ExpirationSpan5, ExpirationSpan6, ExpirationSpan7,
+ ExpirationSpan8, ExpirationSpan9, ExpirationSpan10);
+
+ if (Data.ContainsKey(k1))
+ {
+ secondDimentionData = Data[k1].subData;
+ }
+
+ secondDimentionData.Put(k2, k3, k4, k5, k6, k7, k8, k9, k10, value);
+
+ Data[k1] = (DateTime.Now, secondDimentionData);
+ }
+
+ #endregion
+
+ #region Get
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1)
+ {
+ return Data[k1].subData;
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2)
+ {
+ return Data[k1].subData.Get(k2);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3)
+ {
+ return Data[k1].subData.Get(k2, k3);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ return Data[k1].subData.Get(k2, k3, k4);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ return Data[k1].subData.Get(k2, k3, k4, k5);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ return Data[k1].subData.Get(k2, k3, k4, k5, k6);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7)
+ {
+ return Data[k1].subData.Get(k2, k3, k4, k5, k6, k7);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7,
+ K8 k8)
+ {
+ return Data[k1].subData.Get(k2, k3, k4, k5, k6, k7, k8);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8,
+ K9 k9)
+ {
+ return Data[k1].subData.Get(k2, k3, k4, k5, k6, k7, k8, k9);
+ }
+
+ public V Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8, K9 k9, K10 k10)
+ {
+ Invalidate();
+ DictionaryAssertions.AssertNotNull(k1, "k1");
+
+ DictionaryAssertions.AssertNotNull(k2, "k2");
+
+ DictionaryAssertions.AssertNotNull(k3, "k3");
+
+ DictionaryAssertions.AssertNotNull(k4, "k4");
+
+ DictionaryAssertions.AssertNotNull(k5, "k5");
+
+ DictionaryAssertions.AssertNotNull(k6, "k6");
+
+ DictionaryAssertions.AssertNotNull(k7, "k7");
+
+ DictionaryAssertions.AssertNotNull(k8, "k8");
+
+ DictionaryAssertions.AssertNotNull(k9, "k9");
+
+ DictionaryAssertions.AssertNotNull(k10, "k10");
+
+
+
+
+ if (Data.TryGetValue(k1, out var secondDimensionData))
+ {
+ return secondDimensionData.subData.Get(k2, k3, k4, k5, k6, k7, k8, k9, k10);
+ }
+
+ throw new KeyNotFoundException();
+ }
+
+
+ #endregion
+
+ #region Remove
+
+ public new void Remove(K1 k1)
+ {
+ Invalidate();
+ Data.Remove(k1, out var ignore);
+ }
+
+ public void Remove(K1 k1, K2 k2)
+ {
+ Invalidate();
+ Data[k1].subData.Remove(k2);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Remove(k3);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Remove(k4);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Remove(k5);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Get(k5).Remove(k6);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Get(k5).Get(k6).Remove(k7);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Get(k5).Get(k6).Get(k7).Remove(k8);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8, K9 k9)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Get(k5).Get(k6).Get(k7).Get(k8).Remove(k9);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8, K9 k9, K10 k10)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Get(k5).Get(k6).Get(k7).Get(k8).Get(k9).Remove(k10);
+ }
+
+
+
+ #endregion
+
+
+ public void _Remove(K1 k1)
+ {
+ (DateTime date, ExpirationalMultiDimensionDictionary subData)
+ ignore = default;
+ Data.TryRemove(k1, out ignore);
+ }
+
+ public void Invalidate()
+ {
+ DateTime now = DateTime.Now;
+ List toRemove = new List();
+ foreach (var entry in Data)
+ {
+ var age = now - entry.Value.date;
+ if (age > ExpirationSpan1)
+ {
+ toRemove.Add(entry.Key);
+ }
+ }
+
+ if (toRemove.Any())
+ {
+ foreach (var k1 in toRemove)
+ {
+ _Remove(k1);
+ }
+ }
+ }
+ }
+
+}
diff --git a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary2.cs b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti2.cs
similarity index 70%
rename from MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary2.cs
rename to MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti2.cs
index 13cb17b..06b10a6 100644
--- a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary2.cs
+++ b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti2.cs
@@ -1,3 +1,5 @@
+
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -5,48 +7,43 @@
namespace multiDimensionalDictionary
{
+
+
public class ExpirationalMultiDimensionDictionary
{
- protected ConcurrentDictionary subData)> Data { get; set; }
-
TimeSpan ExpirationSpan1;
TimeSpan ExpirationSpan2;
-
- public ExpirationalMultiDimensionDictionary(long expiration1MMillis, long expiration2Millis) : this (TimeSpan.FromMilliseconds(expiration1MMillis), TimeSpan.FromMilliseconds(expiration2Millis))
+
+
+
+ public ExpirationalMultiDimensionDictionary(TimeSpan expiration1, TimeSpan expiration2)
{
-
+ ExpirationSpan1 = expiration1;
+ ExpirationSpan2 = expiration2;
+ Data = new ConcurrentDictionary subData)>();
}
-
- public ExpirationalMultiDimensionDictionary(TimeSpan expirationSpan1, TimeSpan expirationSpan2)
+
+ public ExpirationalMultiDimensionDictionary(long expiration1, long expiration2) : this(
+ TimeSpan.FromMilliseconds(expiration1), TimeSpan.FromMilliseconds(expiration2))
{
- ExpirationSpan1 = expirationSpan1;
- ExpirationSpan2 = expirationSpan2;
- Data = new ConcurrentDictionary subData)>();
}
- public void Invalidate()
+ protected ConcurrentDictionary subData)> Data
{
- DateTime now = DateTime.Now;
- List toRemove = new List();
- foreach (var entry in Data)
- {
- var age = now - entry.Value.date;
- if (age > ExpirationSpan1)
- {
- toRemove.Add(entry.Key);
- }
- }
+ get;
+ set;
+ }
- if (toRemove.Any())
- {
- foreach (var k1 in toRemove)
- {
- _Remove(k1);
- }
- }
+ public ExpirationalMultiDimensionDictionary() : base()
+ {
+ Data = new ConcurrentDictionary subData)>();
}
+
+
+ #region ContainsKey
+
public bool ContainsKey(K1 k1)
{
Invalidate();
@@ -58,11 +55,16 @@ public bool ContainsKey(K1 k1, K2 k2)
Invalidate();
return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2);
}
-
+
+
+ #endregion
+
+ #region getKeys
public List<(K1, K2)> GetKeys()
{
- List<(K1, K2)> keys = new List<(K1, K2)>();
+ Invalidate();
+ var keys = new List<(K1, K2)>();
foreach (var kvp in Data)
{
List subkeys = kvp.Value.subData.GetKeys();
@@ -71,44 +73,43 @@ public List<(K1, K2)> GetKeys()
keys.Add((kvp.Key, subkey));
}
}
+
return keys;
}
+ #endregion
+
+ #region Put
+
public void Put(K1 k1, K2 k2, V value)
{
-
Invalidate();
-
DictionaryAssertions.AssertNotNull(k1, "k1");
DictionaryAssertions.AssertNotNull(k2, "k2");
DictionaryAssertions.AssertNotNull(value, "value");
- ExpirationalMultiDimensionDictionary secondDimentionData = new ExpirationalMultiDimensionDictionary(ExpirationSpan2);
+ var secondDimentionData = new ExpirationalMultiDimensionDictionary(ExpirationSpan2);
if (Data.ContainsKey(k1))
{
secondDimentionData = Data[k1].subData;
}
- if (secondDimentionData.ContainsKey(k2))
- {
- throw new ArgumentException($"dictionary already contains key {k1};{k2}");
- }
- else
- {
- secondDimentionData.Put(k2, value);
- }
+ secondDimentionData.Put(k2, value);
Data[k1] = (DateTime.Now, secondDimentionData);
}
+ #endregion
+
+ #region Get
+
public ExpirationalMultiDimensionDictionary Get(K1 k1)
{
- Invalidate();
return Data[k1].subData;
}
@@ -118,41 +119,67 @@ public V Get(K1 k1, K2 k2)
DictionaryAssertions.AssertNotNull(k1, "k1");
DictionaryAssertions.AssertNotNull(k2, "k2");
-
- if (Data.TryGetValue(k1, out (DateTime date, ExpirationalMultiDimensionDictionary subData) secondDimensionData ))
- {
- if (secondDimensionData.subData.ContainsKey(k2))
- {
- var value = secondDimensionData.subData.Get(k2);
- return value;
- }
+
+
+
+ if (Data.TryGetValue(k1, out var secondDimensionData))
+ {
+ return secondDimensionData.subData.Get(k2);
}
throw new KeyNotFoundException();
}
- public void Remove(K1 k1)
+
+ #endregion
+
+ #region Remove
+
+ public new void Remove(K1 k1)
{
Invalidate();
- _Remove(k1);
+ Data.Remove(k1, out var ignore);
}
+ public void Remove(K1 k1, K2 k2)
+ {
+ Invalidate();
+ Data[k1].subData.Remove(k2);
+ }
+
+
+
+ #endregion
+
+
public void _Remove(K1 k1)
{
(DateTime date, ExpirationalMultiDimensionDictionary subData) ignore = default;
Data.TryRemove(k1, out ignore);
}
- public void Remove(K1 k1, K2 k2)
+ public void Invalidate()
{
- Invalidate();
- Data[k1].subData.Remove(k2);
- }
+ DateTime now = DateTime.Now;
+ List toRemove = new List();
+ foreach (var entry in Data)
+ {
+ var age = now - entry.Value.date;
+ if (age > ExpirationSpan1)
+ {
+ toRemove.Add(entry.Key);
+ }
+ }
- public void Clear()
- {
- Data.Clear();
+ if (toRemove.Any())
+ {
+ foreach (var k1 in toRemove)
+ {
+ _Remove(k1);
+ }
+ }
}
}
-}
\ No newline at end of file
+
+}
diff --git a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary3.cs b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti3.cs
similarity index 61%
rename from MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary3.cs
rename to MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti3.cs
index a6b02a3..5d0528a 100644
--- a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary3.cs
+++ b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti3.cs
@@ -1,3 +1,5 @@
+
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -5,163 +7,206 @@
namespace multiDimensionalDictionary
{
+
+
public class ExpirationalMultiDimensionDictionary
{
-
TimeSpan ExpirationSpan1;
TimeSpan ExpirationSpan2;
TimeSpan ExpirationSpan3;
-
- protected ConcurrentDictionary data)> Data { get; set; }
-
- public ExpirationalMultiDimensionDictionary(TimeSpan expirationSpan1, TimeSpan expirationSpan2, TimeSpan expirationSpan3) : base()
+
+
+
+ public ExpirationalMultiDimensionDictionary(TimeSpan expiration1, TimeSpan expiration2, TimeSpan expiration3)
{
- ExpirationSpan1 = expirationSpan1;
- ExpirationSpan2 = expirationSpan2;
- ExpirationSpan3 = expirationSpan3;
- Data = new ConcurrentDictionary data)>();
+ ExpirationSpan1 = expiration1;
+ ExpirationSpan2 = expiration2;
+ ExpirationSpan3 = expiration3;
+ Data =
+ new ConcurrentDictionary subData
+ )>();
}
- public ExpirationalMultiDimensionDictionary(long expiration1MMillis, long expiration2Millis,
- long expiration3Millis) : this (TimeSpan.FromMilliseconds(expiration1MMillis), TimeSpan.FromMilliseconds(expiration2Millis), TimeSpan.FromMilliseconds(expiration3Millis))
+ public ExpirationalMultiDimensionDictionary(long expiration1, long expiration2, long expiration3) : this(
+ TimeSpan.FromMilliseconds(expiration1), TimeSpan.FromMilliseconds(expiration2),
+ TimeSpan.FromMilliseconds(expiration3))
{
-
}
-
- public void Invalidate()
- {
- DateTime now = DateTime.Now;
- List toRemove = new List();
- foreach (var entry in Data)
- {
- var age = now - entry.Value.date;
- if (age > ExpirationSpan1)
- {
- toRemove.Add(entry.Key);
- }
- }
- if (toRemove.Any())
- {
- foreach (var k1 in toRemove)
- {
- _Remove(k1);
- }
- }
- }
-
- public void _Remove(K1 k1)
+ protected ConcurrentDictionary subData)>
+ Data { get; set; }
+
+ public ExpirationalMultiDimensionDictionary() : base()
{
- (DateTime date, ExpirationalMultiDimensionDictionary data) ignore;
- Data.TryRemove(k1, out ignore);
+ Data =
+ new ConcurrentDictionary subData
+ )>();
}
+
+
+
+ #region ContainsKey
+
public bool ContainsKey(K1 k1)
{
Invalidate();
return Data.ContainsKey(k1);
}
-
+
public bool ContainsKey(K1 k1, K2 k2)
{
Invalidate();
- return Data.ContainsKey(k1) && Data[k1].data.ContainsKey(k2);
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2);
}
public bool ContainsKey(K1 k1, K2 k2, K3 k3)
{
Invalidate();
- return Data.ContainsKey(k1) && Data[k1].data.ContainsKey(k2, k3);
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3);
}
+
+ #endregion
+
+ #region getKeys
+
public List<(K1, K2, K3)> GetKeys()
{
Invalidate();
- List<(K1, K2, K3)> keys = new List<(K1, K2, K3)>();
+ var keys = new List<(K1, K2, K3)>();
foreach (var kvp in Data)
{
- List<(K2, K3)> subkeys = kvp.Value.data.GetKeys();
+ List<(K2, K3)> subkeys = kvp.Value.subData.GetKeys();
foreach (var subkey in subkeys)
{
keys.Add((kvp.Key, subkey.Item1, subkey.Item2));
}
}
+
return keys;
}
-
+
+ #endregion
+
+ #region Put
+
public void Put(K1 k1, K2 k2, K3 k3, V value)
{
Invalidate();
-
DictionaryAssertions.AssertNotNull(k1, "k1");
-
+
DictionaryAssertions.AssertNotNull(k2, "k2");
-
+
DictionaryAssertions.AssertNotNull(k3, "k3");
-
+
DictionaryAssertions.AssertNotNull(value, "value");
-
- var secondDimentionData = new ExpirationalMultiDimensionDictionary(ExpirationSpan2,ExpirationSpan3);
-
-
-
+
+
+
+ var secondDimentionData =
+ new ExpirationalMultiDimensionDictionary(ExpirationSpan2, ExpirationSpan3);
+
if (Data.ContainsKey(k1))
{
- secondDimentionData = Data[k1].data;
+ secondDimentionData = Data[k1].subData;
}
-
+
secondDimentionData.Put(k2, k3, value);
-
+
Data[k1] = (DateTime.Now, secondDimentionData);
}
-
+
+ #endregion
+
+ #region Get
+
public ExpirationalMultiDimensionDictionary Get(K1 k1)
{
- Invalidate();
- return Data[k1].data;
+ return Data[k1].subData;
}
-
+
public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2)
{
- Invalidate();
- return Data[k1].data.Get(k2);
+ return Data[k1].subData.Get(k2);
}
-
+
public V Get(K1 k1, K2 k2, K3 k3)
{
Invalidate();
DictionaryAssertions.AssertNotNull(k1, "k1");
+
DictionaryAssertions.AssertNotNull(k2, "k2");
+
DictionaryAssertions.AssertNotNull(k3, "k3");
- if (Data.TryGetValue(k1, out (DateTime date, ExpirationalMultiDimensionDictionary data) secondDimensionData))
+
+
+
+ if (Data.TryGetValue(k1, out var secondDimensionData))
{
- return secondDimensionData.data.Get(k2, k3);
+ return secondDimensionData.subData.Get(k2, k3);
}
+
throw new KeyNotFoundException();
}
- public void Remove(K1 k1)
+
+ #endregion
+
+ #region Remove
+
+ public new void Remove(K1 k1)
{
Invalidate();
- _Remove(k1);
+ Data.Remove(k1, out var ignore);
}
-
+
public void Remove(K1 k1, K2 k2)
{
Invalidate();
- Data[k1].data.Remove(k2);
+ Data[k1].subData.Remove(k2);
}
-
+
+
public void Remove(K1 k1, K2 k2, K3 k3)
{
- Data[k1].data.Get(k2).Remove(k3);
+ Invalidate();
+ Data[k1].subData.Get(k2).Remove(k3);
+ }
+
+
+
+ #endregion
+
+
+ public void _Remove(K1 k1)
+ {
+ (DateTime date, ExpirationalMultiDimensionDictionary subData) ignore = default;
+ Data.TryRemove(k1, out ignore);
}
-
- public void Clear()
+
+ public void Invalidate()
{
- Data.Clear();
+ DateTime now = DateTime.Now;
+ List toRemove = new List();
+ foreach (var entry in Data)
+ {
+ var age = now - entry.Value.date;
+ if (age > ExpirationSpan1)
+ {
+ toRemove.Add(entry.Key);
+ }
+ }
+
+ if (toRemove.Any())
+ {
+ foreach (var k1 in toRemove)
+ {
+ _Remove(k1);
+ }
+ }
}
}
-}
\ No newline at end of file
+}
diff --git a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary4.cs b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti4.cs
similarity index 58%
rename from MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary4.cs
rename to MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti4.cs
index c9e0fb2..d08c220 100644
--- a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary4.cs
+++ b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti4.cs
@@ -1,3 +1,5 @@
+
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -5,193 +7,232 @@
namespace multiDimensionalDictionary
{
- public class ExpirationalMultiDimensionDictionary
+
+
+ public class ExpirationalMultiDimensionDictionary
{
- protected ConcurrentDictionary data)> Data { get; set; }
-
TimeSpan ExpirationSpan1;
TimeSpan ExpirationSpan2;
TimeSpan ExpirationSpan3;
TimeSpan ExpirationSpan4;
-
- public ExpirationalMultiDimensionDictionary(long expiration1MMillis, long expiration2Millis,
- long expiration3Millis, long expieration4Millis) : this (TimeSpan.FromMilliseconds(expiration1MMillis), TimeSpan.FromMilliseconds(expiration2Millis), TimeSpan.FromMilliseconds(expiration3Millis), TimeSpan.FromMilliseconds(expieration4Millis))
+
+
+
+ public ExpirationalMultiDimensionDictionary(TimeSpan expiration1, TimeSpan expiration2, TimeSpan expiration3,
+ TimeSpan expiration4)
{
-
+ ExpirationSpan1 = expiration1;
+ ExpirationSpan2 = expiration2;
+ ExpirationSpan3 = expiration3;
+ ExpirationSpan4 = expiration4;
+ Data =
+ new ConcurrentDictionary subData
+ )>();
}
-
- public ExpirationalMultiDimensionDictionary(TimeSpan expirationSpan1, TimeSpan expirationSpan2, TimeSpan expirationSpan3, TimeSpan expirationSpan4)
+
+ public ExpirationalMultiDimensionDictionary(long expiration1, long expiration2, long expiration3,
+ long expiration4) : this(TimeSpan.FromMilliseconds(expiration1), TimeSpan.FromMilliseconds(expiration2),
+ TimeSpan.FromMilliseconds(expiration3), TimeSpan.FromMilliseconds(expiration4))
{
- Data = new ConcurrentDictionary data)>();
- ExpirationSpan1 = expirationSpan1;
- ExpirationSpan2 = expirationSpan2;
- ExpirationSpan3 = expirationSpan3;
- ExpirationSpan4 = expirationSpan4;
}
-
-
- public void Invalidate()
- {
-
- DateTime now = DateTime.Now;
- List toRemove = new List();
- foreach (var entry in Data)
- {
- var age = now - entry.Value.date;
- if (age > ExpirationSpan1)
- {
- toRemove.Add(entry.Key);
- }
- }
- if (toRemove.Any())
- {
- foreach (var k1 in toRemove)
- {
- _Remove(k1);
- }
- }
+ protected ConcurrentDictionary subData)>
+ Data { get; set; }
+
+ public ExpirationalMultiDimensionDictionary() : base()
+ {
+ Data =
+ new ConcurrentDictionary subData
+ )>();
}
+
+
+
+ #region ContainsKey
+
public bool ContainsKey(K1 k1)
{
Invalidate();
- return Data.ContainsKey(k1);
- }
-
- public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4)
+ return Data.ContainsKey(k1);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2)
{
Invalidate();
- bool containsK1 = Data.ContainsKey(k1);
- bool containsChildren = Data[k1].data.ContainsKey(k2, k3, k4);
- return containsK1 && containsChildren;
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2);
}
public bool ContainsKey(K1 k1, K2 k2, K3 k3)
{
Invalidate();
- var containsKey = Data.ContainsKey(k1);
- var containsChildren = Data[k1].data.ContainsKey(k2, k3);
- return containsKey && containsChildren;
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3);
}
- public bool ContainsKey(K1 k1, K2 k2)
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4)
{
Invalidate();
- return Data.ContainsKey(k1) && Data[k1].data.ContainsKey(k2);
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4);
}
-
-
+
+
+ #endregion
+
+ #region getKeys
+
public List<(K1, K2, K3, K4)> GetKeys()
{
Invalidate();
- List<(K1, K2, K3, K4)> keys = new List<(K1, K2, K3, K4)>();
+ var keys = new List<(K1, K2, K3, K4)>();
foreach (var kvp in Data)
{
- List<(K2, K3, K4)> subkeys = kvp.Value.data.GetKeys();
+ List<(K2, K3, K4)> subkeys = kvp.Value.subData.GetKeys();
foreach (var subkey in subkeys)
{
keys.Add((kvp.Key, subkey.Item1, subkey.Item2, subkey.Item3));
}
}
+
return keys;
}
-
+
+ #endregion
+
+ #region Put
+
public void Put(K1 k1, K2 k2, K3 k3, K4 k4, V value)
{
Invalidate();
DictionaryAssertions.AssertNotNull(k1, "k1");
-
+
DictionaryAssertions.AssertNotNull(k2, "k2");
-
+
DictionaryAssertions.AssertNotNull(k3, "k3");
-
+
DictionaryAssertions.AssertNotNull(k4, "k4");
-
+
DictionaryAssertions.AssertNotNull(value, "value");
-
- var secondDimentionData = new ExpirationalMultiDimensionDictionary(ExpirationSpan2,ExpirationSpan3,ExpirationSpan4);
-
+
+
+
+ var secondDimentionData =
+ new ExpirationalMultiDimensionDictionary(ExpirationSpan2, ExpirationSpan3,
+ ExpirationSpan4);
+
if (Data.ContainsKey(k1))
{
- secondDimentionData = Data[k1].data;
+ secondDimentionData = Data[k1].subData;
}
-
- secondDimentionData.Put(k2, k3, k4, value); ;
-
+
+ secondDimentionData.Put(k2, k3, k4, value);
+
Data[k1] = (DateTime.Now, secondDimentionData);
}
-
-
+
+ #endregion
+
+ #region Get
+
public ExpirationalMultiDimensionDictionary Get(K1 k1)
{
- Invalidate();
- return Data[k1].data;
+ return Data[k1].subData;
}
-
+
public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2)
{
- Invalidate();
- return Data[k1].data.Get(k2);
+ return Data[k1].subData.Get(k2);
}
-
+
public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3)
{
- Invalidate();
- return Data[k1].data.Get(k2).Get(k3);
+ return Data[k1].subData.Get(k2, k3);
}
-
+
public V Get(K1 k1, K2 k2, K3 k3, K4 k4)
{
Invalidate();
DictionaryAssertions.AssertNotNull(k1, "k1");
+
DictionaryAssertions.AssertNotNull(k2, "k2");
+
DictionaryAssertions.AssertNotNull(k3, "k3");
+
DictionaryAssertions.AssertNotNull(k4, "k4");
-
- (DateTime date, ExpirationalMultiDimensionDictionary data) secondDimensionData;
- if (Data.TryGetValue(k1, out secondDimensionData))
+
+
+
+
+ if (Data.TryGetValue(k1, out var secondDimensionData))
{
- return secondDimensionData.data.Get(k2, k3, k4);
+ return secondDimensionData.subData.Get(k2, k3, k4);
}
-
+
throw new KeyNotFoundException();
}
-
- public void Remove(K1 k1)
+
+
+ #endregion
+
+ #region Remove
+
+ public new void Remove(K1 k1)
{
Invalidate();
- _Remove(k1);
- }
-
- public void _Remove(K1 k1)
- {
- (DateTime date, ExpirationalMultiDimensionDictionary subData) ignore = default;
- Data.TryRemove(k1, out ignore);
+ Data.Remove(k1, out var ignore);
}
-
+
public void Remove(K1 k1, K2 k2)
{
Invalidate();
- Data[k1].data.Remove(k2);
+ Data[k1].subData.Remove(k2);
}
-
+
+
public void Remove(K1 k1, K2 k2, K3 k3)
{
Invalidate();
- Data[k1].data.Get(k2).Remove(k3);
+ Data[k1].subData.Get(k2).Remove(k3);
}
-
+
+
public void Remove(K1 k1, K2 k2, K3 k3, K4 k4)
{
Invalidate();
- Data[k1].data.Get(k2).Get(k3).Remove(k4);
+ Data[k1].subData.Get(k2).Get(k3).Remove(k4);
}
-
- public void Clear()
+
+
+
+ #endregion
+
+
+ public void _Remove(K1 k1)
{
- Data.Clear();
+ (DateTime date, ExpirationalMultiDimensionDictionary subData) ignore = default;
+ Data.TryRemove(k1, out ignore);
+ }
+
+ public void Invalidate()
+ {
+ DateTime now = DateTime.Now;
+ List toRemove = new List();
+ foreach (var entry in Data)
+ {
+ var age = now - entry.Value.date;
+ if (age > ExpirationSpan1)
+ {
+ toRemove.Add(entry.Key);
+ }
+ }
+
+ if (toRemove.Any())
+ {
+ foreach (var k1 in toRemove)
+ {
+ _Remove(k1);
+ }
+ }
}
}
-}
\ No newline at end of file
+}
diff --git a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary5.cs b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti5.cs
similarity index 54%
rename from MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary5.cs
rename to MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti5.cs
index 03ccd42..3b3adba 100644
--- a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/ExpirationalMultiDimensionDictionary5.cs
+++ b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti5.cs
@@ -1,3 +1,5 @@
+
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -5,181 +7,256 @@
namespace multiDimensionalDictionary
{
- public class ExpirationalMultiDimensionDictionary
+
+
+ public class ExpirationalMultiDimensionDictionary
{
- protected ConcurrentDictionary data)> Data { get; set; }
TimeSpan ExpirationSpan1;
TimeSpan ExpirationSpan2;
TimeSpan ExpirationSpan3;
TimeSpan ExpirationSpan4;
TimeSpan ExpirationSpan5;
-
- public ExpirationalMultiDimensionDictionary(long expiration1MMillis, long expiration2Millis,
- long expiration3Millis, long expieration4Millis, long expiration5Millis) : this (TimeSpan.FromMilliseconds(expiration1MMillis), TimeSpan.FromMilliseconds(expiration2Millis), TimeSpan.FromMilliseconds(expiration3Millis), TimeSpan.FromMilliseconds(expieration4Millis), TimeSpan.FromMilliseconds(expiration5Millis))
+
+
+
+ public ExpirationalMultiDimensionDictionary(TimeSpan expiration1, TimeSpan expiration2, TimeSpan expiration3,
+ TimeSpan expiration4, TimeSpan expiration5)
{
-
+ ExpirationSpan1 = expiration1;
+ ExpirationSpan2 = expiration2;
+ ExpirationSpan3 = expiration3;
+ ExpirationSpan4 = expiration4;
+ ExpirationSpan5 = expiration5;
+ Data =
+ new ConcurrentDictionary
+ subData)>();
}
-
- public ExpirationalMultiDimensionDictionary(TimeSpan expirationSpan1, TimeSpan expirationSpan2, TimeSpan expirationSpan3, TimeSpan expirationSpan4, TimeSpan expirationSpan5)
+
+ public ExpirationalMultiDimensionDictionary(long expiration1, long expiration2, long expiration3,
+ long expiration4, long expiration5) : this(TimeSpan.FromMilliseconds(expiration1),
+ TimeSpan.FromMilliseconds(expiration2), TimeSpan.FromMilliseconds(expiration3),
+ TimeSpan.FromMilliseconds(expiration4), TimeSpan.FromMilliseconds(expiration5))
{
- Data = new ConcurrentDictionary data)>();
- ExpirationSpan1 = expirationSpan1;
- ExpirationSpan2 = expirationSpan2;
- ExpirationSpan3 = expirationSpan3;
- ExpirationSpan4 = expirationSpan4;
- ExpirationSpan5 = expirationSpan5;
}
-
-
- public void Invalidate()
- {
-
- DateTime now = DateTime.Now;
- List toRemove = new List();
- foreach (var entry in Data)
- {
- var age = now - entry.Value.date;
- if (age > ExpirationSpan1)
- {
- toRemove.Add(entry.Key);
- }
- }
- if (toRemove.Any())
- {
- foreach (var k1 in toRemove)
- {
- _Remove(k1);
- }
- }
+ protected ConcurrentDictionary
+ subData)> Data { get; set; }
+
+ public ExpirationalMultiDimensionDictionary() : base()
+ {
+ Data =
+ new ConcurrentDictionary
+ subData)>();
}
+
+
+
+ #region ContainsKey
+
public bool ContainsKey(K1 k1)
{
Invalidate();
- return Data.ContainsKey(k1);
+ return Data.ContainsKey(k1);
}
- public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5) {
+
+ public bool ContainsKey(K1 k1, K2 k2)
+ {
Invalidate();
- bool containsK1 = Data.ContainsKey(k1);
- bool containsChildren = Data[k1].data.ContainsKey(k2, k3, k4, k5);
- return containsK1 && containsChildren;
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2);
}
- public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4)
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3)
{
Invalidate();
- bool containsK1 = Data.ContainsKey(k1);
- bool containsChildren = Data[k1].data.ContainsKey(k2, k3, k4);
- return containsK1 && containsChildren;
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3);
}
- public bool ContainsKey(K1 k1, K2 k2, K3 k3)
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4)
{
Invalidate();
- var containsKey = Data.ContainsKey(k1);
- var containsChildren = Data[k1].data.ContainsKey(k2, k3);
- return containsKey && containsChildren;
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4);
}
- public bool ContainsKey(K1 k1, K2 k2)
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
{
Invalidate();
- return Data.ContainsKey(k1) && Data[k1].data.ContainsKey(k2);
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5);
}
-
-
+
+
+ #endregion
+
+ #region getKeys
+
public List<(K1, K2, K3, K4, K5)> GetKeys()
{
Invalidate();
- List<(K1, K2, K3, K4, K5)> keys = new List<(K1, K2, K3, K4, K5)>();
+ var keys = new List<(K1, K2, K3, K4, K5)>();
foreach (var kvp in Data)
{
- List<(K2, K3, K4, K5)> subkeys = kvp.Value.data.GetKeys();
+ List<(K2, K3, K4, K5)> subkeys = kvp.Value.subData.GetKeys();
foreach (var subkey in subkeys)
{
keys.Add((kvp.Key, subkey.Item1, subkey.Item2, subkey.Item3, subkey.Item4));
}
}
+
return keys;
}
-
+
+ #endregion
+
+ #region Put
+
public void Put(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, V value)
{
Invalidate();
DictionaryAssertions.AssertNotNull(k1, "k1");
+
DictionaryAssertions.AssertNotNull(k2, "k2");
+
DictionaryAssertions.AssertNotNull(k3, "k3");
+
DictionaryAssertions.AssertNotNull(k4, "k4");
+
DictionaryAssertions.AssertNotNull(k5, "k5");
+
DictionaryAssertions.AssertNotNull(value, "value");
- var secondDimentionData = new ExpirationalMultiDimensionDictionary(ExpirationSpan2,ExpirationSpan3,ExpirationSpan4, ExpirationSpan5);
+
+
+ var secondDimentionData = new ExpirationalMultiDimensionDictionary(ExpirationSpan2,
+ ExpirationSpan3, ExpirationSpan4, ExpirationSpan5);
if (Data.ContainsKey(k1))
{
- secondDimentionData = Data[k1].data;
+ secondDimentionData = Data[k1].subData;
}
- secondDimentionData.Put(k2, k3, k4, k5, value); ;
+
+ secondDimentionData.Put(k2, k3, k4, k5, value);
+
Data[k1] = (DateTime.Now, secondDimentionData);
}
+
+ #endregion
+
+ #region Get
+
public ExpirationalMultiDimensionDictionary Get(K1 k1)
{
- Invalidate();
- return Data[k1].data;
+ return Data[k1].subData;
}
public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2)
{
- Invalidate();
- return Data[k1].data.Get(k2);
+ return Data[k1].subData.Get(k2);
}
public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3)
{
- Invalidate();
- DictionaryAssertions.AssertNotNull(k1, "k1");
- DictionaryAssertions.AssertNotNull(k2, "k2");
- DictionaryAssertions.AssertNotNull(k3, "k3");
- return Data[k1].data.Get(k2).Get(k3);
+ return Data[k1].subData.Get(k2, k3);
}
-
+
public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4)
{
- Invalidate();
- return Data[k1].data.Get(k2).Get(k3).Get(k4);
+ return Data[k1].subData.Get(k2, k3, k4);
}
- public void Remove(K1 k1)
+
+ public V Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
{
Invalidate();
- _Remove(k1);
+ DictionaryAssertions.AssertNotNull(k1, "k1");
+
+ DictionaryAssertions.AssertNotNull(k2, "k2");
+
+ DictionaryAssertions.AssertNotNull(k3, "k3");
+
+ DictionaryAssertions.AssertNotNull(k4, "k4");
+
+ DictionaryAssertions.AssertNotNull(k5, "k5");
+
+
+
+
+ if (Data.TryGetValue(k1, out var secondDimensionData))
+ {
+ return secondDimensionData.subData.Get(k2, k3, k4, k5);
+ }
+
+ throw new KeyNotFoundException();
}
-
- public void _Remove(K1 k1)
+
+
+ #endregion
+
+ #region Remove
+
+ public new void Remove(K1 k1)
{
- (DateTime date, ExpirationalMultiDimensionDictionary subData) ignore = default;
- Data.TryRemove(k1, out ignore);
+ Invalidate();
+ Data.Remove(k1, out var ignore);
}
-
+
public void Remove(K1 k1, K2 k2)
{
Invalidate();
- Data[k1].data.Remove(k2);
+ Data[k1].subData.Remove(k2);
}
-
+
+
public void Remove(K1 k1, K2 k2, K3 k3)
{
Invalidate();
- Data[k1].data.Get(k2).Remove(k3);
+ Data[k1].subData.Get(k2).Remove(k3);
}
+
+
public void Remove(K1 k1, K2 k2, K3 k3, K4 k4)
{
Invalidate();
- Data[k1].data.Get(k2).Get(k3).Remove(k4);
+ Data[k1].subData.Get(k2).Get(k3).Remove(k4);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Remove(k5);
}
- public void Clear()
+
+
+
+ #endregion
+
+
+ public void _Remove(K1 k1)
{
- Data.Clear();
+ (DateTime date, ExpirationalMultiDimensionDictionary subData) ignore = default;
+ Data.TryRemove(k1, out ignore);
+ }
+
+ public void Invalidate()
+ {
+ DateTime now = DateTime.Now;
+ List toRemove = new List();
+ foreach (var entry in Data)
+ {
+ var age = now - entry.Value.date;
+ if (age > ExpirationSpan1)
+ {
+ toRemove.Add(entry.Key);
+ }
+ }
+
+ if (toRemove.Any())
+ {
+ foreach (var k1 in toRemove)
+ {
+ _Remove(k1);
+ }
+ }
}
}
-}
\ No newline at end of file
+
+}
diff --git a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti6.cs b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti6.cs
new file mode 100644
index 0000000..249935f
--- /dev/null
+++ b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti6.cs
@@ -0,0 +1,287 @@
+
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace multiDimensionalDictionary
+{
+
+
+ public class ExpirationalMultiDimensionDictionary
+ {
+ TimeSpan ExpirationSpan1;
+ TimeSpan ExpirationSpan2;
+ TimeSpan ExpirationSpan3;
+ TimeSpan ExpirationSpan4;
+ TimeSpan ExpirationSpan5;
+ TimeSpan ExpirationSpan6;
+
+
+
+ public ExpirationalMultiDimensionDictionary(TimeSpan expiration1, TimeSpan expiration2, TimeSpan expiration3,
+ TimeSpan expiration4, TimeSpan expiration5, TimeSpan expiration6)
+ {
+ ExpirationSpan1 = expiration1;
+ ExpirationSpan2 = expiration2;
+ ExpirationSpan3 = expiration3;
+ ExpirationSpan4 = expiration4;
+ ExpirationSpan5 = expiration5;
+ ExpirationSpan6 = expiration6;
+ Data =
+ new ConcurrentDictionary
+ subData)>();
+ }
+
+ public ExpirationalMultiDimensionDictionary(long expiration1, long expiration2, long expiration3,
+ long expiration4, long expiration5, long expiration6) : this(TimeSpan.FromMilliseconds(expiration1),
+ TimeSpan.FromMilliseconds(expiration2), TimeSpan.FromMilliseconds(expiration3),
+ TimeSpan.FromMilliseconds(expiration4), TimeSpan.FromMilliseconds(expiration5),
+ TimeSpan.FromMilliseconds(expiration6))
+ {
+ }
+
+ protected ConcurrentDictionary
+ subData)> Data { get; set; }
+
+ public ExpirationalMultiDimensionDictionary() : base()
+ {
+ Data =
+ new ConcurrentDictionary
+ subData)>();
+ }
+
+
+
+
+ #region ContainsKey
+
+ public bool ContainsKey(K1 k1)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6);
+ }
+
+
+ #endregion
+
+ #region getKeys
+
+ public List<(K1, K2, K3, K4, K5, K6)> GetKeys()
+ {
+ Invalidate();
+ var keys = new List<(K1, K2, K3, K4, K5, K6)>();
+ foreach (var kvp in Data)
+ {
+ List<(K2, K3, K4, K5, K6)> subkeys = kvp.Value.subData.GetKeys();
+ foreach (var subkey in subkeys)
+ {
+ keys.Add((kvp.Key, subkey.Item1, subkey.Item2, subkey.Item3, subkey.Item4, subkey.Item5));
+ }
+ }
+
+ return keys;
+ }
+
+ #endregion
+
+ #region Put
+
+ public void Put(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, V value)
+ {
+ Invalidate();
+ DictionaryAssertions.AssertNotNull(k1, "k1");
+
+ DictionaryAssertions.AssertNotNull(k2, "k2");
+
+ DictionaryAssertions.AssertNotNull(k3, "k3");
+
+ DictionaryAssertions.AssertNotNull(k4, "k4");
+
+ DictionaryAssertions.AssertNotNull(k5, "k5");
+
+ DictionaryAssertions.AssertNotNull(k6, "k6");
+
+ DictionaryAssertions.AssertNotNull(value, "value");
+
+
+
+ var secondDimentionData = new ExpirationalMultiDimensionDictionary(ExpirationSpan2,
+ ExpirationSpan3, ExpirationSpan4, ExpirationSpan5, ExpirationSpan6);
+
+ if (Data.ContainsKey(k1))
+ {
+ secondDimentionData = Data[k1].subData;
+ }
+
+ secondDimentionData.Put(k2, k3, k4, k5, k6, value);
+
+ Data[k1] = (DateTime.Now, secondDimentionData);
+ }
+
+ #endregion
+
+ #region Get
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1)
+ {
+ return Data[k1].subData;
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2)
+ {
+ return Data[k1].subData.Get(k2);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3)
+ {
+ return Data[k1].subData.Get(k2, k3);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ return Data[k1].subData.Get(k2, k3, k4);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ return Data[k1].subData.Get(k2, k3, k4, k5);
+ }
+
+ public V Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ Invalidate();
+ DictionaryAssertions.AssertNotNull(k1, "k1");
+
+ DictionaryAssertions.AssertNotNull(k2, "k2");
+
+ DictionaryAssertions.AssertNotNull(k3, "k3");
+
+ DictionaryAssertions.AssertNotNull(k4, "k4");
+
+ DictionaryAssertions.AssertNotNull(k5, "k5");
+
+ DictionaryAssertions.AssertNotNull(k6, "k6");
+
+
+
+
+ if (Data.TryGetValue(k1, out var secondDimensionData))
+ {
+ return secondDimensionData.subData.Get(k2, k3, k4, k5, k6);
+ }
+
+ throw new KeyNotFoundException();
+ }
+
+
+ #endregion
+
+ #region Remove
+
+ public new void Remove(K1 k1)
+ {
+ Invalidate();
+ Data.Remove(k1, out var ignore);
+ }
+
+ public void Remove(K1 k1, K2 k2)
+ {
+ Invalidate();
+ Data[k1].subData.Remove(k2);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Remove(k3);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Remove(k4);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Remove(k5);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Get(k5).Remove(k6);
+ }
+
+
+
+ #endregion
+
+
+ public void _Remove(K1 k1)
+ {
+ (DateTime date, ExpirationalMultiDimensionDictionary subData) ignore = default;
+ Data.TryRemove(k1, out ignore);
+ }
+
+ public void Invalidate()
+ {
+ DateTime now = DateTime.Now;
+ List toRemove = new List();
+ foreach (var entry in Data)
+ {
+ var age = now - entry.Value.date;
+ if (age > ExpirationSpan1)
+ {
+ toRemove.Add(entry.Key);
+ }
+ }
+
+ if (toRemove.Any())
+ {
+ foreach (var k1 in toRemove)
+ {
+ _Remove(k1);
+ }
+ }
+ }
+ }
+
+}
diff --git a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti7.cs b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti7.cs
new file mode 100644
index 0000000..978b298
--- /dev/null
+++ b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti7.cs
@@ -0,0 +1,313 @@
+
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace multiDimensionalDictionary
+{
+
+
+ public class ExpirationalMultiDimensionDictionary
+ {
+ TimeSpan ExpirationSpan1;
+ TimeSpan ExpirationSpan2;
+ TimeSpan ExpirationSpan3;
+ TimeSpan ExpirationSpan4;
+ TimeSpan ExpirationSpan5;
+ TimeSpan ExpirationSpan6;
+ TimeSpan ExpirationSpan7;
+
+
+
+ public ExpirationalMultiDimensionDictionary(TimeSpan expiration1, TimeSpan expiration2, TimeSpan expiration3,
+ TimeSpan expiration4, TimeSpan expiration5, TimeSpan expiration6, TimeSpan expiration7)
+ {
+ ExpirationSpan1 = expiration1;
+ ExpirationSpan2 = expiration2;
+ ExpirationSpan3 = expiration3;
+ ExpirationSpan4 = expiration4;
+ ExpirationSpan5 = expiration5;
+ ExpirationSpan6 = expiration6;
+ ExpirationSpan7 = expiration7;
+ Data =
+ new ConcurrentDictionary subData)>();
+ }
+
+ public ExpirationalMultiDimensionDictionary(long expiration1, long expiration2, long expiration3,
+ long expiration4, long expiration5, long expiration6, long expiration7) : this(
+ TimeSpan.FromMilliseconds(expiration1), TimeSpan.FromMilliseconds(expiration2),
+ TimeSpan.FromMilliseconds(expiration3), TimeSpan.FromMilliseconds(expiration4),
+ TimeSpan.FromMilliseconds(expiration5), TimeSpan.FromMilliseconds(expiration6),
+ TimeSpan.FromMilliseconds(expiration7))
+ {
+ }
+
+ protected ConcurrentDictionary subData)> Data { get; set; }
+
+ public ExpirationalMultiDimensionDictionary() : base()
+ {
+ Data =
+ new ConcurrentDictionary subData)>();
+ }
+
+
+
+
+ #region ContainsKey
+
+ public bool ContainsKey(K1 k1)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6, k7);
+ }
+
+
+ #endregion
+
+ #region getKeys
+
+ public List<(K1, K2, K3, K4, K5, K6, K7)> GetKeys()
+ {
+ Invalidate();
+ var keys = new List<(K1, K2, K3, K4, K5, K6, K7)>();
+ foreach (var kvp in Data)
+ {
+ List<(K2, K3, K4, K5, K6, K7)> subkeys = kvp.Value.subData.GetKeys();
+ foreach (var subkey in subkeys)
+ {
+ keys.Add((kvp.Key, subkey.Item1, subkey.Item2, subkey.Item3, subkey.Item4, subkey.Item5,
+ subkey.Item6));
+ }
+ }
+
+ return keys;
+ }
+
+ #endregion
+
+ #region Put
+
+ public void Put(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, V value)
+ {
+ Invalidate();
+ DictionaryAssertions.AssertNotNull(k1, "k1");
+
+ DictionaryAssertions.AssertNotNull(k2, "k2");
+
+ DictionaryAssertions.AssertNotNull(k3, "k3");
+
+ DictionaryAssertions.AssertNotNull(k4, "k4");
+
+ DictionaryAssertions.AssertNotNull(k5, "k5");
+
+ DictionaryAssertions.AssertNotNull(k6, "k6");
+
+ DictionaryAssertions.AssertNotNull(k7, "k7");
+
+ DictionaryAssertions.AssertNotNull(value, "value");
+
+
+
+ var secondDimentionData = new ExpirationalMultiDimensionDictionary(
+ ExpirationSpan2, ExpirationSpan3, ExpirationSpan4, ExpirationSpan5, ExpirationSpan6, ExpirationSpan7);
+
+ if (Data.ContainsKey(k1))
+ {
+ secondDimentionData = Data[k1].subData;
+ }
+
+ secondDimentionData.Put(k2, k3, k4, k5, k6, k7, value);
+
+ Data[k1] = (DateTime.Now, secondDimentionData);
+ }
+
+ #endregion
+
+ #region Get
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1)
+ {
+ return Data[k1].subData;
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2)
+ {
+ return Data[k1].subData.Get(k2);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3)
+ {
+ return Data[k1].subData.Get(k2, k3);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ return Data[k1].subData.Get(k2, k3, k4);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ return Data[k1].subData.Get(k2, k3, k4, k5);
+ }
+
+ public ExpirationalMultiDimensionDictionary Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ return Data[k1].subData.Get(k2, k3, k4, k5, k6);
+ }
+
+ public V Get(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7)
+ {
+ Invalidate();
+ DictionaryAssertions.AssertNotNull(k1, "k1");
+
+ DictionaryAssertions.AssertNotNull(k2, "k2");
+
+ DictionaryAssertions.AssertNotNull(k3, "k3");
+
+ DictionaryAssertions.AssertNotNull(k4, "k4");
+
+ DictionaryAssertions.AssertNotNull(k5, "k5");
+
+ DictionaryAssertions.AssertNotNull(k6, "k6");
+
+ DictionaryAssertions.AssertNotNull(k7, "k7");
+
+
+
+
+ if (Data.TryGetValue(k1, out var secondDimensionData))
+ {
+ return secondDimensionData.subData.Get(k2, k3, k4, k5, k6, k7);
+ }
+
+ throw new KeyNotFoundException();
+ }
+
+
+ #endregion
+
+ #region Remove
+
+ public new void Remove(K1 k1)
+ {
+ Invalidate();
+ Data.Remove(k1, out var ignore);
+ }
+
+ public void Remove(K1 k1, K2 k2)
+ {
+ Invalidate();
+ Data[k1].subData.Remove(k2);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Remove(k3);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Remove(k4);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Remove(k5);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Get(k5).Remove(k6);
+ }
+
+
+ public void Remove(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7)
+ {
+ Invalidate();
+ Data[k1].subData.Get(k2).Get(k3).Get(k4).Get(k5).Get(k6).Remove(k7);
+ }
+
+
+
+ #endregion
+
+
+ public void _Remove(K1 k1)
+ {
+ (DateTime date, ExpirationalMultiDimensionDictionary subData) ignore = default;
+ Data.TryRemove(k1, out ignore);
+ }
+
+ public void Invalidate()
+ {
+ DateTime now = DateTime.Now;
+ List toRemove = new List();
+ foreach (var entry in Data)
+ {
+ var age = now - entry.Value.date;
+ if (age > ExpirationSpan1)
+ {
+ toRemove.Add(entry.Key);
+ }
+ }
+
+ if (toRemove.Any())
+ {
+ foreach (var k1 in toRemove)
+ {
+ _Remove(k1);
+ }
+ }
+ }
+ }
+
+}
diff --git a/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti8.cs b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti8.cs
new file mode 100644
index 0000000..397268e
--- /dev/null
+++ b/MultiDimensionDictionary/expirationalMultiDimensionDictionary/expirationalMulti8.cs
@@ -0,0 +1,340 @@
+
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace multiDimensionalDictionary
+{
+
+
+ public class ExpirationalMultiDimensionDictionary
+ {
+ TimeSpan ExpirationSpan1;
+ TimeSpan ExpirationSpan2;
+ TimeSpan ExpirationSpan3;
+ TimeSpan ExpirationSpan4;
+ TimeSpan ExpirationSpan5;
+ TimeSpan ExpirationSpan6;
+ TimeSpan ExpirationSpan7;
+ TimeSpan ExpirationSpan8;
+
+
+
+ public ExpirationalMultiDimensionDictionary(TimeSpan expiration1, TimeSpan expiration2, TimeSpan expiration3,
+ TimeSpan expiration4, TimeSpan expiration5, TimeSpan expiration6, TimeSpan expiration7,
+ TimeSpan expiration8)
+ {
+ ExpirationSpan1 = expiration1;
+ ExpirationSpan2 = expiration2;
+ ExpirationSpan3 = expiration3;
+ ExpirationSpan4 = expiration4;
+ ExpirationSpan5 = expiration5;
+ ExpirationSpan6 = expiration6;
+ ExpirationSpan7 = expiration7;
+ ExpirationSpan8 = expiration8;
+ Data =
+ new ConcurrentDictionary subData)>();
+ }
+
+ public ExpirationalMultiDimensionDictionary(long expiration1, long expiration2, long expiration3,
+ long expiration4, long expiration5, long expiration6, long expiration7, long expiration8) : this(
+ TimeSpan.FromMilliseconds(expiration1), TimeSpan.FromMilliseconds(expiration2),
+ TimeSpan.FromMilliseconds(expiration3), TimeSpan.FromMilliseconds(expiration4),
+ TimeSpan.FromMilliseconds(expiration5), TimeSpan.FromMilliseconds(expiration6),
+ TimeSpan.FromMilliseconds(expiration7), TimeSpan.FromMilliseconds(expiration8))
+ {
+ }
+
+ protected ConcurrentDictionary subData)> Data { get; set; }
+
+ public ExpirationalMultiDimensionDictionary() : base()
+ {
+ Data =
+ new ConcurrentDictionary subData)>();
+ }
+
+
+
+
+ #region ContainsKey
+
+ public bool ContainsKey(K1 k1)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6, k7);
+ }
+
+ public bool ContainsKey(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8)
+ {
+ Invalidate();
+ return Data.ContainsKey(k1) && Data[k1].subData.ContainsKey(k2, k3, k4, k5, k6, k7, k8);
+ }
+
+
+ #endregion
+
+ #region getKeys
+
+ public List<(K1, K2, K3, K4, K5, K6, K7, K8)> GetKeys()
+ {
+ Invalidate();
+ var keys = new List<(K1, K2, K3, K4, K5, K6, K7, K8)>();
+ foreach (var kvp in Data)
+ {
+ List<(K2, K3, K4, K5, K6, K7, K8)> subkeys = kvp.Value.subData.GetKeys();
+ foreach (var subkey in subkeys)
+ {
+ keys.Add((kvp.Key, subkey.Item1, subkey.Item2, subkey.Item3, subkey.Item4, subkey.Item5,
+ subkey.Item6, subkey.Item7));
+ }
+ }
+
+ return keys;
+ }
+
+ #endregion
+
+ #region Put
+
+ public void Put(K1 k1, K2 k2, K3 k3, K4 k4, K5 k5, K6 k6, K7 k7, K8 k8, V value)
+ {
+ Invalidate();
+ DictionaryAssertions.AssertNotNull(k1, "k1");
+
+ DictionaryAssertions.AssertNotNull