diff --git a/SabreTools.DatFiles/ItemDictionaryDB.cs b/SabreTools.DatFiles/ItemDictionaryDB.cs index 669e8fe4..189c42a8 100644 --- a/SabreTools.DatFiles/ItemDictionaryDB.cs +++ b/SabreTools.DatFiles/ItemDictionaryDB.cs @@ -1,8 +1,8 @@ #if NET40_OR_GREATER || NETCOREAPP using System.Collections.Concurrent; -#else -using System.Collections.Generic; #endif +using System.Collections.Generic; +using System.Linq; using System.Xml.Serialization; using Newtonsoft.Json; using SabreTools.DatItems; @@ -20,30 +20,188 @@ namespace SabreTools.DatFiles /// /// Internal dictionary for all items /// + [JsonIgnore, XmlIgnore] #if NET40_OR_GREATER || NETCOREAPP - private readonly ConcurrentDictionary items = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _items = new ConcurrentDictionary(); #else - private readonly Dictionary items = []; + private readonly Dictionary _items = []; #endif + /// + /// Current highest available item index + /// + private long _itemIndex = 0; + /// /// Internal dictionary for all machines /// + [JsonIgnore, XmlIgnore] #if NET40_OR_GREATER || NETCOREAPP - private readonly ConcurrentDictionary machines = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _machines = new ConcurrentDictionary(); #else - private readonly Dictionary machines = []; + private readonly Dictionary _machines = []; #endif + /// + /// Current highest available machine index + /// + private long _machineIndex = 0; + /// /// Internal dictionary for item to machine mappings /// + [JsonIgnore, XmlIgnore] #if NET40_OR_GREATER || NETCOREAPP - private readonly ConcurrentDictionary itemToMachineMapping = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _itemToMachineMapping = new ConcurrentDictionary(); #else - private readonly Dictionary itemToMachineMapping = []; + private readonly Dictionary _itemToMachineMapping = []; #endif + // TODO: Add another dictionary of string => ConcurrentList representing a bucketed key to a set of item IDs + #endregion + + #region Fields + + /// + /// DAT statistics + /// + [JsonIgnore, XmlIgnore] + public DatStatistics DatStatistics { get; } = new DatStatistics(); + + #endregion + + #region Accessors + + /// + /// Add an item, returning the insert index + /// + public long AddItem(DatItem item) + { + _items[_itemIndex++] = item; + DatStatistics.AddItemStatistics(item); + return _itemIndex - 1; + } + + /// + /// Add a machine, returning the insert index + /// + public long AddMachine(Machine machine) + { + _machines[_machineIndex++] = machine; + return _machineIndex - 1; + } + + /// + /// Get an item based on the index + /// + public DatItem? GetItemByIndex(long index) + { + if (!_items.ContainsKey(index)) + return null; + + return _items[index]; + } + + /// + /// Get a machine based on the index + /// + public Machine? GetMachineByIndex(long index) + { + if (!_machines.ContainsKey(index)) + return null; + + return _machines[index]; + } + + /// + /// Get the machine associated with an item index + /// + public Machine? GetMachineForItemByIndex(long itemIndex) + { + if (!_itemToMachineMapping.ContainsKey(itemIndex)) + return null; + + long machineIndex = _itemToMachineMapping[itemIndex]; + if (!_machines.ContainsKey(machineIndex)) + return null; + + return _machines[machineIndex]; + } + + /// + /// Get the items associated with a machine index + /// + public DatItem[]? GetDatItemsForMachineByIndex(long machineIndex) + { + var itemIds = _itemToMachineMapping + .Where(mapping => mapping.Value == machineIndex) + .Select(mapping => mapping.Key); + + var datItems = new List(); + foreach (long itemId in itemIds) + { + if (_items.ContainsKey(itemId)) + datItems.Add(_items[itemId]); + } + + return datItems.ToArray(); + } + + /// + /// Remove an item, returning if it could be removed + /// + public bool RemoveItem(long itemIndex) + { + if (!_items.ContainsKey(itemIndex)) + return false; + +#if NET40_OR_GREATER || NETCOREAPP + _items.TryRemove(itemIndex, out _); +#else + _items.Remove(itemIndex); +#endif + + if (_itemToMachineMapping.ContainsKey(itemIndex)) +#if NET40_OR_GREATER || NETCOREAPP + _itemToMachineMapping.TryRemove(itemIndex, out _); +#else + _itemToMachineMapping.Remove(itemIndex); +#endif + + return true; + } + + /// + /// Remove a machine, returning if it could be removed + /// + public bool RemoveMachine(long machineIndex) + { + if (!_machines.ContainsKey(machineIndex)) + return false; + +#if NET40_OR_GREATER || NETCOREAPP + _machines.TryRemove(machineIndex, out _); +#else + _machines.Remove(machineIndex); +#endif + + var itemIds = _itemToMachineMapping + .Where(mapping => mapping.Value == machineIndex) + .Select(mapping => mapping.Key); + + foreach (long itemId in itemIds) + { +#if NET40_OR_GREATER || NETCOREAPP + _itemToMachineMapping.TryRemove(itemId, out _); +#else + _itemToMachineMapping.Remove(itemId); +#endif + } + + return true; + } + +#endregion } }