Improved further memory usage and added a subsystem for the collector to dump into a file data while it keeps the pre-processor going

This commit is contained in:
Alex 2024-01-30 20:22:32 +00:00
parent 2930581d25
commit 54243f0932
15 changed files with 124 additions and 19 deletions

View File

@ -47,6 +47,11 @@
"spawnPointToleranceForForced": 99.5, "spawnPointToleranceForForced": 99.5,
"looseLootCountTolerancePercentage": 75 "looseLootCountTolerancePercentage": 75
}, },
"collectorConfig": {
"collectorType": "Dump",
"maxEntitiesBeforeDumping": 1000,
"dumpLocation": "C:\\Users\\USER\\SPT\\tmp"
},
"writerConfig": { "writerConfig": {
"outputLocation": "E:\\spt\\dumps\\output" "outputLocation": "E:\\spt\\dumps\\output"
}, },

View File

@ -1,5 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using LootDumpProcessor.Model.Processing; using LootDumpProcessor.Model.Processing;
using LootDumpProcessor.Utils;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace LootDumpProcessor.Model; namespace LootDumpProcessor.Model;
@ -26,7 +27,7 @@ public class ComposedKey
.Cast<string>() .Cast<string>()
.Select(i => (double)i.GetHashCode()) .Select(i => (double)i.GetHashCode())
.Sum() .Sum()
.ToString() ?? Guid.NewGuid().ToString(); .ToString() ?? KeyGenerator.GetNextKey();
FirstItem = items?[0]; FirstItem = items?[0];
} }

View File

@ -0,0 +1,20 @@
using System.Text.Json.Serialization;
using LootDumpProcessor.Process.Collector;
using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Config;
public class CollectorConfig
{
[JsonProperty("collectorType")]
[JsonPropertyName("collectorType")]
public CollectorType CollectorType { get; set; }
[JsonProperty("maxEntitiesBeforeDumping")]
[JsonPropertyName("maxEntitiesBeforeDumping")]
public int MaxEntitiesBeforeDumping { get; set; }
[JsonProperty("dumpLocation")]
[JsonPropertyName("dumpLocation")]
public string DumpLocation { get; set; }
}

View File

@ -49,6 +49,10 @@ public class Config
[JsonProperty("writerConfig")] [JsonProperty("writerConfig")]
[JsonPropertyName("writerConfig")] [JsonPropertyName("writerConfig")]
public WriterConfig WriterConfig { get; set; } public WriterConfig WriterConfig { get; set; }
[JsonProperty("collectorConfig")]
[JsonPropertyName("collectorConfig")]
public CollectorConfig CollectorConfig { get; set; }
[JsonProperty("containerIgnoreList")] [JsonProperty("containerIgnoreList")]
[JsonPropertyName("containerIgnoreList")] [JsonPropertyName("containerIgnoreList")]

View File

