diff --git a/SabreTools.DatFiles/ItemDictionary.cs b/SabreTools.DatFiles/ItemDictionary.cs index 0c90938f..d157556f 100644 --- a/SabreTools.DatFiles/ItemDictionary.cs +++ b/SabreTools.DatFiles/ItemDictionary.cs @@ -553,7 +553,7 @@ namespace SabreTools.DatFiles PerformSorting(); } } - + /// /// List all duplicates found in a DAT based on a DatItem /// @@ -684,41 +684,41 @@ namespace SabreTools.DatFiles List oldkeys = [.. Keys]; #if NET452_OR_GREATER || NETCOREAPP - Parallel.For(0, oldkeys.Count, Globals.ParallelOptions, k => + Parallel.For(0, oldkeys.Count, Globals.ParallelOptions, k => #elif NET40_OR_GREATER Parallel.For(0, oldkeys.Count, k => #else for (int k = 0; k < oldkeys.Count; k++) #endif + { + string key = oldkeys[k]; + if (this[key] == null) + Remove(key); + + // Now add each of the roms to their respective keys + for (int i = 0; i < this[key]!.Count; i++) { - string key = oldkeys[k]; - if (this[key] == null) - Remove(key); + DatItem item = this[key]![i]; + if (item == null) + continue; - // Now add each of the roms to their respective keys - for (int i = 0; i < this[key]!.Count; i++) + // We want to get the key most appropriate for the given sorting type + string newkey = item.GetKey(bucketBy, lower, norename); + + // If the key is different, move the item to the new key + if (newkey != key) { - DatItem item = this[key]![i]; - if (item == null) - continue; - - // We want to get the key most appropriate for the given sorting type - string newkey = item.GetKey(bucketBy, lower, norename); - - // If the key is different, move the item to the new key - if (newkey != key) - { - Add(newkey, item); - Remove(key, item); - i--; // This make sure that the pointer stays on the correct since one was removed - } + Add(newkey, item); + Remove(key, item); + i--; // This make sure that the pointer stays on the correct since one was removed } + } - // If the key is now empty, remove it - if (this[key]!.Count == 0) - Remove(key); + // If the key is now empty, remove it + if (this[key]!.Count == 0) + Remove(key); #if NET40_OR_GREATER || NETCOREAPP - }); + }); #else } #endif @@ -736,34 +736,34 @@ namespace SabreTools.DatFiles List keys = [.. Keys]; #if NET452_OR_GREATER || NETCOREAPP - Parallel.ForEach(keys, Globals.ParallelOptions, key => + Parallel.ForEach(keys, Globals.ParallelOptions, key => #elif NET40_OR_GREATER Parallel.ForEach(keys, key => #else foreach (var key in keys) #endif - { - // Get the possibly unsorted list - ConcurrentList? sortedlist = this[key]?.ToConcurrentList(); - if (sortedlist == null) + { + // Get the possibly unsorted list + ConcurrentList? sortedlist = this[key]?.ToConcurrentList(); + if (sortedlist == null) #if NET40_OR_GREATER || NETCOREAPP - return; + return; #else continue; #endif - // Sort the list of items to be consistent - DatItem.Sort(ref sortedlist, false); + // Sort the list of items to be consistent + DatItem.Sort(ref sortedlist, false); - // If we're merging the roms, do so - if (dedupeType == DedupeType.Full || (dedupeType == DedupeType.Game && bucketBy == ItemKey.Machine)) - sortedlist = DatItem.Merge(sortedlist); + // If we're merging the roms, do so + if (dedupeType == DedupeType.Full || (dedupeType == DedupeType.Game && bucketBy == ItemKey.Machine)) + sortedlist = DatItem.Merge(sortedlist); - // Add the list back to the dictionary - Reset(key); - AddRange(key, sortedlist); + // Add the list back to the dictionary + Reset(key); + AddRange(key, sortedlist); #if NET40_OR_GREATER || NETCOREAPP - }); + }); #else } #endif @@ -776,21 +776,21 @@ namespace SabreTools.DatFiles { List keys = [.. Keys]; #if NET452_OR_GREATER || NETCOREAPP - Parallel.ForEach(keys, Globals.ParallelOptions, key => + Parallel.ForEach(keys, Globals.ParallelOptions, key => #elif NET40_OR_GREATER Parallel.ForEach(keys, key => #else foreach (var key in keys) #endif - { - // Get the possibly unsorted list - ConcurrentList? sortedlist = this[key]; + { + // Get the possibly unsorted list + ConcurrentList? sortedlist = this[key]; - // Sort the list of items to be consistent - if (sortedlist != null) - DatItem.Sort(ref sortedlist, false); + // Sort the list of items to be consistent + if (sortedlist != null) + DatItem.Sort(ref sortedlist, false); #if NET40_OR_GREATER || NETCOREAPP - }); + }); #else } #endif @@ -867,89 +867,13 @@ namespace SabreTools.DatFiles { // First we want to get a mapping for all games to description #if NET40_OR_GREATER || NETCOREAPP - ConcurrentDictionary mapping = new(); + ConcurrentDictionary mapping = CreateMachineToDescriptionMapping(); #else - Dictionary mapping = []; -#endif -#if NET452_OR_GREATER || NETCOREAPP - Parallel.ForEach(Keys, Globals.ParallelOptions, key => -#elif NET40_OR_GREATER - Parallel.ForEach(Keys, key => -#else - foreach (var key in Keys) -#endif - { - var items = this[key]; - if (items == null) -#if NET40_OR_GREATER || NETCOREAPP - return; -#else - continue; -#endif - - foreach (DatItem item in items) - { - // If the key mapping doesn't exist, add it -#if NET40_OR_GREATER || NETCOREAPP - mapping.TryAdd(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -")); -#else - mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!] = item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -"); -#endif - } -#if NET40_OR_GREATER || NETCOREAPP - }); -#else - } + Dictionary mapping = CreateMachineToDescriptionMapping(); #endif // Now we loop through every item and update accordingly -#if NET452_OR_GREATER || NETCOREAPP - Parallel.ForEach(Keys, Globals.ParallelOptions, key => -#elif NET40_OR_GREATER - Parallel.ForEach(Keys, key => -#else - foreach (var key in Keys) -#endif - { - var items = this[key]; - if (items == null) -#if NET40_OR_GREATER || NETCOREAPP - return; -#else - continue; -#endif - - ConcurrentList newItems = []; - foreach (DatItem item in items) - { - // Update machine name - if (!string.IsNullOrEmpty(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)) && mapping.ContainsKey(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!)) - item.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.NameKey, mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!]); - - // Update cloneof - if (!string.IsNullOrEmpty(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)) && mapping.ContainsKey(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!)) - item.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.CloneOfKey, mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!]); - - // Update romof - if (!string.IsNullOrEmpty(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)) && mapping.ContainsKey(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!)) - item.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.RomOfKey, mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!]); - - // Update sampleof - if (!string.IsNullOrEmpty(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)) && mapping.ContainsKey(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!)) - item.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.SampleOfKey, mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!]); - - // Add the new item to the output list - newItems.Add(item); - } - - // Replace the old list of roms with the new one - Remove(key); - AddRange(key, newItems); -#if NET40_OR_GREATER || NETCOREAPP - }); -#else - } -#endif + UpdateMachineNamesFromDescriptions(mapping); } catch (Exception ex) when (!throwOnError) { @@ -1036,6 +960,56 @@ namespace SabreTools.DatFiles #endif } + /// + /// Create machine to description mapping dictionary + /// +#if NET40_OR_GREATER || NETCOREAPP + private ConcurrentDictionary CreateMachineToDescriptionMapping() +#else + private Dictionary CreateMachineToDescriptionMapping() +#endif + { +#if NET40_OR_GREATER || NETCOREAPP + ConcurrentDictionary mapping = new(); +#else + Dictionary mapping = []; +#endif +#if NET452_OR_GREATER || NETCOREAPP + Parallel.ForEach(Keys, Globals.ParallelOptions, key => +#elif NET40_OR_GREATER + Parallel.ForEach(Keys, key => +#else + foreach (var key in Keys) +#endif + { + var items = this[key]; + if (items == null) +#if NET40_OR_GREATER || NETCOREAPP + return; +#else + continue; +#endif + + foreach (DatItem item in items) + { + // If the key mapping doesn't exist, add it +#if NET40_OR_GREATER || NETCOREAPP + mapping.TryAdd(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, + item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -")); +#else + mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!] + = item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -"); +#endif + } +#if NET40_OR_GREATER || NETCOREAPP + }); +#else + } +#endif + + return mapping; + } + /// /// Set internal names to match One Rom Per Game (ORPG) logic /// @@ -1054,6 +1028,64 @@ namespace SabreTools.DatFiles datItem.SetName(Path.GetFileName(datItem.GetName())); } + /// + /// Update machine names from descriptions according to mappings + /// +#if NET40_OR_GREATER || NETCOREAPP + private void UpdateMachineNamesFromDescriptions(ConcurrentDictionary mapping) +#else + private void UpdateMachineNamesFromDescriptions(Dictionary mapping) +#endif + { +#if NET452_OR_GREATER || NETCOREAPP + Parallel.ForEach(Keys, Globals.ParallelOptions, key => +#elif NET40_OR_GREATER + Parallel.ForEach(Keys, key => +#else + foreach (var key in Keys) +#endif + { + var items = this[key]; + if (items == null) +#if NET40_OR_GREATER || NETCOREAPP + return; +#else + continue; +#endif + + ConcurrentList newItems = []; + foreach (DatItem item in items) + { + // Update machine name + if (!string.IsNullOrEmpty(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)) && mapping.ContainsKey(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!)) + item.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.NameKey, mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!]); + + // Update cloneof + if (!string.IsNullOrEmpty(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)) && mapping.ContainsKey(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!)) + item.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.CloneOfKey, mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!]); + + // Update romof + if (!string.IsNullOrEmpty(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)) && mapping.ContainsKey(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!)) + item.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.RomOfKey, mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!]); + + // Update sampleof + if (!string.IsNullOrEmpty(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)) && mapping.ContainsKey(item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!)) + item.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.SampleOfKey, mapping[item.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!]); + + // Add the new item to the output list + newItems.Add(item); + } + + // Replace the old list of roms with the new one + Remove(key); + AddRange(key, newItems); +#if NET40_OR_GREATER || NETCOREAPP + }); +#else + } +#endif + } + #endregion #region Statistics diff --git a/SabreTools.DatFiles/ItemDictionaryDB.cs b/SabreTools.DatFiles/ItemDictionaryDB.cs index 036f2831..9ed4e3ea 100644 --- a/SabreTools.DatFiles/ItemDictionaryDB.cs +++ b/SabreTools.DatFiles/ItemDictionaryDB.cs @@ -928,90 +928,13 @@ namespace SabreTools.DatFiles { // First we want to get a mapping for all games to description #if NET40_OR_GREATER || NETCOREAPP - ConcurrentDictionary mapping = new(); + ConcurrentDictionary mapping = CreateMachineToDescriptionMapping(); #else - Dictionary mapping = []; -#endif -#if NET452_OR_GREATER || NETCOREAPP - Parallel.ForEach(SortedKeys, Globals.ParallelOptions, key => -#elif NET40_OR_GREATER - Parallel.ForEach(SortedKeys, key => -#else - foreach (var key in SortedKeys) -#endif - { - var items = GetDatItemsForBucket(key); - if (items == null) -#if NET40_OR_GREATER || NETCOREAPP - return; -#else - continue; -#endif - - foreach ((long, DatItem) item in items) - { - // If the key mapping doesn't exist, add it -#if NET40_OR_GREATER || NETCOREAPP - mapping.TryAdd(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, - item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -")); -#else - mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!] - = item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -"); -#endif - } -#if NET40_OR_GREATER || NETCOREAPP - }); -#else - } + Dictionary mapping = CreateMachineToDescriptionMapping(); #endif // Now we loop through every item and update accordingly -#if NET452_OR_GREATER || NETCOREAPP - Parallel.ForEach(SortedKeys, Globals.ParallelOptions, key => -#elif NET40_OR_GREATER - Parallel.ForEach(SortedKeys, key => -#else - foreach (var key in SortedKeys) -#endif - { - var items = GetDatItemsForBucket(key); - if (items == null) -#if NET40_OR_GREATER || NETCOREAPP - return; -#else - continue; -#endif - - ConcurrentList<(long, DatItem)> newItems = []; - foreach ((long, DatItem) item in items) - { - // Update machine name - if (!string.IsNullOrEmpty(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)) && mapping.ContainsKey(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!)) - item.Item2.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.NameKey, mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!]); - - // Update cloneof - if (!string.IsNullOrEmpty(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)) && mapping.ContainsKey(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!)) - item.Item2.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.CloneOfKey, mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!]); - - // Update romof - if (!string.IsNullOrEmpty(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)) && mapping.ContainsKey(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!)) - item.Item2.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.RomOfKey, mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!]); - - // Update sampleof - if (!string.IsNullOrEmpty(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)) && mapping.ContainsKey(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!)) - item.Item2.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.SampleOfKey, mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!]); - - // Add the new item to the output list - newItems.Add(item); - } - - // Replace the old list of roms with the new one - _buckets[key] = newItems.Select(i => i.Item1).ToConcurrentList(); -#if NET40_OR_GREATER || NETCOREAPP - }); -#else - } -#endif + UpdateMachineNamesFromDescriptions(mapping); } catch (Exception ex) when (!throwOnError) { @@ -1097,6 +1020,56 @@ namespace SabreTools.DatFiles #endif } + /// + /// Create machine to description mapping dictionary + /// +#if NET40_OR_GREATER || NETCOREAPP + private ConcurrentDictionary CreateMachineToDescriptionMapping() +#else + private Dictionary CreateMachineToDescriptionMapping() +#endif + { +#if NET40_OR_GREATER || NETCOREAPP + ConcurrentDictionary mapping = new(); +#else + Dictionary mapping = []; +#endif +#if NET452_OR_GREATER || NETCOREAPP + Parallel.ForEach(SortedKeys, Globals.ParallelOptions, key => +#elif NET40_OR_GREATER + Parallel.ForEach(SortedKeys, key => +#else + foreach (var key in SortedKeys) +#endif + { + var items = GetDatItemsForBucket(key); + if (items == null) +#if NET40_OR_GREATER || NETCOREAPP + return; +#else + continue; +#endif + + foreach ((long, DatItem) item in items) + { + // If the key mapping doesn't exist, add it +#if NET40_OR_GREATER || NETCOREAPP + mapping.TryAdd(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!, + item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -")); +#else + mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!] + = item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.DescriptionKey)!.Replace('/', '_').Replace("\"", "''").Replace(":", " -"); +#endif + } +#if NET40_OR_GREATER || NETCOREAPP + }); +#else + } +#endif + + return mapping; + } + /// /// Execute all filters in a filter runner on a single bucket /// @@ -1138,6 +1111,63 @@ namespace SabreTools.DatFiles datItem.Item2.SetName(Path.GetFileName(datItem.Item2.GetName())); } + /// + /// Update machine names from descriptions according to mappings + /// +#if NET40_OR_GREATER || NETCOREAPP + private void UpdateMachineNamesFromDescriptions(ConcurrentDictionary mapping) +#else + private void UpdateMachineNamesFromDescriptions(Dictionary mapping) +#endif + { +#if NET452_OR_GREATER || NETCOREAPP + Parallel.ForEach(SortedKeys, Globals.ParallelOptions, key => +#elif NET40_OR_GREATER + Parallel.ForEach(SortedKeys, key => +#else + foreach (var key in SortedKeys) +#endif + { + var items = GetDatItemsForBucket(key); + if (items == null) +#if NET40_OR_GREATER || NETCOREAPP + return; +#else + continue; +#endif + + ConcurrentList<(long, DatItem)> newItems = []; + foreach ((long, DatItem) item in items) + { + // Update machine name + if (!string.IsNullOrEmpty(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)) && mapping.ContainsKey(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!)) + item.Item2.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.NameKey, mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.NameKey)!]); + + // Update cloneof + if (!string.IsNullOrEmpty(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)) && mapping.ContainsKey(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!)) + item.Item2.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.CloneOfKey, mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey)!]); + + // Update romof + if (!string.IsNullOrEmpty(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)) && mapping.ContainsKey(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!)) + item.Item2.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.RomOfKey, mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.RomOfKey)!]); + + // Update sampleof + if (!string.IsNullOrEmpty(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)) && mapping.ContainsKey(item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!)) + item.Item2.GetFieldValue(DatItem.MachineKey)!.SetFieldValue(Models.Metadata.Machine.SampleOfKey, mapping[item.Item2.GetFieldValue(DatItem.MachineKey)!.GetStringFieldValue(Models.Metadata.Machine.SampleOfKey)!]); + + // Add the new item to the output list + newItems.Add(item); + } + + // Replace the old list of roms with the new one + _buckets[key] = newItems.Select(i => i.Item1).ToConcurrentList(); +#if NET40_OR_GREATER || NETCOREAPP + }); +#else + } +#endif + } + #endregion #region Statistics