From d5462c6909b3eabdfbb1453a68196a8774787772 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 4 Mar 2024 23:17:13 -0500 Subject: [PATCH] Simplify status count statistics --- SabreTools.DatFiles/ItemDictionary.cs | 136 ++++++++++++------- SabreTools.DatFiles/ItemDictionaryDB.cs | 134 +++++++++++------- SabreTools.Reports/Formats/Html.cs | 4 +- SabreTools.Reports/Formats/SeparatedValue.cs | 4 +- SabreTools.Reports/Formats/Textfile.cs | 4 +- 5 files changed, 173 insertions(+), 109 deletions(-) diff --git a/SabreTools.DatFiles/ItemDictionary.cs b/SabreTools.DatFiles/ItemDictionary.cs index 47c53fc4..ef283e93 100644 --- a/SabreTools.DatFiles/ItemDictionary.cs +++ b/SabreTools.DatFiles/ItemDictionary.cs @@ -118,28 +118,16 @@ namespace SabreTools.DatFiles public long TotalSize { get; private set; } = 0; /// - /// Number of hashes for each hash type + /// Number of items for each hash type /// [JsonIgnore, XmlIgnore] public Dictionary HashCounts { get; private set; } = []; /// - /// Number of items with the baddump status + /// Number of items for each item status /// [JsonIgnore, XmlIgnore] - public long BaddumpCount { get; private set; } = 0; - - /// - /// Number of items with the good status - /// - [JsonIgnore, XmlIgnore] - public long GoodCount { get; private set; } = 0; - - /// - /// Number of items with the nodump status - /// - [JsonIgnore, XmlIgnore] - public long NodumpCount { get; private set; } = 0; + public Dictionary StatusCounts { get; private set; } = []; /// /// Number of items with the remove flag @@ -147,12 +135,6 @@ namespace SabreTools.DatFiles [JsonIgnore, XmlIgnore] public long RemovedCount { get; private set; } = 0; - /// - /// Number of items with the verified status - /// - [JsonIgnore, XmlIgnore] - public long VerifiedCount { get; private set; } = 0; - #endregion #endregion @@ -250,10 +232,10 @@ namespace SabreTools.DatFiles AddHashCount(Hash.SHA1, string.IsNullOrEmpty(disk.SHA1) ? 0 : 1); } - BaddumpCount += (disk.ItemStatus == ItemStatus.BadDump ? 1 : 0); - GoodCount += (disk.ItemStatus == ItemStatus.Good ? 1 : 0); - NodumpCount += (disk.ItemStatus == ItemStatus.Nodump ? 1 : 0); - VerifiedCount += (disk.ItemStatus == ItemStatus.Verified ? 1 : 0); + AddStatusCount(ItemStatus.BadDump, disk.ItemStatus == ItemStatus.BadDump ? 1 : 0); + AddStatusCount(ItemStatus.Good, disk.ItemStatus == ItemStatus.Good ? 1 : 0); + AddStatusCount(ItemStatus.Nodump, disk.ItemStatus == ItemStatus.Nodump ? 1 : 0); + AddStatusCount(ItemStatus.Verified, disk.ItemStatus == ItemStatus.Verified ? 1 : 0); break; case Media media: AddHashCount(Hash.MD5, string.IsNullOrEmpty(media.MD5) ? 0 : 1); @@ -274,10 +256,10 @@ namespace SabreTools.DatFiles AddHashCount(Hash.SpamSum, string.IsNullOrEmpty(rom.SpamSum) ? 0 : 1); } - BaddumpCount += (rom.ItemStatus == ItemStatus.BadDump ? 1 : 0); - GoodCount += (rom.ItemStatus == ItemStatus.Good ? 1 : 0); - NodumpCount += (rom.ItemStatus == ItemStatus.Nodump ? 1 : 0); - VerifiedCount += (rom.ItemStatus == ItemStatus.Verified ? 1 : 0); + AddStatusCount(ItemStatus.BadDump, rom.ItemStatus == ItemStatus.BadDump ? 1 : 0); + AddStatusCount(ItemStatus.Good, rom.ItemStatus == ItemStatus.Good ? 1 : 0); + AddStatusCount(ItemStatus.Nodump, rom.ItemStatus == ItemStatus.Nodump ? 1 : 0); + AddStatusCount(ItemStatus.Verified, rom.ItemStatus == ItemStatus.Verified ? 1 : 0); break; } } @@ -336,11 +318,12 @@ namespace SabreTools.DatFiles } // Individual status counts - BaddumpCount += stats.BaddumpCount; - GoodCount += stats.GoodCount; - NodumpCount += stats.NodumpCount; + foreach (var statusCountKvp in stats.StatusCounts) + { + AddStatusCount(statusCountKvp.Key, statusCountKvp.Value); + } + RemovedCount += stats.RemovedCount; - VerifiedCount += stats.VerifiedCount; } /// @@ -530,10 +513,10 @@ namespace SabreTools.DatFiles RemoveHashCount(Hash.SHA1, string.IsNullOrEmpty(disk.SHA1) ? 0 : 1); } - BaddumpCount -= (disk.ItemStatus == ItemStatus.BadDump ? 1 : 0); - GoodCount -= (disk.ItemStatus == ItemStatus.Good ? 1 : 0); - NodumpCount -= (disk.ItemStatus == ItemStatus.Nodump ? 1 : 0); - VerifiedCount -= (disk.ItemStatus == ItemStatus.Verified ? 1 : 0); + RemoveStatusCount(ItemStatus.BadDump, disk.ItemStatus == ItemStatus.BadDump ? 1 : 0); + RemoveStatusCount(ItemStatus.Good, disk.ItemStatus == ItemStatus.Good ? 1 : 0); + RemoveStatusCount(ItemStatus.Nodump, disk.ItemStatus == ItemStatus.Nodump ? 1 : 0); + RemoveStatusCount(ItemStatus.Verified, disk.ItemStatus == ItemStatus.Verified ? 1 : 0); break; case Media media: RemoveHashCount(Hash.MD5, string.IsNullOrEmpty(media.MD5) ? 0 : 1); @@ -554,10 +537,10 @@ namespace SabreTools.DatFiles RemoveHashCount(Hash.SpamSum, string.IsNullOrEmpty(rom.SpamSum) ? 0 : 1); } - BaddumpCount -= (rom.ItemStatus == ItemStatus.BadDump ? 1 : 0); - GoodCount -= (rom.ItemStatus == ItemStatus.Good ? 1 : 0); - NodumpCount -= (rom.ItemStatus == ItemStatus.Nodump ? 1 : 0); - VerifiedCount -= (rom.ItemStatus == ItemStatus.Verified ? 1 : 0); + RemoveStatusCount(ItemStatus.BadDump, rom.ItemStatus == ItemStatus.BadDump ? 1 : 0); + RemoveStatusCount(ItemStatus.Good, rom.ItemStatus == ItemStatus.Good ? 1 : 0); + RemoveStatusCount(ItemStatus.Nodump, rom.ItemStatus == ItemStatus.Nodump ? 1 : 0); + RemoveStatusCount(ItemStatus.Verified, rom.ItemStatus == ItemStatus.Verified ? 1 : 0); break; } } @@ -595,6 +578,22 @@ namespace SabreTools.DatFiles } } + /// + /// Get the item count for a given item status, defaulting to 0 if it does not exist + /// + /// Item status to retrieve + /// The number of items of that type, if it exists + public long GetStatusCount(ItemStatus itemStatus) + { + lock (StatusCounts) + { + if (!StatusCounts.ContainsKey(itemStatus)) + return 0; + + return StatusCounts[itemStatus]; + } + } + /// /// Increment the hash count for a given hash type /// @@ -667,6 +666,42 @@ namespace SabreTools.DatFiles } } + /// + /// Increment the item count for a given item status + /// + /// Item type to increment + /// Amount to increment by, defaults to 1 + private void AddStatusCount(ItemStatus itemStatus, long interval = 1) + { + lock (StatusCounts) + { + if (!StatusCounts.ContainsKey(itemStatus)) + StatusCounts[itemStatus] = 0; + + StatusCounts[itemStatus] += interval; + if (StatusCounts[itemStatus] < 0) + StatusCounts[itemStatus] = 0; + } + } + + /// + /// Decrement the item count for a given item status + /// + /// Item type to decrement + /// Amount to increment by, defaults to 1 + private void RemoveStatusCount(ItemStatus itemStatus, long interval = 1) + { + lock (StatusCounts) + { + if (!StatusCounts.ContainsKey(itemStatus)) + return; + + StatusCounts[itemStatus] -= interval; + if (StatusCounts[itemStatus] < 0) + StatusCounts[itemStatus] = 0; + } + } + #endregion #region Constructors @@ -984,12 +1019,8 @@ namespace SabreTools.DatFiles GameCount = 0; TotalSize = 0; HashCounts = []; - - BaddumpCount = 0; - GoodCount = 0; - NodumpCount = 0; + StatusCounts = []; RemovedCount = 0; - VerifiedCount = 0; } /// @@ -997,29 +1028,30 @@ namespace SabreTools.DatFiles /// private ItemKey GetBestAvailable() { - // Get the item counts for the 3 hashable types + // Get the required counts long diskCount = GetItemCount(ItemType.Disk); long mediaCount = GetItemCount(ItemType.Media); long romCount = GetItemCount(ItemType.Rom); + long nodumpCount = GetStatusCount(ItemStatus.Nodump); // If all items are supposed to have a SHA-512, we bucket by that - if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.SHA512)) + if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.SHA512)) return ItemKey.SHA512; // If all items are supposed to have a SHA-384, we bucket by that - else if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.SHA384)) + else if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.SHA384)) return ItemKey.SHA384; // If all items are supposed to have a SHA-256, we bucket by that - else if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.SHA256)) + else if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.SHA256)) return ItemKey.SHA256; // If all items are supposed to have a SHA-1, we bucket by that - else if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.SHA1)) + else if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.SHA1)) return ItemKey.SHA1; // If all items are supposed to have a MD5, we bucket by that - else if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.MD5)) + else if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.MD5)) return ItemKey.MD5; // Otherwise, we bucket by CRC diff --git a/SabreTools.DatFiles/ItemDictionaryDB.cs b/SabreTools.DatFiles/ItemDictionaryDB.cs index acf5f4d3..5985f53c 100644 --- a/SabreTools.DatFiles/ItemDictionaryDB.cs +++ b/SabreTools.DatFiles/ItemDictionaryDB.cs @@ -182,22 +182,10 @@ namespace SabreTools.DatFiles public Dictionary HashCounts { get; private set; } = []; /// - /// Number of items with the baddump status + /// Number of items for each item status /// [JsonIgnore, XmlIgnore] - public long BaddumpCount { get; private set; } = 0; - - /// - /// Number of items with the good status - /// - [JsonIgnore, XmlIgnore] - public long GoodCount { get; private set; } = 0; - - /// - /// Number of items with the nodump status - /// - [JsonIgnore, XmlIgnore] - public long NodumpCount { get; private set; } = 0; + public Dictionary StatusCounts { get; private set; } = []; /// /// Number of items with the remove flag @@ -205,12 +193,6 @@ namespace SabreTools.DatFiles [JsonIgnore, XmlIgnore] public long RemovedCount { get; private set; } = 0; - /// - /// Number of items with the verified status - /// - [JsonIgnore, XmlIgnore] - public long VerifiedCount { get; private set; } = 0; - #endregion #endregion @@ -369,10 +351,10 @@ namespace SabreTools.DatFiles AddHashCount(Hash.SHA1, string.IsNullOrEmpty(disk.SHA1) ? 0 : 1); } - BaddumpCount += (disk.ItemStatus == ItemStatus.BadDump ? 1 : 0); - GoodCount += (disk.ItemStatus == ItemStatus.Good ? 1 : 0); - NodumpCount += (disk.ItemStatus == ItemStatus.Nodump ? 1 : 0); - VerifiedCount += (disk.ItemStatus == ItemStatus.Verified ? 1 : 0); + AddStatusCount(ItemStatus.BadDump, disk.ItemStatus == ItemStatus.BadDump ? 1 : 0); + AddStatusCount(ItemStatus.Good, disk.ItemStatus == ItemStatus.Good ? 1 : 0); + AddStatusCount(ItemStatus.Nodump, disk.ItemStatus == ItemStatus.Nodump ? 1 : 0); + AddStatusCount(ItemStatus.Verified, disk.ItemStatus == ItemStatus.Verified ? 1 : 0); break; case Media media: AddHashCount(Hash.MD5, string.IsNullOrEmpty(media.MD5) ? 0 : 1); @@ -393,10 +375,10 @@ namespace SabreTools.DatFiles AddHashCount(Hash.SpamSum, string.IsNullOrEmpty(rom.SpamSum) ? 0 : 1); } - BaddumpCount += (rom.ItemStatus == ItemStatus.BadDump ? 1 : 0); - GoodCount += (rom.ItemStatus == ItemStatus.Good ? 1 : 0); - NodumpCount += (rom.ItemStatus == ItemStatus.Nodump ? 1 : 0); - VerifiedCount += (rom.ItemStatus == ItemStatus.Verified ? 1 : 0); + AddStatusCount(ItemStatus.BadDump, rom.ItemStatus == ItemStatus.BadDump ? 1 : 0); + AddStatusCount(ItemStatus.Good, rom.ItemStatus == ItemStatus.Good ? 1 : 0); + AddStatusCount(ItemStatus.Nodump, rom.ItemStatus == ItemStatus.Nodump ? 1 : 0); + AddStatusCount(ItemStatus.Verified, rom.ItemStatus == ItemStatus.Verified ? 1 : 0); break; } } @@ -458,11 +440,12 @@ namespace SabreTools.DatFiles } // Individual status counts - BaddumpCount += stats.BaddumpCount; - GoodCount += stats.GoodCount; - NodumpCount += stats.NodumpCount; + foreach (var statusCountKvp in stats.StatusCounts) + { + AddStatusCount(statusCountKvp.Key, statusCountKvp.Value); + } + RemovedCount += stats.RemovedCount; - VerifiedCount += stats.VerifiedCount; } /// @@ -676,10 +659,10 @@ namespace SabreTools.DatFiles RemoveHashCount(Hash.SHA1, string.IsNullOrEmpty(disk.SHA1) ? 0 : 1); } - BaddumpCount -= (disk.ItemStatus == ItemStatus.BadDump ? 1 : 0); - GoodCount -= (disk.ItemStatus == ItemStatus.Good ? 1 : 0); - NodumpCount -= (disk.ItemStatus == ItemStatus.Nodump ? 1 : 0); - VerifiedCount -= (disk.ItemStatus == ItemStatus.Verified ? 1 : 0); + RemoveStatusCount(ItemStatus.BadDump, disk.ItemStatus == ItemStatus.BadDump ? 1 : 0); + RemoveStatusCount(ItemStatus.Good, disk.ItemStatus == ItemStatus.Good ? 1 : 0); + RemoveStatusCount(ItemStatus.Nodump, disk.ItemStatus == ItemStatus.Nodump ? 1 : 0); + RemoveStatusCount(ItemStatus.Verified, disk.ItemStatus == ItemStatus.Verified ? 1 : 0); break; case Media media: RemoveHashCount(Hash.MD5, string.IsNullOrEmpty(media.MD5) ? 0 : 1); @@ -700,10 +683,10 @@ namespace SabreTools.DatFiles RemoveHashCount(Hash.SpamSum, string.IsNullOrEmpty(rom.SpamSum) ? 0 : 1); } - BaddumpCount -= (rom.ItemStatus == ItemStatus.BadDump ? 1 : 0); - GoodCount -= (rom.ItemStatus == ItemStatus.Good ? 1 : 0); - NodumpCount -= (rom.ItemStatus == ItemStatus.Nodump ? 1 : 0); - VerifiedCount -= (rom.ItemStatus == ItemStatus.Verified ? 1 : 0); + RemoveStatusCount(ItemStatus.BadDump, rom.ItemStatus == ItemStatus.BadDump ? 1 : 0); + RemoveStatusCount(ItemStatus.Good, rom.ItemStatus == ItemStatus.Good ? 1 : 0); + RemoveStatusCount(ItemStatus.Nodump, rom.ItemStatus == ItemStatus.Nodump ? 1 : 0); + RemoveStatusCount(ItemStatus.Verified, rom.ItemStatus == ItemStatus.Verified ? 1 : 0); break; } } @@ -741,6 +724,22 @@ namespace SabreTools.DatFiles } } + /// + /// Get the item count for a given item status, defaulting to 0 if it does not exist + /// + /// Item status to retrieve + /// The number of items of that type, if it exists + public long GetStatusCount(ItemStatus itemStatus) + { + lock (StatusCounts) + { + if (!StatusCounts.ContainsKey(itemStatus)) + return 0; + + return StatusCounts[itemStatus]; + } + } + /// /// Increment the hash count for a given hash type /// @@ -813,6 +812,42 @@ namespace SabreTools.DatFiles } } + /// + /// Increment the item count for a given item status + /// + /// Item type to increment + /// Amount to increment by, defaults to 1 + private void AddStatusCount(ItemStatus itemStatus, long interval = 1) + { + lock (StatusCounts) + { + if (!StatusCounts.ContainsKey(itemStatus)) + StatusCounts[itemStatus] = 0; + + StatusCounts[itemStatus] += interval; + if (StatusCounts[itemStatus] < 0) + StatusCounts[itemStatus] = 0; + } + } + + /// + /// Decrement the item count for a given item status + /// + /// Item type to decrement + /// Amount to increment by, defaults to 1 + private void RemoveStatusCount(ItemStatus itemStatus, long interval = 1) + { + lock (StatusCounts) + { + if (!StatusCounts.ContainsKey(itemStatus)) + return; + + StatusCounts[itemStatus] -= interval; + if (StatusCounts[itemStatus] < 0) + StatusCounts[itemStatus] = 0; + } + } + #endregion #region Constructors @@ -1155,12 +1190,8 @@ CREATE TABLE IF NOT EXISTS groups ( GameCount = 0; TotalSize = 0; HashCounts = []; - - BaddumpCount = 0; - GoodCount = 0; - NodumpCount = 0; + StatusCounts = []; RemovedCount = 0; - VerifiedCount = 0; } /// @@ -1168,29 +1199,30 @@ CREATE TABLE IF NOT EXISTS groups ( /// private ItemKey GetBestAvailable() { - // Get the item counts for the 3 hashable types + // Get the required counts long diskCount = GetItemCount(ItemType.Disk); long mediaCount = GetItemCount(ItemType.Media); long romCount = GetItemCount(ItemType.Rom); + long nodumpCount = GetStatusCount(ItemStatus.Nodump); // If all items are supposed to have a SHA-512, we bucket by that - if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.SHA512)) + if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.SHA512)) return ItemKey.SHA512; // If all items are supposed to have a SHA-384, we bucket by that - else if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.SHA384)) + else if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.SHA384)) return ItemKey.SHA384; // If all items are supposed to have a SHA-256, we bucket by that - else if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.SHA256)) + else if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.SHA256)) return ItemKey.SHA256; // If all items are supposed to have a SHA-1, we bucket by that - else if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.SHA1)) + else if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.SHA1)) return ItemKey.SHA1; // If all items are supposed to have a MD5, we bucket by that - else if (diskCount + mediaCount + romCount - NodumpCount == GetHashCount(Hash.MD5)) + else if (diskCount + mediaCount + romCount - nodumpCount == GetHashCount(Hash.MD5)) return ItemKey.MD5; // Otherwise, we bucket by CRC diff --git a/SabreTools.Reports/Formats/Html.cs b/SabreTools.Reports/Formats/Html.cs index 9e54f296..8c24baaf 100644 --- a/SabreTools.Reports/Formats/Html.cs +++ b/SabreTools.Reports/Formats/Html.cs @@ -269,7 +269,7 @@ body { { xtw.WriteStartElement("td"); xtw.WriteAttributeString("align", "right"); - xtw.WriteString(stat.Statistics.BaddumpCount.ToString()); + xtw.WriteString(stat.Statistics.GetStatusCount(Core.ItemStatus.BadDump).ToString()); xtw.WriteEndElement(); // td } @@ -277,7 +277,7 @@ body { { xtw.WriteStartElement("td"); xtw.WriteAttributeString("align", "right"); - xtw.WriteString(stat.Statistics.NodumpCount.ToString()); + xtw.WriteString(stat.Statistics.GetStatusCount(Core.ItemStatus.Nodump).ToString()); xtw.WriteEndElement(); // td } diff --git a/SabreTools.Reports/Formats/SeparatedValue.cs b/SabreTools.Reports/Formats/SeparatedValue.cs index 23fac8de..1f9a9a85 100644 --- a/SabreTools.Reports/Formats/SeparatedValue.cs +++ b/SabreTools.Reports/Formats/SeparatedValue.cs @@ -139,8 +139,8 @@ namespace SabreTools.Reports.Formats stat.Statistics.GetHashCount(Core.Hash.SHA256).ToString(), stat.Statistics.GetHashCount(Core.Hash.SHA384).ToString(), stat.Statistics.GetHashCount(Core.Hash.SHA512).ToString(), - baddumpCol ? stat.Statistics.BaddumpCount.ToString() : string.Empty, - nodumpCol ? stat.Statistics.NodumpCount.ToString() : string.Empty, + baddumpCol ? stat.Statistics.GetStatusCount(Core.ItemStatus.BadDump).ToString() : string.Empty, + nodumpCol ? stat.Statistics.GetStatusCount(Core.ItemStatus.Nodump).ToString() : string.Empty, ]; svw.WriteValues(values); svw.Flush(); diff --git a/SabreTools.Reports/Formats/Textfile.cs b/SabreTools.Reports/Formats/Textfile.cs index 82151941..0eb9056a 100644 --- a/SabreTools.Reports/Formats/Textfile.cs +++ b/SabreTools.Reports/Formats/Textfile.cs @@ -103,10 +103,10 @@ namespace SabreTools.Reports.Formats Roms with SHA-512: " + stat.Statistics.GetHashCount(Core.Hash.SHA512) + "\n"; if (baddumpCol) - line += " Roms with BadDump status: " + stat.Statistics.BaddumpCount + "\n"; + line += " Roms with BadDump status: " + stat.Statistics.GetStatusCount(Core.ItemStatus.BadDump) + "\n"; if (nodumpCol) - line += " Roms with Nodump status: " + stat.Statistics.NodumpCount + "\n"; + line += " Roms with Nodump status: " + stat.Statistics.GetStatusCount(Core.ItemStatus.Nodump) + "\n"; // For spacing between DATs line += "\n\n";