From d71a1a34df216ff54cd1002edb6d4eb37af0b18d Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Tue, 20 Feb 2024 17:04:58 +0800 Subject: [PATCH] core: fix datarace in MergeLabels (#7537) (#7830) close tikv/pd#7535 Signed-off-by: lhy1024 Co-authored-by: lhy1024 --- pkg/core/store.go | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/pkg/core/store.go b/pkg/core/store.go index 1d3362cac0e..9b660754496 100644 --- a/pkg/core/store.go +++ b/pkg/core/store.go @@ -600,22 +600,36 @@ func DistinctScore(labels []string, stores []*StoreInfo, other *StoreInfo) float return score } -// MergeLabels merges the passed in labels with origins, overriding duplicated -// ones. +// MergeLabels merges the passed in labels with origins, overriding duplicated ones. +// Note: To prevent potential data races, it is advisable to refrain from directly modifying the 'origin' variable. func MergeLabels(origin []*metapb.StoreLabel, labels []*metapb.StoreLabel) []*metapb.StoreLabel { - storeLabels := origin -L: + results := make([]*metapb.StoreLabel, 0, len(origin)) + for _, label := range origin { + results = append(results, &metapb.StoreLabel{ + Key: label.Key, + Value: label.Value, + }) + } + for _, newLabel := range labels { - for _, label := range storeLabels { + found := false + for _, label := range results { if strings.EqualFold(label.Key, newLabel.Key) { + // Update the value for an existing key. label.Value = newLabel.Value - continue L + found = true + break } } - storeLabels = append(storeLabels, newLabel) + // Add a new label if the key doesn't exist in the original slice. + if !found { + results = append(results, newLabel) + } } - res := storeLabels[:0] - for _, l := range storeLabels { + + // Filter out labels with an empty value. + res := results[:0] + for _, l := range results { if l.Value != "" { res = append(res, l) }