github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/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/goshafaq/sonic"
    27  )
    28  
    29  type GlobalConfig []Conf
    30  
    31  type Conf struct {
    32  	A string   `json:"A"`
    33  	B SubConf  `json:"B"`
    34  	C []string `json:"C"`
    35  }
    36  
    37  type SubConf struct {
    38  	Slice []int64        `json:"Slice"`
    39  	Map   map[int64]bool `json:"-"`
    40  }
    41  
    42  func IntSlide2Map(l []int64) map[int64]bool {
    43  	m := make(map[int64]bool)
    44  	for _, item := range l {
    45  		m[item] = true
    46  	}
    47  	return m
    48  }
    49  
    50  func Reload(t *testing.T, rawData string) (tmp GlobalConfig) {
    51  	buf := []byte(rawData)
    52  	runtime.GC()
    53  	// t.Logf("got bytes %x\n", unsafe.Pointer(&buf[0]))
    54  	// runtime.SetFinalizer(&buf[0], func(x *byte){
    55  	// t.Logf("&byte %x got free\n", x)
    56  	// })
    57  	err := sonic.Unmarshal(buf, &tmp) // better use sonic.UnmarshalString()!
    58  	if err != nil {
    59  		t.Fatalf("failed to unmarshal json, raw data: %v, err: %v", rawData, err)
    60  	}
    61  	runtime.GC()
    62  	// t.Log("unmarshal done")
    63  	for index, conf := range tmp {
    64  		tmp[index].B.Map = IntSlide2Map(conf.B.Slice)
    65  	}
    66  	runtime.GC()
    67  	// t.Log("calc done")
    68  	return
    69  }
    70  
    71  func TestIssue186(t *testing.T) {
    72  	t.Parallel()
    73  	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"]}]`
    74  	// var obj interface{}
    75  	for k := 0; k < 100; k++ {
    76  		wg := sync.WaitGroup{}
    77  		for i := 0; i < 1000; i++ {
    78  			wg.Add(1)
    79  			go func() {
    80  				defer wg.Done()
    81  				time.Sleep(time.Duration(rand.Intn(100) + 1000))
    82  				tmp := Reload(t, data)
    83  				runtime.GC()
    84  				_ = tmp[0].A
    85  				runtime.GC()
    86  				// obj = tmp
    87  			}()
    88  		}
    89  		runtime.GC()
    90  		// t.Log(obj)
    91  		wg.Wait()
    92  	}
    93  }