github.com/annchain/OG@v0.0.9/og/txcache/cache_test.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 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 package txcache 15 16 import ( 17 "fmt" 18 types2 "github.com/annchain/OG/arefactor/og/types" 19 "github.com/annchain/OG/og/types" 20 "github.com/annchain/OG/og/types/archive" 21 22 "github.com/annchain/gcache" 23 "github.com/sirupsen/logrus" 24 "sync" 25 "testing" 26 "time" 27 ) 28 29 func init_log() { 30 Formatter := new(logrus.TextFormatter) 31 //Formatter.DisableColors = true 32 Formatter.TimestampFormat = "2006-01-02 15:04:05.000000" 33 Formatter.FullTimestamp = true 34 35 logrus.SetFormatter(Formatter) 36 } 37 38 func (c *TxCache) addInitTx() { 39 c.addInitTxWithNum(40000) 40 } 41 42 func (c *TxCache) addInitTxWithNum(num int) { 43 minWeight := uint64(500) 44 for i := 0; i < num; i++ { 45 var tx types.Txi 46 if i%40 == 0 { 47 tx = types.RandomSequencer() 48 tx.GetBase().Height = uint64(i / 1000) 49 tx.GetBase().Weight = uint64(i%1000) + tx.GetBase().Height + minWeight 50 } else { 51 tx = archive.RandomTx() 52 tx.GetBase().Height = uint64(i / 1000) 53 tx.GetBase().Weight = uint64(i%1000) + tx.GetBase().Height + minWeight 54 } 55 err := c.EnQueue(tx) 56 if err != nil { 57 panic(err) 58 } 59 //fmt.Println(tx) 60 } 61 } 62 63 func newTestTxcache(sorted bool) *TxCache { 64 return newTestTxcacheWithParam(100000, sorted, 3) 65 } 66 67 func newTestTxcacheWithParam(size int, sorted bool, expire int) *TxCache { 68 logrus.SetLevel(logrus.InfoLevel) 69 invalidTx := func(h types2.Hash) bool { 70 return true 71 } 72 //gcache.DebugMode = true 73 c := NewTxCache(size, expire, invalidTx, sorted) 74 75 logrus.SetLevel(logrus.DebugLevel) 76 return c 77 } 78 79 func TestTxCache_Get(t *testing.T) { 80 start := time.Now() 81 tx1 := archive.RandomTx() 82 tx2 := archive.RandomTx() 83 c := newTestTxcache(true) 84 c.addInitTx() 85 c.EnQueue(tx1) 86 if !c.Has(tx1.GetHash()) { 87 t.Fatal("tx is in cache") 88 } 89 if c.Has(tx2.GetHash()) { 90 t.Fatal("tx is not in cache") 91 } 92 hash := c.GetHashOrder()[5] 93 t.Log("hash", hash) 94 if tx := c.Get(hash); tx != nil { 95 t.Log(tx.String()) 96 } else { 97 t.Fatal("tx not found") 98 } 99 if tx := c.Get(tx1.GetHash()); tx != tx1 { 100 t.Fatalf("requied %v ;got %v", tx1.String(), tx.String()) 101 } 102 t.Log("len", c.Len()) 103 t.Log(time.Now().Sub(start).String()) 104 c.Remove(hash) 105 t.Log("remove tx", time.Now().Sub(start).String()) 106 time.Sleep(time.Second * 4) 107 c.Refresh() 108 if c.cache.Len() != 0 { 109 t.Fatalf("requied 0 , got %d", c.Len()) 110 } 111 if tx := c.Get(tx1.GetHash()); tx != nil { 112 t.Fatalf("requied nil ;got %v", tx.String()) 113 } 114 c.Remove(tx1.GetHash()) 115 t.Log("len", c.Len()) 116 c.RemoveExpiredAndInvalid(100) 117 t.Log("len", c.Len()) 118 } 119 120 func TestTxCache_PopALl(t *testing.T) { 121 122 c := newTestTxcache(true) 123 c.addInitTx() 124 fmt.Println(c.Len()) 125 start := time.Now() 126 for c.Len() != 0 { 127 c.DeQueue() //10000 item 2.1s 128 //c.cache.Remove(hash) // 10000 item 6ms 129 } 130 if c.Len() != 0 { 131 t.Fatalf("requied 0 , got %d", c.Len()) 132 } 133 t.Log("deQueue all used", time.Now().Sub(start).String()) 134 c = newTestTxcache(true) 135 c.addInitTx() 136 start = time.Now() 137 hashes := c.GetHashOrder() 138 for _, hash := range hashes { 139 //c.deQueue() //10000 item 2.1s 140 c.cache.Remove(hash) // 10000 item 6ms 141 } 142 if c.Len() != 0 { 143 t.Fatalf("requied 0 , got %d", c.Len()) 144 } 145 t.Log("directly remove all used", time.Now().Sub(start).String()) 146 147 c = newTestTxcache(true) 148 c.addInitTx() 149 start = time.Now() 150 c.cache.DeQueueBatch(39000) 151 c.cache.DeQueueBatch(3000) 152 if c.Len() != 0 { 153 t.Fatalf("requied 0 , got %d", c.Len()) 154 } 155 t.Log("deque batch remove all used", time.Now().Sub(start).String()) 156 //result for 50000 items 157 //remove all by hash cmp used 28.865s 158 //deQueue all used 22ms 159 //directly remove all used 22ms 160 } 161 162 func TestTxCache_EnQueue(t *testing.T) { 163 c := newTestTxcache(true) 164 c.addInitTx() 165 var wg sync.WaitGroup 166 start := time.Now() 167 for i := 0; i < 28000; i++ { 168 tx := archive.RandomTx() 169 wg.Add(1) 170 go func() { 171 //begin := time.Now() 172 c.EnQueue(tx) 173 //fmt.Println(time.Now().Sub(begin).String(),"enqueue") 174 wg.Done() 175 //fmt.Println(time.Now().Sub(begin).String(),"done") 176 }() 177 } 178 wg.Wait() 179 fmt.Println(c.cache.Len(), "used", time.Now().Sub(start)) 180 } 181 182 func TestTxCache_GetTop(t *testing.T) { 183 c := newTestTxcache(true) 184 c.addInitTx() 185 var wg sync.WaitGroup 186 start := time.Now() 187 for i := 0; i < 28000; i++ { 188 tx := archive.RandomTx() 189 wg.Add(1) 190 go func(int) { 191 //begin := time.Now() 192 c.EnQueue(tx) 193 //fmt.Println(time.Now().Sub(begin).String(),"enqueue") 194 if i%1000 == 0 { 195 fmt.Println("top,i", c.GetTop()) 196 } else if i%1001 == 0 { 197 fmt.Println(c.DeQueueBatch(2)) 198 } 199 wg.Done() 200 //fmt.Println(time.Now().Sub(begin).String(),"done") 201 }(i) 202 } 203 wg.Wait() 204 fmt.Println(c.cache.Len(), "used", time.Now().Sub(start)) 205 } 206 207 func TestTxCache_DeQueueBatch(t *testing.T) { 208 c := newTestTxcache(true) 209 c.addInitTx() 210 c.DeQueueBatch(50000) 211 start := time.Now() 212 var txis []*types.Tx 213 for i := 0; i < 100; i++ { 214 tx := archive.RandomTx() 215 tx.Weight = uint64(i) 216 txis = append(txis, tx) 217 //begin := time.Now() 218 c.EnQueue(tx) 219 //fmt.Println(time.Now().Sub(begin).String(),"enqueue") 220 if i%20 == 0 { 221 fmt.Println("top,i", c.GetTop()) 222 } 223 //fmt.Println(time.Now().Sub(begin).String(),"done") 224 } 225 226 for i := 0; i < 100; i++ { 227 tx := c.DeQueue() 228 if tx != txis[i] { 229 t.Fatal("diff ", tx, txis[i]) 230 } 231 if i%20 == 0 { 232 t.Log("same ", tx, txis[i]) 233 } 234 } 235 fmt.Println(c.cache.Len(), "used", time.Now().Sub(start)) 236 } 237 238 func TestTxCache_AddFrontBatch(t *testing.T) { 239 c := newTestTxcache(true) 240 c.addInitTx() 241 var txs []types.Txi 242 for i := 0; i < 100; i++ { 243 tx := archive.RandomTx() 244 tx.Weight = uint64(i*3 + 2) 245 txs = append(txs, tx) 246 //begin := time.Now() 247 //fmt.Println(time.Now().Sub(begin).String(),"enqueue") 248 if i%20 == 0 { 249 fmt.Println("top,i", c.GetTop()) 250 } 251 //fmt.Println(time.Now().Sub(begin).String(),"done") 252 } 253 start := time.Now() 254 c.PrependBatch(txs) 255 for i := 0; i < 100; i++ { 256 tx := c.DeQueue() 257 if tx != txs[i] { 258 t.Fatal("diff ", tx, txs[i]) 259 } 260 if i%20 == 0 { 261 t.Log("same ", tx, txs[i]) 262 } 263 } 264 fmt.Println(c.cache.Len(), "used", time.Now().Sub(start)) 265 } 266 267 func TestTxCache_Sort(t *testing.T) { 268 c := newTestTxcache(true) 269 c.addInitTx() 270 for i := 0; i < 100; i++ { 271 fmt.Println(i, c.DeQueue()) 272 } 273 //c.cache.PrintValues(1) 274 fmt.Println("\n***sort**") 275 start := time.Now() 276 c.Sort() 277 fmt.Println(c.cache.Len(), "used", time.Now().Sub(start)) 278 c.cache.PrintValues(1) 279 for i := 0; i < 100; i++ { 280 fmt.Println(i, c.DeQueue()) 281 } 282 } 283 284 func TestTxCache_Sort2(t *testing.T) { 285 c := newTestTxcache(true) 286 c.addInitTx() 287 c.DeQueueBatch(100000) 288 for i := 10; i < 40000; i++ { 289 var tx types.Txi 290 if i%40 == 0 { 291 seq := types.RandomSequencer() 292 if i%200 == 0 { 293 seq.Height = uint64(i/1000 + 1) 294 seq.Weight = uint64(i%1000) + seq.Height 295 } else { 296 seq.Height = uint64(i/1000 - 1) 297 seq.Weight = uint64(i%1000) + seq.Height 298 } 299 300 tx = seq 301 } else { 302 randTx := archive.RandomTx() 303 randTx.Height = uint64(i / 100) 304 randTx.Weight = uint64(i%100) + randTx.Height 305 tx = randTx 306 } 307 err := c.EnQueue(tx) 308 if err != nil { 309 panic(err) 310 } 311 } 312 for i := 0; i < 100; i++ { 313 fmt.Println(i, c.DeQueue()) 314 } 315 fmt.Println("\n***sort**") 316 start := time.Now() 317 c.Sort() 318 fmt.Println(c.cache.Len(), "used", time.Now().Sub(start)) 319 for i := 0; i < 100; i++ { 320 fmt.Println(i, c.DeQueue()) 321 } 322 } 323 324 func TestTxCache_Remove(t *testing.T) { 325 c := newTestTxcacheWithParam(400000, true, 60) 326 c.addInitTxWithNum(100000) 327 gcache.DebugMode = true 328 hash := c.GetHashOrder()[99999] 329 tx := c.Get(hash) 330 start := time.Now() 331 c.Remove(hash) 332 //gcache.DebugMode= false 333 fmt.Println("sorted remove use time ", time.Now().Sub(start), hash, tx, c.cache.Len(), c.Get(hash)) 334 c = newTestTxcacheWithParam(400000, false, 60) 335 c.addInitTxWithNum(100000) 336 gcache.DebugMode = true 337 hash = c.GetHashOrder()[99999] 338 tx = c.Get(hash) 339 start = time.Now() 340 c.Remove(hash) 341 fmt.Println("unsorted remove use time ", time.Now().Sub(start), hash, tx, c.cache.Len(), c.Get(hash)) 342 } 343 344 func TestTxCache_Has(t *testing.T) { 345 c := newTestTxcacheWithParam(1000, true, 60) 346 c.addInitTxWithNum(200) 347 gcache.DebugMode = true 348 hash := c.GetHashOrder()[150] 349 tx := c.Get(hash) 350 fmt.Println(hash, tx, c.cache.Len(), c.Get(hash), c.Has(hash), c.Has(archive.RandomTx().GetHash())) 351 }