@@ -133,9 +133,38 @@ func generateMockDBLabelValues(size int) []*metadbmodel.PrometheusLabelValue {
133133 return mockData
134134}
135135
136- // newTestLabel 创建一个不依赖 DB 的 label 实例
136+ // newTestLabel 创建一个不依赖 DB 的 label 实例,同时创建配套的 labelName/labelValue
137137func newTestLabel () * label {
138- return newLabel (nil )
138+ ln := newTestLabelName ()
139+ lv := newTestLabelValue ()
140+ return newLabel (nil , ln , lv )
141+ }
142+
143+ // newTestLabelWithRefs 返回 label 及其内部引用的 labelName/labelValue
144+ func newTestLabelWithRefs () (* label , * labelName , * labelValue ) {
145+ ln := newTestLabelName ()
146+ lv := newTestLabelValue ()
147+ l := newLabel (nil , ln , lv )
148+ return l , ln , lv
149+ }
150+
151+ // populateLabelDeps ensures labelName and labelValue contain entries matching
152+ // the naming pattern used by generateProtoLabels ("label_name_i" / "label_value_i").
153+ func populateLabelDeps (l * label , n int ) {
154+ lnBatch := make ([]* controller.PrometheusLabelName , n )
155+ lvBatch := make ([]* controller.PrometheusLabelValue , n )
156+ for i := 0 ; i < n ; i ++ {
157+ lnBatch [i ] = & controller.PrometheusLabelName {
158+ Name : proto .String (fmt .Sprintf ("label_name_%d" , i )),
159+ Id : proto .Uint32 (uint32 (i + 1 )),
160+ }
161+ lvBatch [i ] = & controller.PrometheusLabelValue {
162+ Value : proto .String (fmt .Sprintf ("label_value_%d" , i )),
163+ Id : proto .Uint32 (uint32 (i + 1 )),
164+ }
165+ }
166+ l .labelName .Add (lnBatch )
167+ l .labelValue .Add (lvBatch )
139168}
140169
141170func newTestMetricName () * metricName {
@@ -161,10 +190,10 @@ func countLabelConcurrentMap(m map[LabelKey]int) int {
161190 return len (m )
162191}
163192
164- func buildLabelConcurrentMap (n int ) map [LabelKey ]int {
165- m := make (map [LabelKey ]int , n )
193+ func buildLabelConcurrentMap (n int ) map [IDLabelKey ]int {
194+ m := make (map [IDLabelKey ]int , n )
166195 for i := 0 ; i < n ; i ++ {
167- m [NewLabelKey ( fmt . Sprintf ( "label_name_%d" , i ), fmt . Sprintf ( "label_value_%d" , i )) ] = i + 1
196+ m [IDLabelKey { NameID : i + 1 , ValueID : i + 1 } ] = i + 1
168197 }
169198 return m
170199}
@@ -176,9 +205,9 @@ func buildLabelValueMap(n int) map[string]int {
176205 return m
177206}
178207
179- func resetLabelState (l * label , active map [LabelKey ]int ) {
208+ func resetLabelState (l * label , active map [IDLabelKey ]int ) {
180209 l .mu .Lock ()
181- l .pending = make (map [LabelKey ]int )
210+ l .pending = make (map [IDLabelKey ]int )
182211 l .mu .Unlock ()
183212 l .replaceActive (active )
184213}
@@ -268,7 +297,10 @@ func refreshLabelEntriesCurrent(l *label, entries []labelRefreshEntry) {
268297 l .mu .Lock ()
269298 defer l .mu .Unlock ()
270299 for _ , entry := range entries {
271- l .pending [entry .key ] = entry .id
300+ idk , ok := l .toIDKey (entry .key )
301+ if ok {
302+ l .pending [idk ] = entry .id
303+ }
272304 }
273305}
274306func refreshLabelValueEntriesCurrent (lv * labelValue , entries []labelValueRefreshEntry ) {
@@ -326,6 +358,7 @@ func benchmarkProtoRefreshSizes() []int {
326358func TestLabel_AddAndGet (t * testing.T ) {
327359 l := newTestLabel ()
328360 batch := generateProtoLabels (100 )
361+ populateLabelDeps (l , 100 )
329362
330363 l .Add (batch )
331364
@@ -401,6 +434,7 @@ func TestLayout_AddAndGet(t *testing.T) {
401434
402435func TestLabel_GetKeyToID_SnapshotIsolation (t * testing.T ) {
403436 l := newTestLabel ()
437+ populateLabelDeps (l , 101 )
404438 l .Add (generateProtoLabels (100 ))
405439
406440 // 取快照
@@ -411,6 +445,9 @@ func TestLabel_GetKeyToID_SnapshotIsolation(t *testing.T) {
411445 extra := []* controller.PrometheusLabel {
412446 {Name : proto .String ("extra_name" ), Value : proto .String ("extra_value" ), Id : proto .Uint32 (999 )},
413447 }
448+ // Populate deps for extra entry
449+ l .labelName .Add ([]* controller.PrometheusLabelName {{Name : proto .String ("extra_name" ), Id : proto .Uint32 (102 )}})
450+ l .labelValue .Add ([]* controller.PrometheusLabelValue {{Value : proto .String ("extra_value" ), Id : proto .Uint32 (102 )}})
414451 l .Add (extra )
415452
416453 // 快照不受影响
@@ -468,6 +505,7 @@ func TestLabelValue_GetValueToID_SnapshotIsolation(t *testing.T) {
468505
469506func TestLabel_SnapshotSwap_DiscardsOldEntries (t * testing.T ) {
470507 l := newTestLabel ()
508+ populateLabelDeps (l , 200 )
471509
472510 // 初始加载 200 条
473511 l .Add (generateProtoLabels (200 ))
@@ -516,6 +554,7 @@ func TestLabelValue_SnapshotSwap_DiscardsOldEntries(t *testing.T) {
516554
517555func TestConcurrentLabel_ReadDuringSwap (t * testing.T ) {
518556 l := newTestLabel ()
557+ populateLabelDeps (l , 1000 )
519558 l .Add (generateProtoLabels (1000 ))
520559
521560 const (
@@ -740,6 +779,7 @@ func TestConcurrentLayout_ReadDuringSwap(t *testing.T) {
740779
741780func TestConcurrentLabel_SnapshotDuringSwap (t * testing.T ) {
742781 l := newTestLabel ()
782+ populateLabelDeps (l , 500 )
743783 l .Add (generateProtoLabels (500 ))
744784
745785 var wg sync.WaitGroup
@@ -785,13 +825,14 @@ func TestLabel_LargeScale_MemoryRelease(t *testing.T) {
785825 const N = 1_000_000
786826
787827 l := newTestLabel ()
828+ populateLabelDeps (l , N )
788829
789830 // 阶段1:加载百万条数据
790831 batch := make ([]* controller.PrometheusLabel , N )
791832 for i := 0 ; i < N ; i ++ {
792833 batch [i ] = & controller.PrometheusLabel {
793- Name : proto .String (fmt .Sprintf ("n_ %d" , i )),
794- Value : proto .String (fmt .Sprintf ("v_ %d" , i )),
834+ Name : proto .String (fmt .Sprintf ("label_name_ %d" , i )),
835+ Value : proto .String (fmt .Sprintf ("label_value_ %d" , i )),
795836 Id : proto .Uint32 (uint32 (i + 1 )),
796837 }
797838 }
@@ -806,9 +847,9 @@ func TestLabel_LargeScale_MemoryRelease(t *testing.T) {
806847
807848 // 阶段2:模拟 refresh——只保留 10% 的数据(模拟 Cleaner 删除后 refresh)
808849 kept := N / 10
809- newMap := make (map [LabelKey ]int , kept )
850+ newMap := make (map [IDLabelKey ]int , kept )
810851 for i := 0 ; i < kept ; i ++ {
811- newMap [NewLabelKey ( fmt . Sprintf ( "n_%d" , i ), fmt . Sprintf ( "v_%d" , i )) ] = i + 1
852+ newMap [IDLabelKey { NameID : i + 1 , ValueID : i + 1 } ] = i + 1
812853 }
813854 resetLabelState (l , newMap )
814855
@@ -893,6 +934,7 @@ func BenchmarkLabel_Add(b *testing.B) {
893934 b .Run (fmt .Sprintf ("n=%d" , size ), func (b * testing.B ) {
894935 for i := 0 ; i < b .N ; i ++ {
895936 l := newTestLabel ()
937+ populateLabelDeps (l , size )
896938 l .Add (batch )
897939 }
898940 })
@@ -902,6 +944,7 @@ func BenchmarkLabel_Add(b *testing.B) {
902944func BenchmarkLabel_GetIDByKey (b * testing.B ) {
903945 for _ , size := range benchmarkLabelLookupSizes () {
904946 l := newTestLabel ()
947+ populateLabelDeps (l , size )
905948 l .Add (generateProtoLabels (size ))
906949 keys := generateLabelKeys (size )
907950
@@ -919,6 +962,7 @@ func BenchmarkLabel_GetIDByKey(b *testing.B) {
919962func BenchmarkLabel_GetKeyToID_Snapshot (b * testing.B ) {
920963 for _ , size := range []int {1000 , 10_000 , 100_000 } {
921964 l := newTestLabel ()
965+ populateLabelDeps (l , size )
922966 l .Add (generateProtoLabels (size ))
923967
924968 b .Run (fmt .Sprintf ("n=%d" , size ), func (b * testing.B ) {
@@ -934,9 +978,9 @@ func BenchmarkLabel_SnapshotSwap(b *testing.B) {
934978 b .Run (fmt .Sprintf ("n=%d" , size ), func (b * testing.B ) {
935979 l := newTestLabel ()
936980 for i := 0 ; i < b .N ; i ++ {
937- newMap := make (map [LabelKey ]int , size )
981+ newMap := make (map [IDLabelKey ]int , size )
938982 for j := 0 ; j < size ; j ++ {
939- newMap [NewLabelKey ( fmt . Sprintf ( "n_%d" , j ), fmt . Sprintf ( "v_%d" , j )) ] = j + 1
983+ newMap [IDLabelKey { NameID : j + 1 , ValueID : j + 1 } ] = j + 1
940984 }
941985 resetLabelState (l , newMap )
942986 }
@@ -948,11 +992,13 @@ func BenchmarkLabel_Refresh(b *testing.B) {
948992 for _ , size := range benchmarkRefreshSizes () {
949993 b .Run (fmt .Sprintf ("n=%d" , size ), func (b * testing.B ) {
950994 l := newTestLabel ()
951- mockData := generateMockDBLabels (size )
995+ populateLabelDeps (l , size )
996+ batch := generateProtoLabels (size )
952997
953998 b .ResetTimer ()
954999 for i := 0 ; i < b .N ; i ++ {
955- l .processLoadedData (mockData )
1000+ l .Add (batch )
1001+ resetLabelState (l , make (map [IDLabelKey ]int ))
9561002 }
9571003 })
9581004 }
@@ -1062,6 +1108,16 @@ func BenchmarkLayout_GetIndexByKey(b *testing.B) {
10621108func BenchmarkLabel_MixedReadWrite (b * testing.B ) {
10631109 for _ , size := range []int {10_000 , 100_000 } {
10641110 l := newTestLabel ()
1111+ populateLabelDeps (l , size )
1112+ // Pre-populate deps for "hot" entries used in write path
1113+ hotLN := make ([]* controller.PrometheusLabelName , 100 )
1114+ hotLV := make ([]* controller.PrometheusLabelValue , 100 )
1115+ for i := 0 ; i < 100 ; i ++ {
1116+ hotLN [i ] = & controller.PrometheusLabelName {Name : proto .String (fmt .Sprintf ("hot_%d" , i )), Id : proto .Uint32 (uint32 (size + i + 1 ))}
1117+ hotLV [i ] = & controller.PrometheusLabelValue {Value : proto .String (fmt .Sprintf ("hot_v_%d" , i )), Id : proto .Uint32 (uint32 (size + i + 1 ))}
1118+ }
1119+ l .labelName .Add (hotLN )
1120+ l .labelValue .Add (hotLV )
10651121 l .Add (generateProtoLabels (size ))
10661122 keys := generateLabelKeys (size )
10671123
0 commit comments