Micro-optimisations

Moved `GetInventoryItemHash` to extensions and rewrote to make better use of linq
This commit is contained in:
Chomp
2025-07-19 11:11:59 +01:00
parent 5f5bf3c39f
commit d7f83e1b7d
3 changed files with 28 additions and 39 deletions
@@ -1,5 +1,6 @@
using System.Text.Json;
using SPTarkov.Common.Extensions;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
@@ -442,5 +443,25 @@ namespace SPTarkov.Server.Core.Extensions
return newId.Value;
}
/// <summary>
/// Create hashsets for passed in items, keyed by the items ID and by the items parentId
/// </summary>
/// <param name="inventoryItems">Items to hash</param>
/// <returns>InventoryItemHash</returns>
public static InventoryItemHash GetInventoryItemHash(this List<Item> inventoryItems)
{
// Group by parentId + turn value into mongoId as we've filtered out non-mongoId values
var byParentId = inventoryItems
.Where(item => !string.IsNullOrEmpty(item.ParentId) && item.ParentId != "hideout")
.GroupBy(item => new MongoId(item.ParentId))
.ToDictionary(kvp => kvp.Key, group => group.ToHashSet());
return new InventoryItemHash
{
ByItemId = inventoryItems.ToDictionary(item => item.Id),
ByParentId = byParentId,
};
}
}
}
@@ -636,9 +636,9 @@ public class BotGeneratorHelper(
);
// Get root items in container we can iterate over to find out what space is free
var containerItemsToCheck = existingContainerItems.Where(x =>
x.SlotId == slotGrid.Name
);
var containerItemsToCheck = existingContainerItems
.Where(x => x.SlotId == slotGrid.Name)
.ToList();
var containerItemsWithChildren = GetContainerItemsWithChildren(
containerItemsToCheck,
inventory.Items
@@ -729,7 +729,7 @@ public class BotGeneratorHelper(
}
// Filter out all items without location prop, (child items)
var itemsWithoutLocation = inventoryItems.Where(item => item.Location is null);
var itemsWithoutLocation = inventoryItems.Where(item => item.Location is null).ToList();
foreach (var rootItem in containerRootItems)
{
// Check item in container for children, store for later insertion into `containerItemsToCheck`
@@ -668,7 +668,7 @@ public class InventoryHelper(
public (int, int) GetItemSize(MongoId itemTpl, MongoId itemId, List<Item> inventoryItems)
{
// -> Prepares item Width and height returns [sizeX, sizeY]
return GetSizeByInventoryItemHash(itemTpl, itemId, GetInventoryItemHash(inventoryItems));
return GetSizeByInventoryItemHash(itemTpl, itemId, inventoryItems.GetInventoryItemHash());
}
/// <summary>
@@ -755,7 +755,7 @@ public class InventoryHelper(
{
// Storage for root item and its children, store root item id for now
// Will store child items that may have sub-children to process
var toDo = new Queue<string>([itemId]);
var toDo = new Queue<MongoId>([itemId]);
while (toDo.Count > 0)
{
// Lookup parent in `to do queue`, get all of its children, then loop over them
@@ -870,7 +870,7 @@ public class InventoryHelper(
);
// Get all items in players inventory keyed by their parentId and by ItemId
var inventoryItemHash = GetInventoryItemHash(itemList);
var inventoryItemHash = itemList.GetInventoryItemHash();
// Get subset of items that belong to the desired container
if (!inventoryItemHash.ByParentId.TryGetValue(containerId, out var rootItemsInContainer))
@@ -948,38 +948,6 @@ public class InventoryHelper(
return container;
}
protected InventoryItemHash GetInventoryItemHash(List<Item> inventoryItems)
{
var inventoryItemHash = new InventoryItemHash
{
ByItemId = new Dictionary<MongoId, Item>(),
ByParentId = new Dictionary<MongoId, HashSet<Item>>(),
};
foreach (var item in inventoryItems)
{
inventoryItemHash.ByItemId.TryAdd(item.Id, item);
if (item.ParentId is null)
{
continue;
}
if (item.ParentId == "hideout")
{
continue;
}
if (!inventoryItemHash.ByParentId.ContainsKey(item.ParentId))
{
inventoryItemHash.ByParentId[item.ParentId] = [];
}
inventoryItemHash.ByParentId[item.ParentId].Add(item);
}
return inventoryItemHash;
}
/// <summary>
/// Return the inventory that needs to be modified (scav/pmc etc)
/// Changes made to result apply to character inventory