@ -1,5 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using LootDumpProcessor.Storage; using LootDumpProcessor.Storage;
using LootDumpProcessor.Utils;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace LootDumpProcessor.Model.Processing; namespace LootDumpProcessor.Model.Processing;
@ -8,7 +9,7 @@ public class LooseLootCounts : IKeyable
{ {
[JsonProperty("__id__")] [JsonProperty("__id__")]
[JsonPropertyName("__id__")] [JsonPropertyName("__id__")]
public string __ID { get; set; } = Guid.NewGuid().ToString(); public string __ID { get; set; } = KeyGenerator.GetNextKey();
public IKey Counts { get; set; } public IKey Counts { get; set; }

View File

@ -9,7 +9,7 @@ namespace LootDumpProcessor.Model
{ {
[Newtonsoft.Json.JsonIgnore] [Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore] [System.Text.Json.Serialization.JsonIgnore]
public string __ID { get; } = Guid.NewGuid().ToString(); public string __ID { get; } = KeyGenerator.GetNextKey();
[JsonProperty("Id", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("Id", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("Id")] [JsonPropertyName("Id")]

View File

@ -2,9 +2,16 @@
public static class CollectorFactory public static class CollectorFactory
{ {
private static ICollector? _collector;
public static ICollector GetInstance() public static ICollector GetInstance()
{ {
// TODO: implement real factory if (_collector == null)
return new HashSetCollector(); _collector = LootDumpProcessorContext.GetConfig().CollectorConfig.CollectorType switch
{
CollectorType.Memory => new HashSetCollector(),
CollectorType.Dump => new DumpCollector(),
_ => throw new ArgumentOutOfRangeException()
};
return _collector;
} }
} }

View File

@ -0,0 +1,7 @@
namespace LootDumpProcessor.Process.Collector;
public enum CollectorType
{
Memory,
Dump
}

View File

@ -0,0 +1,45 @@
using LootDumpProcessor.Model.Processing;
using LootDumpProcessor.Serializers.Json;
namespace LootDumpProcessor.Process.Collector;
public class DumpCollector : ICollector
{
private static readonly string DumpLocation = $"{LootDumpProcessorContext.GetConfig().CollectorConfig.DumpLocation}/collector/";
private readonly List<PartialData> processedDumps = new(LootDumpProcessorContext.GetConfig().CollectorConfig.MaxEntitiesBeforeDumping + 50);
private readonly object lockObject = new();
public void Setup()
{
if (Directory.Exists(DumpLocation))
{
Directory.Delete(DumpLocation, true);
}
Directory.CreateDirectory(DumpLocation);
}
public void Hold(PartialData parsedDump)
{
lock (lockObject)
{
processedDumps.Add(parsedDump);
if (processedDumps.Count > LootDumpProcessorContext.GetConfig().CollectorConfig.MaxEntitiesBeforeDumping)
{
var fileName = $"collector-{DateTime.Now.ToString("yyyyMMddHHmmssfffff")}.json";
File.WriteAllText($"{DumpLocation}{fileName}", JsonSerializerFactory.GetInstance().Serialize(processedDumps));
processedDumps.Clear();
}
}
}
public List<PartialData> Retrieve()
{
foreach (var file in Directory.GetFiles(DumpLocation))
{
processedDumps.AddRange(JsonSerializerFactory.GetInstance().Deserialize<List<PartialData>>(File.ReadAllText(file)));
}
return processedDumps;
}
}

View File

@ -4,11 +4,9 @@ namespace LootDumpProcessor.Process.Collector;
public class HashSetCollector : ICollector public class HashSetCollector : ICollector
{ {
private readonly HashSet<PartialData> processedDumps = new(); private readonly HashSet<PartialData> processedDumps = new(100_000);
private readonly object lockObject = new(); private readonly object lockObject = new();
public void Setup() public void Setup()
{ {
} }

View File

@ -2,7 +2,7 @@
public static class FileProcessorFactory public static class FileProcessorFactory
{ {
private static IFileProcessor _fileProcessor; private static IFileProcessor? _fileProcessor;
public static IFileProcessor GetInstance() public static IFileProcessor GetInstance()
{ {
// TODO: implement actual factory someday // TODO: implement actual factory someday

View File

@ -1,4 +1,5 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using LootDumpProcessor.Utils;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace LootDumpProcessor.Storage.Collections; namespace LootDumpProcessor.Storage.Collections;
@ -7,10 +8,10 @@ public class FlatKeyableDictionary<K, V> : Dictionary<K, V>, IKeyable
{ {
[JsonProperty("__id__")] [JsonProperty("__id__")]
[JsonPropertyName("__id__")] [JsonPropertyName("__id__")]
public string __ID { get; set; } = Guid.NewGuid().ToString(); public string __ID { get; set; } = KeyGenerator.GetNextKey();
public IKey GetKey() public IKey GetKey()
{ {
return new FlatUniqueKey(new[] { __ID }); return new FlatUniqueKey([__ID]);
} }
} }

View File

@ -1,11 +1,13 @@
namespace LootDumpProcessor.Storage.Collections; using LootDumpProcessor.Utils;
namespace LootDumpProcessor.Storage.Collections;
public class FlatKeyableList<T> : List<T>, IKeyable public class FlatKeyableList<T> : List<T>, IKeyable
{ {
public string __ID { get; } = Guid.NewGuid().ToString(); public string __ID { get; } = KeyGenerator.GetNextKey();
public IKey GetKey() public IKey GetKey()
{ {
return new FlatUniqueKey(new[] { __ID }); return new FlatUniqueKey([__ID]);
} }
} }

View File

@ -1,4 +1,5 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using LootDumpProcessor.Utils;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace LootDumpProcessor.Storage.Collections; namespace LootDumpProcessor.Storage.Collections;
@ -7,7 +8,7 @@ public class SubdivisionedKeyableDictionary<K, V> : Dictionary<K, V>, IKeyable
{ {
[JsonProperty("__id__")] [JsonProperty("__id__")]
[JsonPropertyName("__id__")] [JsonPropertyName("__id__")]
public string __ID { get; set; } = Guid.NewGuid().ToString(); public string __ID { get; set; } = KeyGenerator.GetNextKey();
[JsonProperty("extras")] [JsonProperty("extras")]
[JsonPropertyName("extras")] [JsonPropertyName("extras")]
@ -38,10 +39,8 @@ public class SubdivisionedKeyableDictionary<K, V> : Dictionary<K, V>, IKeyable
subdivisions.Add(__ID); subdivisions.Add(__ID);
return new SubdivisionedUniqueKey(subdivisions.ToArray()); return new SubdivisionedUniqueKey(subdivisions.ToArray());
} }
else
{ return new SubdivisionedUniqueKey(["dictionaries", __ID]);
return new SubdivisionedUniqueKey(new[] { "dictionaries", __ID });
}
} }
public void AddExtraSubdivisions(string[] extras) public void AddExtraSubdivisions(string[] extras)

15
Utils/KeyGenerator.cs Normal file
View File

@ -0,0 +1,15 @@
namespace LootDumpProcessor.Utils;
public class KeyGenerator
{
private static long currentKey = 0L;
private static object lockObject = new();
public static string GetNextKey()
{
lock (lockObject)
{
return $"{++currentKey}";
}
}
}