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  }