fix(parser): dedupe HPE AHS DIMM inventory per slot, newest snapshot wins
The AHS blackbox stores a DIMM inventory snapshot per POST cycle and parseDIMMs flattens all of them. dedupeMemory keyed on serial, so a slot whose module was swapped between captures survived once per historical occupant — a 24-slot board reported 26 modules and "same P/N" vs "mixed P/N" configs looked identical. dedupeMemory now collapses to one entry per non-empty slot with the last (most recent, since token order follows chronological blackbox-record order) occurrence winning. Slotless entries keep the serial/part fallback. See ADL-060. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
99d8f098ac
commit
632067fef5
+20
-1
@@ -1045,11 +1045,30 @@ func dedupeCPUs(items []models.CPU) []models.CPU {
|
||||
return out
|
||||
}
|
||||
|
||||
// dedupeMemory collapses the DIMM inventory to one entry per physical slot.
|
||||
//
|
||||
// The AHS blackbox carries a separate inventory snapshot for every POST cycle,
|
||||
// and parseDIMMs walks all of them. When a module is swapped between captures the
|
||||
// same slot shows up with different serials; keying the dedupe on serial alone
|
||||
// (as an earlier version did) let every historical occupant survive, inflating
|
||||
// the module count. Tokens are appended in blackbox-record order, which is
|
||||
// chronological, so the last occurrence for a slot is the most recent snapshot
|
||||
// and wins. Entries without a slot label fall back to serial-based dedupe.
|
||||
func dedupeMemory(items []models.MemoryDIMM) []models.MemoryDIMM {
|
||||
slotIndex := make(map[string]int)
|
||||
seen := make(map[string]bool)
|
||||
out := make([]models.MemoryDIMM, 0, len(items))
|
||||
for _, item := range items {
|
||||
key := valueOr(item.SerialNumber, item.Slot+"|"+item.PartNumber)
|
||||
if item.Slot != "" {
|
||||
if idx, ok := slotIndex[item.Slot]; ok {
|
||||
out[idx] = item
|
||||
continue
|
||||
}
|
||||
slotIndex[item.Slot] = len(out)
|
||||
out = append(out, item)
|
||||
continue
|
||||
}
|
||||
key := valueOr(item.SerialNumber, item.PartNumber)
|
||||
if seen[key] {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user