github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/cloud/metainfo/info_test.go (about)

     1  // Copyright 2021 ByteDance Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package metainfo_test
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"testing"
    21  
    22  	"github.com/bytedance/gopkg/cloud/metainfo"
    23  )
    24  
    25  func TestWithValue(t *testing.T) {
    26  	ctx := context.Background()
    27  
    28  	k, v := "Key", "Value"
    29  	ctx = metainfo.WithValue(ctx, k, v)
    30  	assert(t, ctx != nil)
    31  
    32  	x, ok := metainfo.GetValue(ctx, k)
    33  	assert(t, ok)
    34  	assert(t, x == v)
    35  }
    36  
    37  func TestWithValues(t *testing.T) {
    38  	ctx := context.Background()
    39  
    40  	k, v := "Key-0", "Value-0"
    41  	ctx = metainfo.WithValue(ctx, k, v)
    42  
    43  	kvs := []string{"Key-1", "Value-1", "Key-2", "Value-2", "Key-3", "Value-3"}
    44  	ctx = metainfo.WithValues(ctx, kvs...)
    45  	assert(t, ctx != nil)
    46  
    47  	for i := 0; i <= 3; i++ {
    48  		x, ok := metainfo.GetValue(ctx, fmt.Sprintf("Key-%d", i))
    49  		assert(t, ok)
    50  		assert(t, x == fmt.Sprintf("Value-%d", i))
    51  	}
    52  }
    53  
    54  func TestWithPersistValues(t *testing.T) {
    55  	ctx := context.Background()
    56  
    57  	k, v := "Key-0", "Value-0"
    58  	ctx = metainfo.WithPersistentValue(ctx, k, v)
    59  
    60  	kvs := []string{"Key-1", "Value-1", "Key-2", "Value-2", "Key-3", "Value-3"}
    61  	ctx = metainfo.WithPersistentValues(ctx, kvs...)
    62  	assert(t, ctx != nil)
    63  
    64  	for i := 0; i <= 3; i++ {
    65  		x, ok := metainfo.GetPersistentValue(ctx, fmt.Sprintf("Key-%d", i))
    66  		assert(t, ok)
    67  		assert(t, x == fmt.Sprintf("Value-%d", i))
    68  	}
    69  }
    70  
    71  func TestWithEmpty(t *testing.T) {
    72  	ctx := context.Background()
    73  
    74  	k, v := "Key", "Value"
    75  	ctx = metainfo.WithValue(ctx, k, "")
    76  	assert(t, ctx != nil)
    77  
    78  	_, ok := metainfo.GetValue(ctx, k)
    79  	assert(t, !ok)
    80  
    81  	ctx = metainfo.WithValue(ctx, "", v)
    82  	assert(t, ctx != nil)
    83  
    84  	_, ok = metainfo.GetValue(ctx, "")
    85  	assert(t, !ok)
    86  }
    87  
    88  func TestDelValue(t *testing.T) {
    89  	ctx := context.Background()
    90  
    91  	k, v := "Key", "Value"
    92  	ctx = metainfo.WithValue(ctx, k, v)
    93  	assert(t, ctx != nil)
    94  
    95  	x, ok := metainfo.GetValue(ctx, k)
    96  	assert(t, ok)
    97  	assert(t, x == v)
    98  
    99  	ctx = metainfo.DelValue(ctx, k)
   100  	assert(t, ctx != nil)
   101  
   102  	x, ok = metainfo.GetValue(ctx, k)
   103  	assert(t, !ok)
   104  
   105  	assert(t, metainfo.DelValue(ctx, "") == ctx)
   106  }
   107  
   108  func TestGetAll(t *testing.T) {
   109  	ctx := context.Background()
   110  
   111  	ss := []string{"1", "2", "3"}
   112  	for _, k := range ss {
   113  		ctx = metainfo.WithValue(ctx, "key"+k, "val"+k)
   114  	}
   115  
   116  	m := metainfo.GetAllValues(ctx)
   117  	assert(t, m != nil)
   118  	assert(t, len(m) == len(ss))
   119  
   120  	for _, k := range ss {
   121  		assert(t, m["key"+k] == "val"+k)
   122  	}
   123  }
   124  
   125  func TestRangeValues(t *testing.T) {
   126  	ctx := context.Background()
   127  
   128  	ss := []string{"1", "2", "3"}
   129  	for _, k := range ss {
   130  		ctx = metainfo.WithValue(ctx, "key"+k, "val"+k)
   131  	}
   132  
   133  	m := make(map[string]string, 3)
   134  	f := func(k, v string) bool {
   135  		m[k] = v
   136  		return true
   137  	}
   138  
   139  	metainfo.RangeValues(ctx, f)
   140  	assert(t, m != nil)
   141  	assert(t, len(m) == len(ss))
   142  
   143  	for _, k := range ss {
   144  		assert(t, m["key"+k] == "val"+k)
   145  	}
   146  }
   147  
   148  func TestGetAll2(t *testing.T) {
   149  	ctx := context.Background()
   150  
   151  	ss := []string{"1", "2", "3"}
   152  	for _, k := range ss {
   153  		ctx = metainfo.WithValue(ctx, "key"+k, "val"+k)
   154  	}
   155  
   156  	ctx = metainfo.DelValue(ctx, "key2")
   157  
   158  	m := metainfo.GetAllValues(ctx)
   159  	assert(t, m != nil)
   160  	assert(t, len(m) == len(ss)-1)
   161  
   162  	for _, k := range ss {
   163  		if k == "2" {
   164  			_, exist := m["key"+k]
   165  			assert(t, !exist)
   166  		} else {
   167  			assert(t, m["key"+k] == "val"+k)
   168  		}
   169  	}
   170  }
   171  
   172  ///////////////////////////////////////////////
   173  
   174  func TestWithPersistentValue(t *testing.T) {
   175  	ctx := context.Background()
   176  
   177  	k, v := "Key", "Value"
   178  	ctx = metainfo.WithPersistentValue(ctx, k, v)
   179  	assert(t, ctx != nil)
   180  
   181  	x, ok := metainfo.GetPersistentValue(ctx, k)
   182  	assert(t, ok)
   183  	assert(t, x == v)
   184  }
   185  
   186  func TestWithPersistentEmpty(t *testing.T) {
   187  	ctx := context.Background()
   188  
   189  	k, v := "Key", "Value"
   190  	ctx = metainfo.WithPersistentValue(ctx, k, "")
   191  	assert(t, ctx != nil)
   192  
   193  	_, ok := metainfo.GetPersistentValue(ctx, k)
   194  	assert(t, !ok)
   195  
   196  	ctx = metainfo.WithPersistentValue(ctx, "", v)
   197  	assert(t, ctx != nil)
   198  
   199  	_, ok = metainfo.GetPersistentValue(ctx, "")
   200  	assert(t, !ok)
   201  }
   202  
   203  func TestWithPersistentValues(t *testing.T) {
   204  	ctx := context.Background()
   205  
   206  	kvs := []string{"Key-1", "Value-1", "Key-2", "Value-2", "Key-3", "Value-3"}
   207  	ctx = metainfo.WithPersistentValues(ctx, kvs...)
   208  	assert(t, ctx != nil)
   209  
   210  	for i := 1; i <= 3; i++ {
   211  		x, ok := metainfo.GetPersistentValue(ctx, fmt.Sprintf("Key-%d", i))
   212  		assert(t, ok)
   213  		assert(t, x == fmt.Sprintf("Value-%d", i))
   214  	}
   215  }
   216  
   217  func TestWithPersistentValuesEmpty(t *testing.T) {
   218  	ctx := context.Background()
   219  
   220  	k, v := "Key", "Value"
   221  	kvs := []string{"", v, k, ""}
   222  
   223  	ctx = metainfo.WithPersistentValues(ctx, kvs...)
   224  	assert(t, ctx != nil)
   225  
   226  	_, ok := metainfo.GetPersistentValue(ctx, k)
   227  	assert(t, !ok)
   228  
   229  	_, ok = metainfo.GetPersistentValue(ctx, "")
   230  	assert(t, !ok)
   231  }
   232  
   233  func TestWithPersistentValuesRepeat(t *testing.T) {
   234  	ctx := context.Background()
   235  
   236  	kvs := []string{"Key", "Value-1", "Key", "Value-2", "Key", "Value-3"}
   237  
   238  	ctx = metainfo.WithPersistentValues(ctx, kvs...)
   239  	assert(t, ctx != nil)
   240  
   241  	x, ok := metainfo.GetPersistentValue(ctx, "Key")
   242  	assert(t, ok)
   243  	assert(t, x == "Value-3")
   244  }
   245  
   246  func TestDelPersistentValue(t *testing.T) {
   247  	ctx := context.Background()
   248  
   249  	k, v := "Key", "Value"
   250  	ctx = metainfo.WithPersistentValue(ctx, k, v)
   251  	assert(t, ctx != nil)
   252  
   253  	x, ok := metainfo.GetPersistentValue(ctx, k)
   254  	assert(t, ok)
   255  	assert(t, x == v)
   256  
   257  	ctx = metainfo.DelPersistentValue(ctx, k)
   258  	assert(t, ctx != nil)
   259  
   260  	x, ok = metainfo.GetPersistentValue(ctx, k)
   261  	assert(t, !ok)
   262  
   263  	assert(t, metainfo.DelPersistentValue(ctx, "") == ctx)
   264  }
   265  
   266  func TestGetAllPersistent(t *testing.T) {
   267  	ctx := context.Background()
   268  
   269  	ss := []string{"1", "2", "3"}
   270  	for _, k := range ss {
   271  		ctx = metainfo.WithPersistentValue(ctx, "key"+k, "val"+k)
   272  	}
   273  
   274  	m := metainfo.GetAllPersistentValues(ctx)
   275  	assert(t, m != nil)
   276  	assert(t, len(m) == len(ss))
   277  
   278  	for _, k := range ss {
   279  		assert(t, m["key"+k] == "val"+k)
   280  	}
   281  }
   282  
   283  func TestRangePersistent(t *testing.T) {
   284  	ctx := context.Background()
   285  
   286  	ss := []string{"1", "2", "3"}
   287  	for _, k := range ss {
   288  		ctx = metainfo.WithPersistentValue(ctx, "key"+k, "val"+k)
   289  	}
   290  
   291  	m := make(map[string]string, 3)
   292  	f := func(k, v string) bool {
   293  		m[k] = v
   294  		return true
   295  	}
   296  
   297  	metainfo.RangePersistentValues(ctx, f)
   298  	assert(t, m != nil)
   299  	assert(t, len(m) == len(ss))
   300  
   301  	for _, k := range ss {
   302  		assert(t, m["key"+k] == "val"+k)
   303  	}
   304  }
   305  
   306  func TestGetAllPersistent2(t *testing.T) {
   307  	ctx := context.Background()
   308  
   309  	ss := []string{"1", "2", "3"}
   310  	for _, k := range ss {
   311  		ctx = metainfo.WithPersistentValue(ctx, "key"+k, "val"+k)
   312  	}
   313  
   314  	ctx = metainfo.DelPersistentValue(ctx, "key2")
   315  
   316  	m := metainfo.GetAllPersistentValues(ctx)
   317  	assert(t, m != nil)
   318  	assert(t, len(m) == len(ss)-1)
   319  
   320  	for _, k := range ss {
   321  		if k == "2" {
   322  			_, exist := m["key"+k]
   323  			assert(t, !exist)
   324  		} else {
   325  			assert(t, m["key"+k] == "val"+k)
   326  		}
   327  	}
   328  }
   329  
   330  ///////////////////////////////////////////////
   331  
   332  func TestNilSafty(t *testing.T) {
   333  	assert(t, metainfo.TransferForward(nil) == nil)
   334  
   335  	_, tOK := metainfo.GetValue(nil, "any")
   336  	assert(t, !tOK)
   337  	assert(t, metainfo.GetAllValues(nil) == nil)
   338  	assert(t, metainfo.WithValue(nil, "any", "any") == nil)
   339  	assert(t, metainfo.DelValue(nil, "any") == nil)
   340  
   341  	_, pOK := metainfo.GetPersistentValue(nil, "any")
   342  	assert(t, !pOK)
   343  	assert(t, metainfo.GetAllPersistentValues(nil) == nil)
   344  	assert(t, metainfo.WithPersistentValue(nil, "any", "any") == nil)
   345  	assert(t, metainfo.DelPersistentValue(nil, "any") == nil)
   346  }
   347  
   348  func TestTransitAndPersistent(t *testing.T) {
   349  	ctx := context.Background()
   350  
   351  	ctx = metainfo.WithValue(ctx, "A", "a")
   352  	ctx = metainfo.WithPersistentValue(ctx, "A", "b")
   353  
   354  	x, xOK := metainfo.GetValue(ctx, "A")
   355  	y, yOK := metainfo.GetPersistentValue(ctx, "A")
   356  
   357  	assert(t, xOK)
   358  	assert(t, yOK)
   359  	assert(t, x == "a")
   360  	assert(t, y == "b")
   361  
   362  	_, uOK := metainfo.GetValue(ctx, "B")
   363  	_, vOK := metainfo.GetPersistentValue(ctx, "B")
   364  
   365  	assert(t, !uOK)
   366  	assert(t, !vOK)
   367  
   368  	ctx = metainfo.DelValue(ctx, "A")
   369  	_, pOK := metainfo.GetValue(ctx, "A")
   370  	q, qOK := metainfo.GetPersistentValue(ctx, "A")
   371  	assert(t, !pOK)
   372  	assert(t, qOK)
   373  	assert(t, q == "b")
   374  }
   375  
   376  func TestTransferForward(t *testing.T) {
   377  	ctx := context.Background()
   378  
   379  	ctx = metainfo.WithValue(ctx, "A", "t")
   380  	ctx = metainfo.WithPersistentValue(ctx, "A", "p")
   381  	ctx = metainfo.WithValue(ctx, "A", "ta")
   382  	ctx = metainfo.WithPersistentValue(ctx, "A", "pa")
   383  
   384  	ctx = metainfo.TransferForward(ctx)
   385  	assert(t, ctx != nil)
   386  
   387  	x, xOK := metainfo.GetValue(ctx, "A")
   388  	y, yOK := metainfo.GetPersistentValue(ctx, "A")
   389  
   390  	assert(t, xOK)
   391  	assert(t, yOK)
   392  	assert(t, x == "ta")
   393  	assert(t, y == "pa")
   394  
   395  	ctx = metainfo.TransferForward(ctx)
   396  	assert(t, ctx != nil)
   397  
   398  	x, xOK = metainfo.GetValue(ctx, "A")
   399  	y, yOK = metainfo.GetPersistentValue(ctx, "A")
   400  
   401  	assert(t, !xOK)
   402  	assert(t, yOK)
   403  	assert(t, y == "pa")
   404  
   405  	ctx = metainfo.WithValue(ctx, "B", "tb")
   406  
   407  	ctx = metainfo.TransferForward(ctx)
   408  	assert(t, ctx != nil)
   409  
   410  	y, yOK = metainfo.GetPersistentValue(ctx, "A")
   411  	z, zOK := metainfo.GetValue(ctx, "B")
   412  
   413  	assert(t, yOK)
   414  	assert(t, y == "pa")
   415  	assert(t, zOK)
   416  	assert(t, z == "tb")
   417  }
   418  
   419  func TestOverride(t *testing.T) {
   420  	ctx := context.Background()
   421  	ctx = metainfo.WithValue(ctx, "base", "base")
   422  	ctx = metainfo.WithValue(ctx, "base2", "base")
   423  	ctx = metainfo.WithValue(ctx, "base3", "base")
   424  
   425  	ctx1 := metainfo.WithValue(ctx, "a", "a")
   426  	ctx2 := metainfo.WithValue(ctx, "b", "b")
   427  
   428  	av, ae := metainfo.GetValue(ctx1, "a")
   429  	bv, be := metainfo.GetValue(ctx2, "b")
   430  	assert(t, ae && av == "a", ae, av)
   431  	assert(t, be && bv == "b", be, bv)
   432  }
   433  
   434  ///////////////////////////////////////////////
   435  
   436  func initMetaInfo(count int) (context.Context, []string, []string) {
   437  	ctx := context.Background()
   438  	var keys, vals []string
   439  	for i := 0; i < count; i++ {
   440  		k, v := fmt.Sprintf("key-%d", i), fmt.Sprintf("val-%d", i)
   441  		ctx = metainfo.WithValue(ctx, k, v)
   442  		ctx = metainfo.WithPersistentValue(ctx, k, v)
   443  		keys = append(keys, k)
   444  		vals = append(vals, v)
   445  	}
   446  	return ctx, keys, vals
   447  }
   448  
   449  func benchmark(b *testing.B, api string, count int) {
   450  	ctx, keys, vals := initMetaInfo(count)
   451  	switch api {
   452  	case "TransferForward":
   453  		b.ReportAllocs()
   454  		b.ResetTimer()
   455  		for i := 0; i < b.N; i++ {
   456  			_ = metainfo.TransferForward(ctx)
   457  		}
   458  	case "GetValue":
   459  		b.ReportAllocs()
   460  		b.ResetTimer()
   461  		for i := 0; i < b.N; i++ {
   462  			_, _ = metainfo.GetValue(ctx, keys[i%len(keys)])
   463  		}
   464  	case "GetAllValues":
   465  		b.ReportAllocs()
   466  		b.ResetTimer()
   467  		for i := 0; i < b.N; i++ {
   468  			_ = metainfo.GetAllValues(ctx)
   469  		}
   470  	case "RangeValues":
   471  		b.ReportAllocs()
   472  		b.ResetTimer()
   473  		for i := 0; i < b.N; i++ {
   474  			metainfo.RangeValues(ctx, func(_, _ string) bool {
   475  				return true
   476  			})
   477  		}
   478  	case "WithValue":
   479  		b.ReportAllocs()
   480  		b.ResetTimer()
   481  		for i := 0; i < b.N; i++ {
   482  			_ = metainfo.WithValue(ctx, "key", "val")
   483  		}
   484  	case "WithValues":
   485  		b.ReportAllocs()
   486  		b.ResetTimer()
   487  		for i := 0; i < b.N; i++ {
   488  			_ = metainfo.WithValues(ctx, "key--1", "val--1", "key--2", "val--2", "key--3", "val--3")
   489  		}
   490  	case "WithValueAcc":
   491  		b.ReportAllocs()
   492  		b.ResetTimer()
   493  		for i := 0; i < b.N; i++ {
   494  			ctx = metainfo.WithValue(ctx, vals[i%len(vals)], "val")
   495  		}
   496  	case "DelValue":
   497  		b.ReportAllocs()
   498  		b.ResetTimer()
   499  		for i := 0; i < b.N; i++ {
   500  			_ = metainfo.DelValue(ctx, "key")
   501  		}
   502  	case "GetPersistentValue":
   503  		b.ReportAllocs()
   504  		b.ResetTimer()
   505  		for i := 0; i < b.N; i++ {
   506  			_, _ = metainfo.GetPersistentValue(ctx, keys[i%len(keys)])
   507  		}
   508  	case "GetAllPersistentValues":
   509  		b.ReportAllocs()
   510  		b.ResetTimer()
   511  		for i := 0; i < b.N; i++ {
   512  			_ = metainfo.GetAllPersistentValues(ctx)
   513  		}
   514  	case "RangePersistentValues":
   515  		b.ReportAllocs()
   516  		b.ResetTimer()
   517  		for i := 0; i < b.N; i++ {
   518  			metainfo.RangePersistentValues(ctx, func(_, _ string) bool {
   519  				return true
   520  			})
   521  		}
   522  	case "WithPersistentValue":
   523  		b.ReportAllocs()
   524  		b.ResetTimer()
   525  		for i := 0; i < b.N; i++ {
   526  			_ = metainfo.WithPersistentValue(ctx, "key", "val")
   527  		}
   528  	case "WithPersistentValues":
   529  		b.ReportAllocs()
   530  		b.ResetTimer()
   531  		for i := 0; i < b.N; i++ {
   532  			_ = metainfo.WithPersistentValues(ctx, "key--1", "val--1", "key--2", "val--2", "key--3", "val--3")
   533  		}
   534  	case "WithPersistentValueAcc":
   535  		b.ReportAllocs()
   536  		b.ResetTimer()
   537  		for i := 0; i < b.N; i++ {
   538  			ctx = metainfo.WithPersistentValue(ctx, vals[i%len(vals)], "val")
   539  		}
   540  		_ = ctx
   541  	case "DelPersistentValue":
   542  		b.ReportAllocs()
   543  		b.ResetTimer()
   544  		for i := 0; i < b.N; i++ {
   545  			_ = metainfo.DelPersistentValue(ctx, "key")
   546  		}
   547  	case "SaveMetaInfoToMap":
   548  		b.ReportAllocs()
   549  		b.ResetTimer()
   550  		for i := 0; i < b.N; i++ {
   551  			m := make(map[string]string)
   552  			metainfo.SaveMetaInfoToMap(ctx, m)
   553  		}
   554  	case "SetMetaInfoFromMap":
   555  		m := make(map[string]string)
   556  		c := context.Background()
   557  		metainfo.SaveMetaInfoToMap(ctx, m)
   558  		b.ReportAllocs()
   559  		b.ResetTimer()
   560  		for i := 0; i < b.N; i++ {
   561  			_ = metainfo.SetMetaInfoFromMap(c, m)
   562  		}
   563  	}
   564  }
   565  
   566  func benchmarkParallel(b *testing.B, api string, count int) {
   567  	ctx, keys, vals := initMetaInfo(count)
   568  	switch api {
   569  	case "TransferForward":
   570  		b.ReportAllocs()
   571  		b.ResetTimer()
   572  		b.RunParallel(func(pb *testing.PB) {
   573  			for pb.Next() {
   574  				_ = metainfo.TransferForward(ctx)
   575  			}
   576  		})
   577  	case "GetValue":
   578  		b.ReportAllocs()
   579  		b.ResetTimer()
   580  		b.RunParallel(func(pb *testing.PB) {
   581  			var i int
   582  			for pb.Next() {
   583  				_, _ = metainfo.GetValue(ctx, keys[i%len(keys)])
   584  				i++
   585  			}
   586  		})
   587  	case "GetAllValues":
   588  		b.ReportAllocs()
   589  		b.ResetTimer()
   590  		b.RunParallel(func(pb *testing.PB) {
   591  			for pb.Next() {
   592  				_ = metainfo.GetAllValues(ctx)
   593  			}
   594  		})
   595  	case "RangeValues":
   596  		b.ReportAllocs()
   597  		b.ResetTimer()
   598  		b.RunParallel(func(pb *testing.PB) {
   599  			for pb.Next() {
   600  				metainfo.RangeValues(ctx, func(_, _ string) bool {
   601  					return true
   602  				})
   603  			}
   604  		})
   605  	case "WithValue":
   606  		b.ReportAllocs()
   607  		b.ResetTimer()
   608  		b.RunParallel(func(pb *testing.PB) {
   609  			for pb.Next() {
   610  				_ = metainfo.WithValue(ctx, "key", "val")
   611  			}
   612  		})
   613  	case "WithValues":
   614  		b.ReportAllocs()
   615  		b.ResetTimer()
   616  		b.RunParallel(func(pb *testing.PB) {
   617  			for pb.Next() {
   618  				_ = metainfo.WithValues(ctx, "key--1", "val--1", "key--2", "val--2", "key--3", "val--3")
   619  			}
   620  		})
   621  	case "WithValueAcc":
   622  		b.ReportAllocs()
   623  		b.ResetTimer()
   624  		b.RunParallel(func(pb *testing.PB) {
   625  			tmp := ctx
   626  			var i int
   627  			for pb.Next() {
   628  				tmp = metainfo.WithValue(tmp, vals[i%len(vals)], "val")
   629  				i++
   630  			}
   631  		})
   632  	case "DelValue":
   633  		b.ReportAllocs()
   634  		b.ResetTimer()
   635  		b.RunParallel(func(pb *testing.PB) {
   636  			for pb.Next() {
   637  				_ = metainfo.DelValue(ctx, "key")
   638  			}
   639  		})
   640  	case "GetPersistentValue":
   641  		b.ReportAllocs()
   642  		b.ResetTimer()
   643  		b.RunParallel(func(pb *testing.PB) {
   644  			var i int
   645  			for pb.Next() {
   646  				_, _ = metainfo.GetPersistentValue(ctx, keys[i%len(keys)])
   647  				i++
   648  			}
   649  		})
   650  	case "GetAllPersistentValues":
   651  		b.ReportAllocs()
   652  		b.ResetTimer()
   653  		b.RunParallel(func(pb *testing.PB) {
   654  			for pb.Next() {
   655  				_ = metainfo.GetAllPersistentValues(ctx)
   656  			}
   657  		})
   658  	case "RangePersistentValues":
   659  		b.ReportAllocs()
   660  		b.ResetTimer()
   661  		b.RunParallel(func(pb *testing.PB) {
   662  			for pb.Next() {
   663  				metainfo.RangePersistentValues(ctx, func(_, _ string) bool {
   664  					return true
   665  				})
   666  			}
   667  		})
   668  	case "WithPersistentValue":
   669  		b.ReportAllocs()
   670  		b.ResetTimer()
   671  		b.RunParallel(func(pb *testing.PB) {
   672  			for pb.Next() {
   673  				_ = metainfo.WithPersistentValue(ctx, "key", "val")
   674  			}
   675  		})
   676  	case "WithPersistentValues":
   677  		b.ReportAllocs()
   678  		b.ResetTimer()
   679  		b.RunParallel(func(pb *testing.PB) {
   680  			for pb.Next() {
   681  				_ = metainfo.WithPersistentValues(ctx, "key--1", "val--1", "key--2", "val--2", "key--3", "val--3")
   682  			}
   683  		})
   684  	case "WithPersistentValueAcc":
   685  		b.ReportAllocs()
   686  		b.ResetTimer()
   687  		b.RunParallel(func(pb *testing.PB) {
   688  			tmp := ctx
   689  			var i int
   690  			for pb.Next() {
   691  				tmp = metainfo.WithPersistentValue(tmp, vals[i%len(vals)], "val")
   692  				i++
   693  			}
   694  		})
   695  	case "DelPersistentValue":
   696  		b.ReportAllocs()
   697  		b.ResetTimer()
   698  		b.RunParallel(func(pb *testing.PB) {
   699  			for pb.Next() {
   700  				_ = metainfo.DelPersistentValue(ctx, "key")
   701  			}
   702  		})
   703  	case "SaveMetaInfoToMap":
   704  		b.ReportAllocs()
   705  		b.ResetTimer()
   706  		b.RunParallel(func(pb *testing.PB) {
   707  			for pb.Next() {
   708  				m := make(map[string]string)
   709  				metainfo.SaveMetaInfoToMap(ctx, m)
   710  			}
   711  		})
   712  	case "SetMetaInfoFromMap":
   713  		m := make(map[string]string)
   714  		c := context.Background()
   715  		metainfo.SaveMetaInfoToMap(ctx, m)
   716  		b.ReportAllocs()
   717  		b.ResetTimer()
   718  		b.RunParallel(func(pb *testing.PB) {
   719  			for pb.Next() {
   720  				_ = metainfo.SetMetaInfoFromMap(c, m)
   721  			}
   722  		})
   723  	}
   724  }
   725  
   726  func BenchmarkAll(b *testing.B) {
   727  	APIs := []string{
   728  		"TransferForward",
   729  		"GetValue",
   730  		"GetAllValues",
   731  		"WithValue",
   732  		"WithValues",
   733  		"WithValueAcc",
   734  		"DelValue",
   735  		"GetPersistentValue",
   736  		"GetAllPersistentValues",
   737  		"RangePersistentValues",
   738  		"WithPersistentValue",
   739  		"WithPersistentValues",
   740  		"WithPersistentValueAcc",
   741  		"DelPersistentValue",
   742  		"SaveMetaInfoToMap",
   743  		"SetMetaInfoFromMap",
   744  	}
   745  	for _, api := range APIs {
   746  		for _, cnt := range []int{10, 20, 50, 100} {
   747  			fun := fmt.Sprintf("%s_%d", api, cnt)
   748  			b.Run(fun, func(b *testing.B) { benchmark(b, api, cnt) })
   749  		}
   750  	}
   751  }
   752  
   753  func BenchmarkAllParallel(b *testing.B) {
   754  	APIs := []string{
   755  		"TransferForward",
   756  		"GetValue",
   757  		"GetAllValues",
   758  		"WithValue",
   759  		"WithValues",
   760  		"WithValueAcc",
   761  		"DelValue",
   762  		"GetPersistentValue",
   763  		"GetPersistentValues",
   764  		"GetAllPersistentValues",
   765  		"RangePersistentValues",
   766  		"WithPersistentValue",
   767  		"WithPersistentValueAcc",
   768  		"DelPersistentValue",
   769  		"SaveMetaInfoToMap",
   770  		"SetMetaInfoFromMap",
   771  	}
   772  	for _, api := range APIs {
   773  		for _, cnt := range []int{10, 20, 50, 100} {
   774  			fun := fmt.Sprintf("%s_%d", api, cnt)
   775  			b.Run(fun, func(b *testing.B) { benchmarkParallel(b, api, cnt) })
   776  		}
   777  	}
   778  }
   779  
   780  func TestValuesCount(t *testing.T) {
   781  	ctx := context.Background()
   782  	type args struct {
   783  		ctx context.Context
   784  	}
   785  	tests := []struct {
   786  		name string
   787  		args args
   788  		want int
   789  	}{
   790  		{
   791  			name: "0",
   792  			args: args{
   793  				ctx: ctx,
   794  			},
   795  			want: 0,
   796  		},
   797  		{
   798  			name: "0",
   799  			args: args{
   800  				ctx: metainfo.WithPersistentValues(ctx, "1", "1", "2", "2"),
   801  			},
   802  			want: 0,
   803  		},
   804  		{
   805  			name: "2",
   806  			args: args{
   807  				ctx: metainfo.WithValues(ctx, "1", "1", "2", "2"),
   808  			},
   809  			want: 2,
   810  		},
   811  	}
   812  	for _, tt := range tests {
   813  		t.Run(tt.name, func(t *testing.T) {
   814  			if got := metainfo.CountValues(tt.args.ctx); got != tt.want {
   815  				t.Errorf("ValuesCount() = %v, want %v", got, tt.want)
   816  			}
   817  		})
   818  	}
   819  }
   820  
   821  func TestPersistentValuesCount(t *testing.T) {
   822  	ctx := context.Background()
   823  	type args struct {
   824  		ctx context.Context
   825  	}
   826  	tests := []struct {
   827  		name string
   828  		args args
   829  		want int
   830  	}{
   831  		{
   832  			name: "0",
   833  			args: args{
   834  				ctx: ctx,
   835  			},
   836  			want: 0,
   837  		},
   838  		{
   839  			name: "0",
   840  			args: args{
   841  				ctx: metainfo.WithValues(ctx, "1", "1", "2", "2"),
   842  			},
   843  			want: 0,
   844  		},
   845  		{
   846  			name: "2",
   847  			args: args{
   848  				ctx: metainfo.WithPersistentValues(ctx, "1", "1", "2", "2"),
   849  			},
   850  			want: 2,
   851  		},
   852  	}
   853  	for _, tt := range tests {
   854  		t.Run(tt.name, func(t *testing.T) {
   855  			if got := metainfo.CountPersistentValues(tt.args.ctx); got != tt.want {
   856  				t.Errorf("ValuesCount() = %v, want %v", got, tt.want)
   857  			}
   858  		})
   859  	}
   860  }