From 9e9933bd32b1f346d9a5fd72ba7a3660452d3806 Mon Sep 17 00:00:00 2001 From: bluextx Date: Sat, 11 Jan 2025 11:50:02 +0300 Subject: [PATCH] Refactored key generation and improved type safety across storage components --- .../Model/Config/ReaderConfig.cs | 3 - .../Model/Processing/LooseLootCounts.cs | 14 +-- source/LootDumpProcessor/Model/Template.cs | 99 +++++++++---------- .../Process/ComposedKeyGenerator.cs | 17 ++-- .../Process/IComposedKeyGenerator.cs | 2 +- .../Process/IKeyGenerator.cs | 6 ++ .../Process/NumericKeyGenerator.cs | 13 +++ .../MultithreadSteppedDumpProcessor.cs | 19 ++-- .../Processor/FileProcessor/FileProcessor.cs | 2 +- .../LooseLootProcessor/LooseLootProcessor.cs | 10 +- .../StaticContainerProcessor.cs | 9 +- source/LootDumpProcessor/Program.cs | 1 + .../Collections/FlatKeyableDictionary.cs | 11 ++- .../Storage/Collections/FlatKeyableList.cs | 12 ++- .../SubdivisionedKeyableDictionary.cs | 13 ++- .../Storage/DataStorageFactory.cs | 2 +- .../Implementations/File/FileDataStorage.cs | 3 +- .../File/StoreHandlerFactory.cs | 2 +- .../LootDumpProcessor/Utils/FileDateParser.cs | 22 +++-- .../LootDumpProcessor/Utils/KeyGenerator.cs | 15 --- 20 files changed, 151 insertions(+), 124 deletions(-) create mode 100644 source/LootDumpProcessor/Process/IKeyGenerator.cs create mode 100644 source/LootDumpProcessor/Process/NumericKeyGenerator.cs delete mode 100644 source/LootDumpProcessor/Utils/KeyGenerator.cs diff --git a/source/LootDumpProcessor/Model/Config/ReaderConfig.cs b/source/LootDumpProcessor/Model/Config/ReaderConfig.cs index 3690508..0627b2e 100644 --- a/source/LootDumpProcessor/Model/Config/ReaderConfig.cs +++ b/source/LootDumpProcessor/Model/Config/ReaderConfig.cs @@ -1,6 +1,3 @@ -using System.Text.Json.Serialization; - - namespace LootDumpProcessor.Model.Config; public class ReaderConfig diff --git a/source/LootDumpProcessor/Model/Processing/LooseLootCounts.cs b/source/LootDumpProcessor/Model/Processing/LooseLootCounts.cs index 295f99a..28a62d9 100644 --- a/source/LootDumpProcessor/Model/Processing/LooseLootCounts.cs +++ b/source/LootDumpProcessor/Model/Processing/LooseLootCounts.cs @@ -1,22 +1,24 @@ using System.Text.Json.Serialization; using LootDumpProcessor.Storage; -using LootDumpProcessor.Utils; namespace LootDumpProcessor.Model.Processing; public class LooseLootCounts : IKeyable { - [JsonPropertyName("__id__")] public string __ID { get; set; } = KeyGenerator.GetNextKey(); + [JsonPropertyName("__id__")] private string Id { get; set; } public IKey Counts { get; set; } - - // public IKey Items { get; set; } public IKey ItemProperties { get; set; } public List MapSpawnpointCount { get; set; } = new(); - public IKey GetKey() + public LooseLootCounts(string id, IKey counts, IKey itemProperties) { - return new FlatUniqueKey(new[] { __ID }); + ArgumentException.ThrowIfNullOrWhiteSpace(id); + Id = id; + Counts = counts ?? throw new ArgumentNullException(nameof(counts)); + ItemProperties = itemProperties ?? throw new ArgumentNullException(nameof(itemProperties)); } + + public IKey GetKey() => new FlatUniqueKey([Id]); } \ No newline at end of file diff --git a/source/LootDumpProcessor/Model/Template.cs b/source/LootDumpProcessor/Model/Template.cs index a8408a4..8274852 100644 --- a/source/LootDumpProcessor/Model/Template.cs +++ b/source/LootDumpProcessor/Model/Template.cs @@ -7,70 +7,63 @@ namespace LootDumpProcessor.Model; public class Template : IKeyable, ICloneable { - [JsonIgnore] public string __ID { get; } = KeyGenerator.GetNextKey(); + [JsonIgnore] public string internalId { get; } + public string Id { get; set; } + public bool IsContainer { get; set; } + public bool UseGravity { get; set; } + public bool RandomRotation { get; set; } + public Vector3 Position { get; set; } + public Vector3 Rotation { get; set; } + public bool IsGroupPosition { get; set; } + public List GroupPositions { get; set; } + public bool IsAlwaysSpawn { get; set; } + public string Root { get; set; } + public List Items { get; set; } + public Template(string internalId, string id, bool isContainer, bool useGravity, bool randomRotation, + Vector3 position, Vector3 rotation, bool isGroupPosition, List groupPositions, + bool isAlwaysSpawn, string root, List items) + { + this.internalId = internalId; + Id = id; + IsContainer = isContainer; + UseGravity = useGravity; + RandomRotation = randomRotation; + Position = position; + Rotation = rotation; + IsGroupPosition = isGroupPosition; + GroupPositions = groupPositions; + IsAlwaysSpawn = isAlwaysSpawn; + Root = root; + Items = items; + } - public string? Id { get; set; } - - - public bool? IsContainer { get; set; } - - - public bool? UseGravity { get; set; } - - - public bool? RandomRotation { get; set; } - - - public Vector3? Position { get; set; } - - - public Vector3? Rotation { get; set; } - - - public bool? IsGroupPosition { get; set; } - - - public List? GroupPositions { get; set; } - - - public bool? IsAlwaysSpawn { get; set; } - - - public string? Root { get; set; } - - - public required List Items { get; set; } - - protected bool Equals(Template other) => Id == other.Id; + private bool Equals(Template other) => Id == other.Id; public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; - return Equals((Template)obj); + return obj.GetType() == GetType() && Equals((Template)obj); } public override int GetHashCode() => Id != null ? Id.GetHashCode() : 0; - public IKey GetKey() - { - return new FlatUniqueKey(new[] { __ID }); - } + public IKey GetKey() => new FlatUniqueKey([internalId]); public object Clone() => new Template - { - Id = Id, - IsContainer = IsContainer, - UseGravity = UseGravity, - RandomRotation = RandomRotation, - Position = ProcessorUtil.Copy(Position), - Rotation = ProcessorUtil.Copy(Rotation), - IsGroupPosition = IsGroupPosition, - GroupPositions = ProcessorUtil.Copy(GroupPositions), - IsAlwaysSpawn = IsAlwaysSpawn, - Root = Root, - Items = ProcessorUtil.Copy(Items) - }; + ( + internalId, + Id, + IsContainer, + UseGravity, + RandomRotation, + ProcessorUtil.Copy(Position), + ProcessorUtil.Copy(Rotation), + IsGroupPosition, + ProcessorUtil.Copy(GroupPositions), + IsAlwaysSpawn, + Root, + ProcessorUtil.Copy(Items) + ); } \ No newline at end of file diff --git a/source/LootDumpProcessor/Process/ComposedKeyGenerator.cs b/source/LootDumpProcessor/Process/ComposedKeyGenerator.cs index 968d672..d552d56 100644 --- a/source/LootDumpProcessor/Process/ComposedKeyGenerator.cs +++ b/source/LootDumpProcessor/Process/ComposedKeyGenerator.cs @@ -1,15 +1,19 @@ -using LootDumpProcessor.Model; +using System.Globalization; +using LootDumpProcessor.Model; using LootDumpProcessor.Model.Processing; -using LootDumpProcessor.Utils; namespace LootDumpProcessor.Process; -public class ComposedKeyGenerator(ITarkovItemsProvider tarkovItemsProvider) : IComposedKeyGenerator +public class ComposedKeyGenerator(ITarkovItemsProvider tarkovItemsProvider, IKeyGenerator keyGenerator) + : IComposedKeyGenerator { private readonly ITarkovItemsProvider _tarkovItemsProvider = tarkovItemsProvider ?? throw new ArgumentNullException(nameof(tarkovItemsProvider)); - public ComposedKey Generate(IEnumerable items) + private readonly IKeyGenerator + _keyGenerator = keyGenerator ?? throw new ArgumentNullException(nameof(keyGenerator)); + + public ComposedKey Generate(IReadOnlyList? items) { var key = items?.Select(i => i.Tpl) .Where(i => !string.IsNullOrEmpty(i) && @@ -17,8 +21,9 @@ public class ComposedKeyGenerator(ITarkovItemsProvider tarkovItemsProvider) : IC .Cast() .Select(i => (double)i.GetHashCode()) .Sum() - .ToString() ?? KeyGenerator.GetNextKey(); - var firstItem = items?.FirstOrDefault(); + .ToString(CultureInfo.InvariantCulture) ?? _keyGenerator.Generate(); + var firstItem = items?[0]; + return new ComposedKey(key, firstItem); } } \ No newline at end of file diff --git a/source/LootDumpProcessor/Process/IComposedKeyGenerator.cs b/source/LootDumpProcessor/Process/IComposedKeyGenerator.cs index ccde32a..09d974e 100644 --- a/source/LootDumpProcessor/Process/IComposedKeyGenerator.cs +++ b/source/LootDumpProcessor/Process/IComposedKeyGenerator.cs @@ -4,5 +4,5 @@ namespace LootDumpProcessor.Process; public interface IComposedKeyGenerator { - ComposedKey Generate(IEnumerable items); + ComposedKey Generate(IReadOnlyList? items); } \ No newline at end of file diff --git a/source/LootDumpProcessor/Process/IKeyGenerator.cs b/source/LootDumpProcessor/Process/IKeyGenerator.cs new file mode 100644 index 0000000..5bf967e --- /dev/null +++ b/source/LootDumpProcessor/Process/IKeyGenerator.cs @@ -0,0 +1,6 @@ +namespace LootDumpProcessor.Process; + +public interface IKeyGenerator +{ + string Generate(); +} \ No newline at end of file diff --git a/source/LootDumpProcessor/Process/NumericKeyGenerator.cs b/source/LootDumpProcessor/Process/NumericKeyGenerator.cs new file mode 100644 index 0000000..a224509 --- /dev/null +++ b/source/LootDumpProcessor/Process/NumericKeyGenerator.cs @@ -0,0 +1,13 @@ +namespace LootDumpProcessor.Process; + +public class NumericKeyGenerator : IKeyGenerator +{ + private ulong _currentKey; + + public string Generate() + { + var key = _currentKey; + Interlocked.Increment(ref _currentKey); + return key.ToString(); + } +} \ No newline at end of file diff --git a/source/LootDumpProcessor/Process/Processor/DumpProcessor/MultithreadSteppedDumpProcessor.cs b/source/LootDumpProcessor/Process/Processor/DumpProcessor/MultithreadSteppedDumpProcessor.cs index edddc92..b26138d 100644 --- a/source/LootDumpProcessor/Process/Processor/DumpProcessor/MultithreadSteppedDumpProcessor.cs +++ b/source/LootDumpProcessor/Process/Processor/DumpProcessor/MultithreadSteppedDumpProcessor.cs @@ -24,7 +24,7 @@ public class MultithreadSteppedDumpProcessor( IStaticContainersProcessor staticContainersProcessor, IAmmoProcessor ammoProcessor, ILooseLootProcessor looseLootProcessor, - ILogger logger + ILogger logger, IKeyGenerator keyGenerator ) : IDumpProcessor { @@ -43,6 +43,9 @@ public class MultithreadSteppedDumpProcessor( private readonly ILogger _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + private readonly IKeyGenerator + _keyGenerator = keyGenerator ?? throw new ArgumentNullException(nameof(keyGenerator)); + private static readonly IDataStorage _dataStorage = DataStorageFactory.GetInstance(); public Dictionary ProcessDumps(List dumps) @@ -225,17 +228,17 @@ public class MultithreadSteppedDumpProcessor( var lockObjectContainerCounts = new object(); var lockObjectCounts = new object(); - var looseLootCounts = new LooseLootCounts(); var lockObjectDictionaryCounts = new object(); - var dictionaryCounts = new FlatKeyableDictionary(); - looseLootCounts.Counts = dictionaryCounts.GetKey(); + var dictionaryCounts = new FlatKeyableDictionary(_keyGenerator.Generate()); var lockObjectDictionaryItemProperties = new object(); - var dictionaryItemProperties = new FlatKeyableDictionary>(); + var dictionaryItemProperties = + new FlatKeyableDictionary>(_keyGenerator.Generate()); - var actualDictionaryItemProperties = new FlatKeyableDictionary(); - looseLootCounts.ItemProperties = actualDictionaryItemProperties.GetKey(); + var actualDictionaryItemProperties = new FlatKeyableDictionary(_keyGenerator.Generate()); + var looseLootCounts = new LooseLootCounts(_keyGenerator.Generate(), dictionaryCounts.GetKey(), + actualDictionaryItemProperties.GetKey()); dumpProcessData.LooseLootCounts.Add(mapName, looseLootCounts.GetKey()); @@ -316,7 +319,7 @@ public class MultithreadSteppedDumpProcessor( { if (!dictionaryItemProperties.TryGetValue(uniqueKey, out var values)) { - values = new FlatKeyableList