From 4daaf1fc47987fa1fa73f38f675ca10f07bd73fa Mon Sep 17 00:00:00 2001 From: Archangel Date: Thu, 18 Dec 2025 15:39:57 +0100 Subject: [PATCH] Make ItemBaseClassService more robust, stop hydrating the entire DB each time --- .../Services/ItemBaseClassService.cs | 59 +++++++++---------- .../Services/Mod/CustomItemService.cs | 4 +- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs b/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs index fedb694b..ccd76572 100644 --- a/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs @@ -16,12 +16,11 @@ public class ItemBaseClassService( ServerLocalisationService serverLocalisationService ) { - private bool _cacheGenerated; - /// /// Key = Item tpl, values = Ids of its parents /// private Dictionary> _itemBaseClassesCache = []; + private readonly Lock _itemBaseClassesLock = new(); private readonly HashSet _rootNodeIds = []; /// @@ -36,23 +35,34 @@ public class ItemBaseClassService( var items = databaseService.GetItems(); foreach (var item in items) { - if (string.Equals(item.Value.Type, "Item", StringComparison.OrdinalIgnoreCase)) - { - var itemIdToUpdate = item.Value.Id; - if (!_itemBaseClassesCache.ContainsKey(item.Value.Id)) - { - _itemBaseClassesCache[item.Value.Id] = []; - } + AddItemToCache(item.Key); + } + } - AddBaseItems(itemIdToUpdate, item.Value); + public void AddItemToCache(MongoId itemTpl) + { + logger.Debug($"Adding {itemTpl} to cache"); + + var itemDb = databaseService.GetItems(); + + if (!itemDb.TryGetValue(itemTpl, out var item)) + { + logger.Error($"Could not add {itemTpl} to cache, it does not exist in the item database!"); + return; + } + + lock (_itemBaseClassesLock) + { + if (string.Equals(item.Type, "Item", StringComparison.OrdinalIgnoreCase)) + { + _itemBaseClassesCache.TryAdd(item.Id, []); + AddBaseItems(item.Id, item); } else { - _rootNodeIds.Add(item.Key); + _rootNodeIds.Add(item.Id); } } - - _cacheGenerated = true; } /// @@ -79,11 +89,6 @@ public class ItemBaseClassService( /// true if item inherits from base class passed in public bool ItemHasBaseClass(MongoId itemTpl, IEnumerable baseClasses) { - if (!_cacheGenerated) - { - HydrateItemBaseClassCache(); - } - if (itemTpl.IsEmpty) { logger.Warning("Unable to check itemTpl base class as value passed is null"); @@ -107,8 +112,8 @@ public class ItemBaseClassService( logger.Debug(serverLocalisationService.GetText("baseclass-item_not_found", itemTpl.ToString())); } - // Not found in cache, Hydrate again - some mods add items late in server startup lifecycle - HydrateItemBaseClassCache(); + // Not found in cache, attempt to add first + AddItemToCache(itemTpl); existsInCache = _itemBaseClassesCache.TryGetValue(itemTpl, out baseClassList); } @@ -131,11 +136,6 @@ public class ItemBaseClassService( /// true if item inherits from base class passed in public bool ItemHasBaseClass(MongoId itemTpl, MongoId baseClasses) { - if (!_cacheGenerated) - { - HydrateItemBaseClassCache(); - } - if (itemTpl.IsEmpty) { logger.Warning("Unable to check itemTpl base class as value passed is null"); @@ -159,8 +159,8 @@ public class ItemBaseClassService( logger.Debug(serverLocalisationService.GetText("baseclass-item_not_found", itemTpl.ToString())); } - // Not found in cache, Hydrate again - some mods add items late in server startup lifecycle - HydrateItemBaseClassCache(); + // Not found in cache, attempt to add first + AddItemToCache(itemTpl); existsInCache = _itemBaseClassesCache.TryGetValue(itemTpl, out baseClassList); } @@ -182,11 +182,6 @@ public class ItemBaseClassService( /// array of base classes public HashSet GetItemBaseClasses(MongoId itemTpl) { - if (!_cacheGenerated) - { - HydrateItemBaseClassCache(); - } - if (!_itemBaseClassesCache.TryGetValue(itemTpl, out var value)) { return []; diff --git a/Libraries/SPTarkov.Server.Core/Services/Mod/CustomItemService.cs b/Libraries/SPTarkov.Server.Core/Services/Mod/CustomItemService.cs index 7f982923..57078670 100644 --- a/Libraries/SPTarkov.Server.Core/Services/Mod/CustomItemService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/Mod/CustomItemService.cs @@ -66,7 +66,7 @@ public class CustomItemService( AddToFleaPriceDb(newItemId, newItemDetails.FleaPriceRoubles); - itemBaseClassService.HydrateItemBaseClassCache(); + itemBaseClassService.AddItemToCache(newItemId); if (itemHelper.IsOfBaseclass(itemClone.Id, BaseClasses.WEAPON)) { @@ -112,7 +112,7 @@ public class CustomItemService( AddToFleaPriceDb(newItem.Id, newItemDetails.FleaPriceRoubles); - itemBaseClassService.HydrateItemBaseClassCache(); + itemBaseClassService.AddItemToCache(newItem.Id); if (itemHelper.IsOfBaseclass(newItem.Id, BaseClasses.WEAPON)) {