github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/issue_test/issue186_test.go (about)

     1  /*
     2  * Copyright 2021 ByteDance Inc.
     3  *
     4  * Licensed under the Apache License, Version 2.0 (the "License");
     5  * you may not use this file except in compliance with the License.
     6  * You may obtain a copy of the License at
     7  *
     8  *     http://www.apache.org/licenses/LICENSE-2.0
     9  *
    10  * Unless required by applicable law or agreed to in writing, software
    11  * distributed under the License is distributed on an "AS IS" BASIS,
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  * See the License for the specific language governing permissions and
    14  * limitations under the License.
    15   */
    16  
    17  package issue_test
    18  
    19  import (
    20      `math/rand`
    21      `runtime`
    22      `sync`
    23      `testing`
    24      `time`
    25  
    26      `github.com/bytedance/sonic`
    27  )
    28  
    29  
    30  type GlobalConfig []Conf
    31  
    32  type Conf struct {
    33      A  string             `json:"A"`
    34      B  SubConf            `json:"B"`
    35      C []string            `json:"C"`
    36  }
    37  
    38  type SubConf struct {
    39      Slice        []int64 `json:"Slice"`
    40      Map          map[int64]bool `json:"-"`
    41  }
    42  
    43  func IntSlide2Map(l []int64) map[int64]bool {
    44      m := make(map[int64]bool)
    45      for _, item := range l {
    46          m[item] = true
    47      }
    48      return m
    49  }
    50  
    51  func Reload(t *testing.T, rawData string) (tmp GlobalConfig) {
    52      buf := []byte(rawData)
    53      runtime.GC()
    54      // t.Logf("got bytes %x\n", unsafe.Pointer(&buf[0]))
    55      // runtime.SetFinalizer(&buf[0], func(x *byte){
    56          // t.Logf("&byte %x got free\n", x)
    57      // })
    58      err := sonic.Unmarshal(buf, &tmp) // better use sonic.UnmarshalString()!
    59      if err != nil {
    60          t.Fatalf("failed to unmarshal json, raw data: %v, err: %v", rawData, err)
    61      }
    62      runtime.GC()
    63      // t.Log("unmarshal done")
    64      for index, conf := range tmp {
    65          tmp[index].B.Map = IntSlide2Map(conf.B.Slice)
    66      }
    67      runtime.GC()
    68      // t.Log("calc done")
    69      return
    70  }
    71  
    72  func TestIssue186(t *testing.T) {
    73      t.Parallel()
    74      var data = `[{"A":"xxx","B":{"Slice":[111]}},{"A":"yyy","B":{"Slice":[222]},"C":["extra"]},{"A":"zzz","B":{"Slice":[333]},"C":["extra"]},{"A":"zzz","B":{"Slice":[333]},"C":["extra"]},{"A":"zzz","B":{"Slice":[1111111111,2222222222,3333333333,44444444444,55555555555]},"C":["extra","aaaaaaaaaaaa","bbbbbbbbbbbbb","ccccccccccccc","ddddddddddddd"]}]`
    75      // var obj interface{}
    76      for k:=0; k<100; k++ {
    77          wg := sync.WaitGroup{}
    78          for i:=0; i<1000; i++ {
    79              wg.Add(1)
    80              go func(){
    81                  defer wg.Done()
    82                  time.Sleep(time.Duration(rand.Intn(100)+1000))
    83                  tmp := Reload(t, data)
    84                  runtime.GC()
    85                  _ = tmp[0].A
    86                  runtime.GC()
    87                  // obj = tmp
    88              }()
    89          }
    90          runtime.GC()
    91          // t.Log(obj)
    92          wg.Wait()
    93      }
    94  }