From f51a1c04920bd8a2a8d45203e0d9f02ba4ae7bbe Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 12 Sep 2023 16:38:41 +0200 Subject: [PATCH] De-duplicate fingerprints and icons --- profile/fingerprint.go | 20 ++++++++++++++++++-- profile/icon.go | 10 +++++++++- profile/merge.go | 4 ++-- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/profile/fingerprint.go b/profile/fingerprint.go index d84f5fa2..a3e6ff02 100644 --- a/profile/fingerprint.go +++ b/profile/fingerprint.go @@ -368,7 +368,7 @@ const ( func deriveProfileID(fps []Fingerprint) string { // Sort the fingerprints. - sortFingerprints(fps) + sortAndCompactFingerprints(fps) // Compile data for hashing. c := container.New(nil) @@ -398,7 +398,8 @@ func deriveProfileID(fps []Fingerprint) string { return h.Base58() } -func sortFingerprints(fps []Fingerprint) { +func sortAndCompactFingerprints(fps []Fingerprint) []Fingerprint { + // Sort. slices.SortFunc[[]Fingerprint, Fingerprint](fps, func(a, b Fingerprint) int { switch { case a.Type != b.Type: @@ -415,4 +416,19 @@ func sortFingerprints(fps []Fingerprint) { return 0 } }) + + // De-duplicate. + // Important: Even if the fingerprint is the same, but MergedFrom is + // different, we need to keep the separate fingerprint, so that new installs + // will cleanly update to the synced state: Auto-generated profiles need to + // be automatically replaced by the merged version. + fps = slices.CompactFunc[[]Fingerprint, Fingerprint](fps, func(a, b Fingerprint) bool { + return a.Type == b.Type && + a.Key == b.Key && + a.Operation == b.Operation && + a.Value == b.Value && + a.MergedFrom == b.MergedFrom + }) + + return fps } diff --git a/profile/icon.go b/profile/icon.go index 7ced8a33..0d002825 100644 --- a/profile/icon.go +++ b/profile/icon.go @@ -35,7 +35,8 @@ func (t IconType) sortOrder() int { } } -func sortIcons(icons []Icon) { +func sortAndCompactIcons(icons []Icon) []Icon { + // Sort. slices.SortFunc[[]Icon, Icon](icons, func(a, b Icon) int { aOrder := a.Type.sortOrder() bOrder := b.Type.sortOrder() @@ -49,4 +50,11 @@ func sortIcons(icons []Icon) { return 0 } }) + + // De-duplicate. + icons = slices.CompactFunc[[]Icon, Icon](icons, func(a, b Icon) bool { + return a.Type == b.Type && a.Value == b.Value + }) + + return icons } diff --git a/profile/merge.go b/profile/merge.go index 2a734a2a..581ba07e 100644 --- a/profile/merge.go +++ b/profile/merge.go @@ -32,7 +32,7 @@ func MergeProfiles(primary *Profile, secondaries ...*Profile) (newProfile *Profi for _, sp := range secondaries { newProfile.Icons = append(newProfile.Icons, sp.Icons...) } - sortIcons(newProfile.Icons) + newProfile.Icons = sortAndCompactIcons(newProfile.Icons) // Collect all fingerprints. newProfile.Fingerprints = make([]Fingerprint, 0, len(secondaries)+1) // Guess the needed space. @@ -40,7 +40,7 @@ func MergeProfiles(primary *Profile, secondaries ...*Profile) (newProfile *Profi for _, sp := range secondaries { newProfile.Fingerprints = addFingerprints(newProfile.Fingerprints, sp.Fingerprints, sp.ScopedID()) } - sortFingerprints(newProfile.Fingerprints) + newProfile.Fingerprints = sortAndCompactFingerprints(newProfile.Fingerprints) // Save new profile. newProfile = New(newProfile)