github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/expires/list_test.go (about) 1 package expires_test 2 3 import ( 4 "github.com/TeaOSLab/EdgeNode/internal/utils/expires" 5 "github.com/TeaOSLab/EdgeNode/internal/utils/fasttime" 6 "github.com/TeaOSLab/EdgeNode/internal/utils/testutils" 7 "github.com/iwind/TeaGo/assert" 8 "github.com/iwind/TeaGo/logs" 9 timeutil "github.com/iwind/TeaGo/utils/time" 10 "math" 11 "math/rand" 12 "runtime" 13 "testing" 14 "time" 15 ) 16 17 func TestList_Add(t *testing.T) { 18 var list = expires.NewList() 19 list.Add(1, time.Now().Unix()) 20 t.Log("===BEFORE===") 21 logs.PrintAsJSON(list.ExpireMap(), t) 22 logs.PrintAsJSON(list.ItemsMap(), t) 23 24 list.Add(1, time.Now().Unix()+1) 25 list.Add(2, time.Now().Unix()+1) 26 list.Add(3, time.Now().Unix()+2) 27 t.Log("===AFTER===") 28 logs.PrintAsJSON(list.ExpireMap(), t) 29 logs.PrintAsJSON(list.ItemsMap(), t) 30 } 31 32 func TestList_Add_Overwrite(t *testing.T) { 33 var timestamp = time.Now().Unix() 34 35 var list = expires.NewList() 36 list.Add(1, timestamp+1) 37 list.Add(1, timestamp+1) 38 list.Add(2, timestamp+1) 39 list.Add(1, timestamp+2) 40 logs.PrintAsJSON(list.ExpireMap(), t) 41 logs.PrintAsJSON(list.ItemsMap(), t) 42 43 var a = assert.NewAssertion(t) 44 a.IsTrue(len(list.ItemsMap()) == 2) 45 a.IsTrue(len(list.ExpireMap()) == 2) 46 a.IsTrue(list.ItemsMap()[1] == timestamp+2) 47 } 48 49 func TestList_Remove(t *testing.T) { 50 var a = assert.NewAssertion(t) 51 52 var list = expires.NewList() 53 list.Add(1, time.Now().Unix()+1) 54 list.Remove(1) 55 logs.PrintAsJSON(list.ExpireMap(), t) 56 logs.PrintAsJSON(list.ItemsMap(), t) 57 58 a.IsTrue(len(list.ExpireMap()) == 0) 59 a.IsTrue(len(list.ItemsMap()) == 0) 60 } 61 62 func TestList_GC(t *testing.T) { 63 var unixTime = time.Now().Unix() 64 t.Log("unixTime:", unixTime) 65 66 var list = expires.NewList() 67 list.Add(1, unixTime+1) 68 list.Add(2, unixTime+1) 69 list.Add(3, unixTime+2) 70 list.OnGC(func(itemId uint64) { 71 t.Log("gc:", itemId) 72 }) 73 t.Log("last unixTime:", list.LastTimestamp()) 74 list.GC(time.Now().Unix() + 2) 75 logs.PrintAsJSON(list.ExpireMap(), t) 76 logs.PrintAsJSON(list.ItemsMap(), t) 77 78 t.Log(list.Count()) 79 } 80 81 func TestList_GC_Batch(t *testing.T) { 82 var list = expires.NewList() 83 list.Add(1, time.Now().Unix()+1) 84 list.Add(2, time.Now().Unix()+1) 85 list.Add(3, time.Now().Unix()+2) 86 list.Add(4, time.Now().Unix()+2) 87 list.OnGCBatch(func(itemMap expires.ItemMap) { 88 t.Log("gc:", itemMap) 89 }) 90 list.GC(time.Now().Unix() + 2) 91 logs.PrintAsJSON(list.ExpireMap(), t) 92 logs.PrintAsJSON(list.ItemsMap(), t) 93 } 94 95 func TestList_Start_GC(t *testing.T) { 96 if !testutils.IsSingleTesting() { 97 return 98 } 99 100 var list = expires.NewList() 101 list.Add(1, time.Now().Unix()+1) 102 list.Add(2, time.Now().Unix()+1) 103 list.Add(3, time.Now().Unix()+2) 104 list.Add(3, time.Now().Unix()+10) 105 list.Add(4, time.Now().Unix()+5) 106 list.Add(5, time.Now().Unix()+5) 107 list.Add(6, time.Now().Unix()+6) 108 list.Add(7, time.Now().Unix()+6) 109 list.Add(8, time.Now().Unix()+6) 110 111 list.OnGC(func(itemId uint64) { 112 t.Log("gc:", itemId, timeutil.Format("H:i:s")) 113 time.Sleep(2 * time.Second) 114 }) 115 116 go func() { 117 expires.SharedManager.Add(list) 118 }() 119 120 time.Sleep(20 * time.Second) 121 logs.PrintAsJSON(list.ItemsMap()) 122 logs.PrintAsJSON(list.ExpireMap()) 123 } 124 125 func TestList_ManyItems(t *testing.T) { 126 var list = expires.NewList() 127 for i := 0; i < 1_000; i++ { 128 list.Add(uint64(i), time.Now().Unix()) 129 } 130 for i := 0; i < 1_000; i++ { 131 list.Add(uint64(i), time.Now().Unix()+1) 132 } 133 134 var now = time.Now() 135 var count = 0 136 list.OnGC(func(itemId uint64) { 137 count++ 138 }) 139 list.GC(time.Now().Unix() + 1) 140 t.Log("gc", count, "items") 141 t.Log(time.Since(now)) 142 } 143 144 func TestList_Memory(t *testing.T) { 145 if !testutils.IsSingleTesting() { 146 return 147 } 148 149 var list = expires.NewList() 150 151 testutils.StartMemoryStats(t, func() { 152 t.Log(list.Count(), "items") 153 }) 154 155 for i := 0; i < 10_000_000; i++ { 156 list.Add(uint64(i), time.Now().Unix()+1800) 157 } 158 159 time.Sleep(1 * time.Hour) 160 } 161 162 func TestList_Map_Performance(t *testing.T) { 163 t.Log("max uint32", math.MaxUint32) 164 165 var timestamp = time.Now().Unix() 166 167 { 168 var m = map[int64]int64{} 169 for i := 0; i < 1_000_000; i++ { 170 m[int64(i)] = timestamp 171 } 172 173 var now = time.Now() 174 for i := 0; i < 100_000; i++ { 175 delete(m, int64(i)) 176 } 177 t.Log(time.Since(now)) 178 } 179 180 { 181 var m = map[uint64]int64{} 182 for i := 0; i < 1_000_000; i++ { 183 m[uint64(i)] = timestamp 184 } 185 186 var now = time.Now() 187 for i := 0; i < 100_000; i++ { 188 delete(m, uint64(i)) 189 } 190 t.Log(time.Since(now)) 191 } 192 193 { 194 var m = map[uint32]int64{} 195 for i := 0; i < 1_000_000; i++ { 196 m[uint32(i)] = timestamp 197 } 198 199 var now = time.Now() 200 for i := 0; i < 100_000; i++ { 201 delete(m, uint32(i)) 202 } 203 t.Log(time.Since(now)) 204 } 205 } 206 207 func BenchmarkList_Add(b *testing.B) { 208 var list = expires.NewList() 209 b.ResetTimer() 210 b.RunParallel(func(pb *testing.PB) { 211 for pb.Next() { 212 list.Add(rand.Uint64(), fasttime.Now().Unix()+int64(rand.Int()%10_000_000)) 213 } 214 }) 215 } 216 217 func Benchmark_Map_Uint64(b *testing.B) { 218 runtime.GOMAXPROCS(1) 219 var timestamp = uint64(time.Now().Unix()) 220 221 var i uint64 222 var count uint64 = 1_000_000 223 224 var m = map[uint64]uint64{} 225 for i = 0; i < count; i++ { 226 m[i] = timestamp 227 } 228 229 for n := 0; n < b.N; n++ { 230 for i = 0; i < count; i++ { 231 _ = m[i] 232 } 233 } 234 } 235 236 func BenchmarkList_GC(b *testing.B) { 237 runtime.GOMAXPROCS(4) 238 239 var lists = []*expires.List{} 240 241 for m := 0; m < 1_000; m++ { 242 var list = expires.NewList() 243 for j := 0; j < 10_000; j++ { 244 list.Add(uint64(j), fasttime.Now().Unix()+int64(rand.Int()%10_000_000)) 245 } 246 lists = append(lists, list) 247 } 248 249 var timestamp = time.Now().Unix() 250 251 b.ResetTimer() 252 253 b.RunParallel(func(pb *testing.PB) { 254 for pb.Next() { 255 for _, list := range lists { 256 list.GC(timestamp + int64(rand.Int()%1_000_000)) 257 } 258 } 259 }) 260 }