github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/counters/counter_test.go (about)

     1  // Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
     2  
     3  package counters_test
     4  
     5  import (
     6  	"github.com/TeaOSLab/EdgeNode/internal/utils/counters"
     7  	"github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
     8  	"github.com/iwind/TeaGo/assert"
     9  	"github.com/iwind/TeaGo/rands"
    10  	"github.com/iwind/TeaGo/types"
    11  	timeutil "github.com/iwind/TeaGo/utils/time"
    12  	"runtime"
    13  	"runtime/debug"
    14  	"sync/atomic"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  func TestCounter_Increase(t *testing.T) {
    20  	var a = assert.NewAssertion(t)
    21  
    22  	var counter = counters.NewCounter[uint32]()
    23  	a.IsTrue(counter.Increase(1, 10) == 1)
    24  	a.IsTrue(counter.Increase(1, 10) == 2)
    25  	a.IsTrue(counter.Increase(2, 10) == 1)
    26  
    27  	counter.Reset(1)
    28  	a.IsTrue(counter.Get(1) == 0) // changed
    29  	a.IsTrue(counter.Get(2) == 1) // not changed
    30  }
    31  
    32  func TestCounter_IncreaseKey(t *testing.T) {
    33  	var a = assert.NewAssertion(t)
    34  
    35  	var counter = counters.NewCounter[uint32]()
    36  	a.IsTrue(counter.IncreaseKey("1", 10) == 1)
    37  	a.IsTrue(counter.IncreaseKey("1", 10) == 2)
    38  	a.IsTrue(counter.IncreaseKey("2", 10) == 1)
    39  
    40  	counter.ResetKey("1")
    41  	a.IsTrue(counter.GetKey("1") == 0) // changed
    42  	a.IsTrue(counter.GetKey("2") == 1) // not changed
    43  }
    44  
    45  func TestCounter_GC(t *testing.T) {
    46  	if !testutils.IsSingleTesting() {
    47  		return
    48  	}
    49  
    50  	var counter = counters.NewCounter[uint32]()
    51  	counter.Increase(1, 20)
    52  	time.Sleep(1 * time.Second)
    53  	counter.Increase(1, 20)
    54  	time.Sleep(1 * time.Second)
    55  	counter.Increase(1, 20)
    56  	counter.GC()
    57  	t.Log(counter.Get(1))
    58  }
    59  
    60  func TestCounter_GC2(t *testing.T) {
    61  	if !testutils.IsSingleTesting() {
    62  		return
    63  	}
    64  
    65  	var counter = counters.NewCounter[uint32]().WithGC()
    66  	for i := 0; i < 100_000; i++ {
    67  		counter.Increase(uint64(i), rands.Int(10, 300))
    68  	}
    69  
    70  	var ticker = time.NewTicker(1 * time.Second)
    71  	for range ticker.C {
    72  		t.Log(timeutil.Format("H:i:s"), counter.TotalItems())
    73  		if counter.TotalItems() == 0 {
    74  			break
    75  		}
    76  	}
    77  }
    78  
    79  func TestCounterMemory(t *testing.T) {
    80  	var stat = &runtime.MemStats{}
    81  	runtime.ReadMemStats(stat)
    82  
    83  	var counter = counters.NewCounter[uint32]()
    84  	for i := 0; i < 1_000_000; i++ {
    85  		counter.Increase(uint64(i), rands.Int(10, 300))
    86  	}
    87  
    88  	runtime.GC()
    89  	runtime.GC()
    90  	debug.FreeOSMemory()
    91  
    92  	var stat1 = &runtime.MemStats{}
    93  	runtime.ReadMemStats(stat1)
    94  	t.Log((stat1.HeapInuse-stat.HeapInuse)/(1<<20), "MB")
    95  
    96  	t.Log(counter.TotalItems())
    97  
    98  	var gcPause = func() {
    99  		var before = time.Now()
   100  		runtime.GC()
   101  		var costSeconds = time.Since(before).Seconds()
   102  		var stats = &debug.GCStats{}
   103  		debug.ReadGCStats(stats)
   104  		t.Log("GC pause:", stats.Pause[0].Seconds()*1000, "ms", "cost:", costSeconds*1000, "ms")
   105  	}
   106  
   107  	gcPause()
   108  
   109  	_ = counter.TotalItems()
   110  }
   111  
   112  func BenchmarkCounter_Increase(b *testing.B) {
   113  	runtime.GOMAXPROCS(4)
   114  
   115  	var counter = counters.NewCounter[uint32]()
   116  
   117  	b.ReportAllocs()
   118  	b.ResetTimer()
   119  
   120  	var i uint64
   121  	b.RunParallel(func(pb *testing.PB) {
   122  		for pb.Next() {
   123  			counter.Increase(atomic.AddUint64(&i, 1)%1_000_000, 20)
   124  		}
   125  	})
   126  
   127  	//b.Log(counter.TotalItems())
   128  }
   129  
   130  func BenchmarkCounter_IncreaseKey(b *testing.B) {
   131  	runtime.GOMAXPROCS(4)
   132  
   133  	var counter = counters.NewCounter[uint32]()
   134  
   135  	go func() {
   136  		var ticker = time.NewTicker(100 * time.Millisecond)
   137  		for range ticker.C {
   138  			counter.GC()
   139  		}
   140  	}()
   141  
   142  	b.ResetTimer()
   143  	b.ReportAllocs()
   144  
   145  	var i uint64
   146  	b.RunParallel(func(pb *testing.PB) {
   147  		for pb.Next() {
   148  			counter.IncreaseKey(types.String(atomic.AddUint64(&i, 1)%1_000_000), 20)
   149  		}
   150  	})
   151  
   152  	//b.Log(counter.TotalItems())
   153  }
   154  
   155  func BenchmarkCounter_IncreaseKey2(b *testing.B) {
   156  	runtime.GOMAXPROCS(4)
   157  
   158  	var counter = counters.NewCounter[uint32]()
   159  
   160  	go func() {
   161  		var ticker = time.NewTicker(1 * time.Millisecond)
   162  		for range ticker.C {
   163  			counter.GC()
   164  		}
   165  	}()
   166  
   167  	b.ResetTimer()
   168  
   169  	var i uint64
   170  	b.RunParallel(func(pb *testing.PB) {
   171  		for pb.Next() {
   172  			counter.IncreaseKey(types.String(atomic.AddUint64(&i, 1)%1e5), 20)
   173  		}
   174  	})
   175  
   176  	//b.Log(counter.TotalItems())
   177  }
   178  
   179  func BenchmarkCounter_GC(b *testing.B) {
   180  	runtime.GOMAXPROCS(4)
   181  
   182  	var counter = counters.NewCounter[uint32]()
   183  
   184  	for i := uint64(0); i < 1e5; i++ {
   185  		counter.IncreaseKey(types.String(i), 20)
   186  	}
   187  
   188  	b.ResetTimer()
   189  
   190  	b.RunParallel(func(pb *testing.PB) {
   191  		for pb.Next() {
   192  			counter.GC()
   193  		}
   194  	})
   195  
   196  	//b.Log(counter.TotalItems())
   197  }