From 2a2a2a46f993ee03a5bfe59e211d4e6fb87d07f3 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 16 Apr 2026 15:37:41 -0400 Subject: [PATCH] Remove need for GetSourceForItem --- .../ItemDatabaseTests.cs | 25 ----- .../DatFile.Splitting.cs | 30 +++--- SabreTools.Metadata.DatFiles/DatFile.cs | 18 ++-- SabreTools.Metadata.DatFiles/ItemDatabase.cs | 100 ++++++++---------- 4 files changed, 65 insertions(+), 108 deletions(-) diff --git a/SabreTools.Metadata.DatFiles.Test/ItemDatabaseTests.cs b/SabreTools.Metadata.DatFiles.Test/ItemDatabaseTests.cs index d25085fd..08cea068 100644 --- a/SabreTools.Metadata.DatFiles.Test/ItemDatabaseTests.cs +++ b/SabreTools.Metadata.DatFiles.Test/ItemDatabaseTests.cs @@ -565,31 +565,6 @@ namespace SabreTools.Metadata.DatFiles.Test #endregion - #region GetSourceForItem - - [Fact] - public void GetSourceForItemTest() - { - Source source = new Source(0, source: null); - Machine machine = new Machine(); - DatItem item = new Rom(); - - var dict = new ItemDatabase(); - - long sourceIndex = dict.AddSource(source); - item.SourceIndex = sourceIndex; - long machineIndex = dict.AddMachine(machine); - item.MachineIndex = machineIndex; - - long itemIndex = dict.AddItem(item, statsOnly: false); - - var actual = dict.GetSourceForItem(itemIndex); - Assert.Equal(0, actual.Key); - Assert.NotNull(actual.Value); - } - - #endregion - #region RemoveBucket [Fact] diff --git a/SabreTools.Metadata.DatFiles/DatFile.Splitting.cs b/SabreTools.Metadata.DatFiles/DatFile.Splitting.cs index f195e46d..6d4bc291 100644 --- a/SabreTools.Metadata.DatFiles/DatFile.Splitting.cs +++ b/SabreTools.Metadata.DatFiles/DatFile.Splitting.cs @@ -421,7 +421,7 @@ namespace SabreTools.Metadata.DatFiles foreach (var item in items) { // Get the source for the current item - var source = GetSourceForItemDB(item.Key); + var source = ItemsDB.GetSource(item.Value.SourceIndex); // Get the parent items and current machine name Dictionary parentItems = GetItemsForBucketDB(cloneOf); @@ -451,7 +451,6 @@ namespace SabreTools.Metadata.DatFiles .Contains(mergeTag)) { item.Value.MachineIndex = cloneOfMachine.Key; - item.Value.SourceIndex = source.Key; ItemsDB.AddItemInternal(item.Value); } @@ -462,7 +461,6 @@ namespace SabreTools.Metadata.DatFiles .Contains(disk.Name)) { item.Value.MachineIndex = cloneOfMachine.Key; - item.Value.SourceIndex = source.Key; ItemsDB.AddItemInternal(item.Value); } } @@ -491,7 +489,6 @@ namespace SabreTools.Metadata.DatFiles rom.Name = $"{machineName}\\{rom.Name}"; item.Value.MachineIndex = cloneOfMachine.Key; - item.Value.SourceIndex = source.Key; ItemsDB.AddItemInternal(item.Value); } @@ -502,7 +499,6 @@ namespace SabreTools.Metadata.DatFiles rom.Name = $"{machineName}\\{rom.Name}"; item.Value.MachineIndex = cloneOfMachine.Key; - item.Value.SourceIndex = source.Key; ItemsDB.AddItemInternal(item.Value); } } @@ -514,7 +510,6 @@ namespace SabreTools.Metadata.DatFiles item.Value.SetName($"{machineName}\\{item.Value.GetName()}"); item.Value.MachineIndex = cloneOfMachine.Key; - item.Value.SourceIndex = source.Key; ItemsDB.AddItemInternal(item.Value); } @@ -593,7 +588,7 @@ namespace SabreTools.Metadata.DatFiles continue; // Get the source for the first item - var source = GetSourceForItemDB(items.First().Key); + var source = ItemsDB.GetSource(items.First().Value.SourceIndex); // Get the machine for the first item in the list var machine = GetMachineForItemDB(items.First().Key); @@ -615,7 +610,7 @@ namespace SabreTools.Metadata.DatFiles { DatItem datItem = (DatItem)item.Value.Clone(); datItem.MachineIndex = machine.Key; - datItem.SourceIndex = source.Key; + datItem.SourceIndex = item.Value.SourceIndex; if (items.Values.Any(i => i.GetName()?.ToLowerInvariant() == datItem.GetName()?.ToLowerInvariant()) && items.Values.Any(i => i == datItem)) @@ -816,10 +811,11 @@ namespace SabreTools.Metadata.DatFiles continue; // Get the source for the first item - var source = GetSourceForItemDB(items.First().Key); + var firstItem = items.First(); + var source = ItemsDB.GetSource(firstItem.Value.SourceIndex); // Get the machine for the first item - var machine = GetMachineForItemDB(items.First().Key); + var machine = GetMachineForItemDB(firstItem.Key); if (machine.Value is null) continue; @@ -883,7 +879,7 @@ namespace SabreTools.Metadata.DatFiles // Clone the item and then add it DatItem datItem = (DatItem)item.Clone(); datItem.MachineIndex = machine.Key; - datItem.SourceIndex = source.Key; + datItem.SourceIndex = item.SourceIndex; ItemsDB.AddItemInternal(datItem); } @@ -898,7 +894,7 @@ namespace SabreTools.Metadata.DatFiles var deviceRef = new DeviceRef { MachineIndex = machine.Key, - SourceIndex = source.Key, + SourceIndex = firstItem.Value.SourceIndex, Name = deviceReference, }; @@ -947,7 +943,7 @@ namespace SabreTools.Metadata.DatFiles // Clone the item and then add it DatItem datItem = (DatItem)item.Clone(); datItem.MachineIndex = machine.Key; - datItem.SourceIndex = source.Key; + datItem.SourceIndex = item.SourceIndex; ItemsDB.AddItemInternal(datItem); } @@ -962,14 +958,14 @@ namespace SabreTools.Metadata.DatFiles var slotOptionItem = new SlotOption { MachineIndex = machine.Key, - SourceIndex = source.Key, + SourceIndex = firstItem.Value.SourceIndex, DevName = slotOption, }; var slotItem = new Slot { MachineIndex = machine.Key, - SourceIndex = source.Key, + SourceIndex = firstItem.Value.SourceIndex, SlotOption = [slotOptionItem], }; @@ -1040,7 +1036,7 @@ namespace SabreTools.Metadata.DatFiles continue; // Get the source for the first item - var source = GetSourceForItemDB(items.First().Key); + var source = ItemsDB.GetSource(items.First().Value.SourceIndex); // Get the machine for the first item var machine = GetMachineForItemDB(items.First().Key); @@ -1058,7 +1054,7 @@ namespace SabreTools.Metadata.DatFiles { DatItem datItem = (DatItem)item.Value.Clone(); datItem.MachineIndex = machine.Key; - datItem.SourceIndex = source.Key; + datItem.SourceIndex = item.Value.SourceIndex; if (items.Any(i => i.Value.GetName() == datItem.GetName()) && items.Any(i => i.Value == datItem)) diff --git a/SabreTools.Metadata.DatFiles/DatFile.cs b/SabreTools.Metadata.DatFiles/DatFile.cs index cd14cfb9..e10fd35b 100644 --- a/SabreTools.Metadata.DatFiles/DatFile.cs +++ b/SabreTools.Metadata.DatFiles/DatFile.cs @@ -277,12 +277,6 @@ namespace SabreTools.Metadata.DatFiles public KeyValuePair GetMachineForItemDB(long itemIndex) => ItemsDB.GetMachineForItem(itemIndex); - /// - /// Get the index and source associated with an item index - /// - public KeyValuePair GetSourceForItemDB(long itemIndex) - => ItemsDB.GetSourceForItem(itemIndex); - /// /// Remove a key from the file dictionary if it exists /// @@ -882,14 +876,14 @@ namespace SabreTools.Metadata.DatFiles ?? string.Empty; // Get sources for both items - var datItemSource = ItemsDB.GetSourceForItem(datItem.Key); - var lastItemSource = ItemsDB.GetSourceForItem(lastItem.Value.Key); + var datItemSource = ItemsDB.GetSource(datItem.Value.SourceIndex); + var lastItemSource = ItemsDB.GetSource(lastItem.Value.Value.SourceIndex); // If the current item exactly matches the last item, then we don't add it #if NET20 || NET35 - if ((ItemsDB.GetDuplicateStatus(datItem, datItemSource.Value, lastItem, lastItemSource.Value) & DupeType.All) != 0) + if ((ItemsDB.GetDuplicateStatus(datItem, datItemSource, lastItem, lastItemSource) & DupeType.All) != 0) #else - if (ItemsDB.GetDuplicateStatus(datItem, datItemSource.Value, lastItem, lastItemSource.Value).HasFlag(DupeType.All)) + if (ItemsDB.GetDuplicateStatus(datItem, datItemSource, lastItem, lastItemSource).HasFlag(DupeType.All)) #endif { _logger.Verbose($"Exact duplicate found for '{datItemName}'"); @@ -1202,8 +1196,8 @@ namespace SabreTools.Metadata.DatFiles // Compare on source if renaming if (!norename) { - int xSourceIndex = ItemsDB.GetSourceForItem(x.Key).Value?.Index ?? 0; - int ySourceIndex = ItemsDB.GetSourceForItem(y.Key).Value?.Index ?? 0; + int xSourceIndex = ItemsDB.GetSource(x.Value.SourceIndex)?.Index ?? 0; + int ySourceIndex = ItemsDB.GetSource(y.Value.SourceIndex)?.Index ?? 0; if (xSourceIndex != ySourceIndex) return xSourceIndex - ySourceIndex; } diff --git a/SabreTools.Metadata.DatFiles/ItemDatabase.cs b/SabreTools.Metadata.DatFiles/ItemDatabase.cs index 9a6261fb..085b8a72 100644 --- a/SabreTools.Metadata.DatFiles/ItemDatabase.cs +++ b/SabreTools.Metadata.DatFiles/ItemDatabase.cs @@ -1,4 +1,4 @@ -#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER +#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER using System.Collections.Concurrent; #endif using System.Collections.Generic; @@ -317,6 +317,17 @@ namespace SabreTools.Metadata.DatFiles } } + /// + /// Get a item based on the index + /// + public DatItem? GetItem(long index) + { + if (_items.TryGetValue(index, out var item)) + return item; + + return null; + } + /// /// Get all items and their indicies /// @@ -402,21 +413,6 @@ namespace SabreTools.Metadata.DatFiles return null; } - /// - /// Get the index and source associated with an item index - /// - public KeyValuePair GetSourceForItem(long itemIndex) - { - if (!_items.TryGetValue(itemIndex, out var item)) - return new KeyValuePair(-1, null); - - long sourceIndex = item.SourceIndex; - if (!_sources.TryGetValue(sourceIndex, out var source)) - return new KeyValuePair(-1, null); - - return new KeyValuePair(sourceIndex, source); - } - /// /// Get all sources and their indicies /// @@ -531,7 +527,7 @@ namespace SabreTools.Metadata.DatFiles DatStatistics.AddItemStatistics(item); // Add the item to the default bucket - PerformItemBucketing(index, _bucketedBy, lower: true, norename: true); + PerformItemBucketing(new KeyValuePair(index, item), _bucketedBy, lower: true, norename: true); // Return the used index return index; @@ -660,8 +656,8 @@ namespace SabreTools.Metadata.DatFiles // We want to get the proper key for the DatItem, ignoring the index _ = SortAndGetKey(datItem, sorted); var machine = GetMachineForItem(datItem.Key); - var source = GetSourceForItem(datItem.Key); - string key = datItem.Value.GetKey(_bucketedBy, machine.Value, source.Value); + var source = GetSource(datItem.Value.SourceIndex); + string key = datItem.Value.GetKey(_bucketedBy, machine.Value, source); // If the key doesn't exist, return the empty list var items = GetItemsForBucket(key); @@ -703,8 +699,8 @@ namespace SabreTools.Metadata.DatFiles // We want to get the proper key for the DatItem, ignoring the index _ = SortAndGetKey(datItem, sorted); var machine = GetMachineForItem(datItem.Key); - var source = GetSourceForItem(datItem.Key); - string key = datItem.Value.GetKey(_bucketedBy, machine.Value, source.Value); + var source = GetSource(datItem.Value.SourceIndex); + string key = datItem.Value.GetKey(_bucketedBy, machine.Value, source); // If the key doesn't exist var roms = GetItemsForBucket(key); @@ -761,11 +757,11 @@ namespace SabreTools.Metadata.DatFiles } // Find the index of the first duplicate, if one exists - var datItemSource = GetSourceForItem(itemIndex); + var datItemSource = GetSource(datItem.SourceIndex); int pos = output.FindIndex(lastItem => { - var lastItemSource = GetSourceForItem(lastItem.Key); - return GetDuplicateStatus(kvp, datItemSource.Value, lastItem, lastItemSource.Value) != 0x00; + var lastItemSource = GetSource(lastItem.Value.SourceIndex); + return GetDuplicateStatus(kvp, datItemSource, lastItem, lastItemSource) != 0x00; }); if (pos < 0) { @@ -776,8 +772,8 @@ namespace SabreTools.Metadata.DatFiles // Get the duplicate item long savedIndex = output[pos].Key; DatItem savedItem = output[pos].Value; - var savedItemSource = GetSourceForItem(savedIndex); - DupeType dupetype = GetDuplicateStatus(kvp, datItemSource.Value, output[pos], savedItemSource.Value); + var savedItemSource = GetSource(savedItem.SourceIndex); + DupeType dupetype = GetDuplicateStatus(kvp, datItemSource, output[pos], savedItemSource); // Disks, Media, and Roms have more information to fill if (datItem is Disk diskItem && savedItem is Disk savedDisk) @@ -792,8 +788,8 @@ namespace SabreTools.Metadata.DatFiles savedItem.DupeType = dupetype; // Get the sources associated with the items - var savedSource = _sources[GetSourceForItem(savedIndex).Key]; - var itemSource = _sources[GetSourceForItem(itemIndex).Key]; + var savedSource = GetSource(savedItem.SourceIndex); + var itemSource = GetSource(datItem.SourceIndex); // Get the machines associated with the items var savedMachine = GetMachineForItem(savedIndex); @@ -886,34 +882,22 @@ namespace SabreTools.Metadata.DatFiles /// /// Get the bucketing key for a given item index - /// Index of the current item + /// Current item /// ItemKey value representing what key to get /// True if the key should be lowercased, false otherwise /// True if games should only be compared on game and file name, false if system and source are counted /// - private string GetBucketKey(long itemIndex, ItemKey bucketBy, bool lower, bool norename) + private string GetBucketKey(KeyValuePair datItem, ItemKey bucketBy, bool lower, bool norename) { -#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER - if (!_items.TryGetValue(itemIndex, out var datItem) || datItem is null) - return string.Empty; -#else - if (!_items.ContainsKey(itemIndex)) - return string.Empty; - - var datItem = _items[itemIndex]; - if (datItem is null) - return string.Empty; -#endif - - var source = GetSourceForItem(itemIndex); - var machine = GetMachineForItem(itemIndex); + var source = GetSource(datItem.Value.SourceIndex); + var machine = GetMachine(datItem.Value.MachineIndex); // Treat NULL like machine if (bucketBy == ItemKey.NULL) bucketBy = ItemKey.Machine; // Get the bucket key - return datItem.GetKey(bucketBy, machine.Value, source.Value, lower, norename); + return datItem.Value.GetKey(bucketBy, machine, source, lower, norename); } /// @@ -937,7 +921,15 @@ namespace SabreTools.Metadata.DatFiles for (int i = 0; i < itemIndicies.Length; i++) #endif { - PerformItemBucketing(i, bucketBy, lower, norename); + var datItem = GetItem(i); + if (datItem is null) +#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER + return; +#else + continue; +#endif + + PerformItemBucketing(new KeyValuePair(i, datItem), bucketBy, lower, norename); #if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER }); #else @@ -948,13 +940,13 @@ namespace SabreTools.Metadata.DatFiles /// /// Bucket a single DatItem /// - /// Index of the item to bucket + /// Item to bucket /// ItemKey enum representing how to bucket the individual items /// True if the key should be lowercased, false otherwise /// True if games should only be compared on game and file name, false if system and source are counted - private void PerformItemBucketing(long itemIndex, ItemKey bucketBy, bool lower, bool norename) + private void PerformItemBucketing(KeyValuePair datItem, ItemKey bucketBy, bool lower, bool norename) { - string? bucketKey = GetBucketKey(itemIndex, bucketBy, lower, norename); + string? bucketKey = GetBucketKey(datItem, bucketBy, lower, norename); lock (bucketKey) { // If the key is missing from the dictionary, add it @@ -969,9 +961,9 @@ namespace SabreTools.Metadata.DatFiles if (!_buckets.TryGetValue(bucketKey, out var bucket) || bucket is null) return; - bucket.Add(itemIndex); + bucket.Add(datItem.Key); #else - _buckets[bucketKey].Add(itemIndex); + _buckets[bucketKey].Add(datItem.Key); #endif } } @@ -1039,8 +1031,8 @@ namespace SabreTools.Metadata.DatFiles // Compare on source if renaming if (!norename) { - int xSourceIndex = GetSourceForItem(x.Key).Value?.Index ?? 0; - int ySourceIndex = GetSourceForItem(y.Key).Value?.Index ?? 0; + int xSourceIndex = GetSource(x.Value.SourceIndex)?.Index ?? 0; + int ySourceIndex = GetSource(y.Value.SourceIndex)?.Index ?? 0; if (xSourceIndex != ySourceIndex) return xSourceIndex - ySourceIndex; } @@ -1095,7 +1087,7 @@ namespace SabreTools.Metadata.DatFiles BucketBy(GetBestAvailable()); // Now that we have the sorted type, we get the proper key - return GetBucketKey(datItem.Key, _bucketedBy, lower: true, norename: true); + return GetBucketKey(datItem, _bucketedBy, lower: true, norename: true); } #endregion