Minor refresh of RagfairRequiredItemsService

Adding a new set + lookup is now atomic
Returns a readonly set, caller shouldn't be able to ever modify this data
Removed memory allocation when calling `GetRequiredOffersById` with a tpl that doesn't have any offerIds
This commit is contained in:
Chomp
2025-08-17 15:47:03 +01:00
parent f96172ac60
commit 3f0d68dbf6
@@ -11,43 +11,46 @@ public class RagfairRequiredItemsService(RagfairOfferService ragfairOfferService
/// <summary>
/// Key = tpl
/// </summary>
protected readonly ConcurrentDictionary<MongoId, HashSet<MongoId>> _requiredItemsCache = new();
protected readonly ConcurrentDictionary<MongoId, HashSet<MongoId>> RequiredItemsCache = new();
/// <summary>
/// Empty hashset to be returned when no keys found by GetRequiredOffersById (reduces memory allocations)
/// </summary>
protected readonly IReadOnlySet<MongoId> EmptyOfferIdSet = new HashSet<MongoId>();
/// <summary>
/// Get the offerId of offers that require the supplied tpl
/// </summary>
/// <param name="tpl">Tpl to find offers ids for</param>
/// <returns></returns>
public HashSet<MongoId> GetRequiredOffersById(MongoId tpl)
/// <returns>Set of OfferIds</returns>
public IReadOnlySet<MongoId> GetRequiredOffersById(MongoId tpl)
{
if (_requiredItemsCache.TryGetValue(tpl, out var offerIds))
{
return offerIds;
}
return [];
return RequiredItemsCache.TryGetValue(tpl, out var offerIds) ? offerIds : EmptyOfferIdSet;
}
/// <summary>
/// Create a cache of requirements to purchase item
/// Create a cache of offer Ids keyed against the item tpl they require
/// </summary>
public void BuildRequiredItemTable()
{
_requiredItemsCache.Clear();
RequiredItemsCache.Clear();
foreach (var offer in ragfairOfferService.GetOffers())
foreach (var requirement in offer.Requirements)
{
if (paymentHelper.IsMoneyTpl(requirement.TemplateId))
// This would just be too noisy
foreach (var requirement in offer.Requirements ?? [])
{
continue;
// Skip offers for currency, it's too expensive to process
// Only process barter offers
if (paymentHelper.IsMoneyTpl(requirement.TemplateId))
{
continue;
}
// Ensure cache has Hashset init for this tpl
var offerIds = RequiredItemsCache.GetOrAdd(requirement.TemplateId, _ => []);
// Add offer id against the tpl key
offerIds.Add(offer.Id);
}
// Ensure key is init
_requiredItemsCache.TryAdd(requirement.TemplateId, []);
// Add matching offer
_requiredItemsCache.GetValueOrDefault(requirement.TemplateId)?.Add(offer.Id);
}
}
}