github.com/pingcap/badger@v1.5.1-0.20230103063557-828f39b09b6d/cache/policy_test.go (about)

     1  package cache
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  )
     7  
     8  func TestPolicy(t *testing.T) {
     9  	defer func() {
    10  		if r := recover(); r != nil {
    11  			t.Fatal("newPolicy failed")
    12  		}
    13  	}()
    14  	newPolicy(100, 10)
    15  }
    16  
    17  func TestPolicyMetrics(t *testing.T) {
    18  	p := newPolicy(100, 10)
    19  	p.CollectMetrics(newMetrics())
    20  	if p.metrics == nil || p.evict.metrics == nil {
    21  		t.Fatal("policy metrics initialization error")
    22  	}
    23  }
    24  
    25  func TestPolicyProcessItems(t *testing.T) {
    26  	p := newPolicy(100, 10)
    27  	p.itemsCh <- []uint64{1, 2, 2}
    28  	time.Sleep(wait)
    29  	p.Lock()
    30  	if p.admit.Estimate(2) != 2 || p.admit.Estimate(1) != 1 {
    31  		p.Unlock()
    32  		t.Fatal("policy processItems not pushing to tinylfu counters")
    33  	}
    34  	p.Unlock()
    35  	p.stop <- struct{}{}
    36  	p.itemsCh <- []uint64{3, 3, 3}
    37  	time.Sleep(wait)
    38  	p.Lock()
    39  	if p.admit.Estimate(3) != 0 {
    40  		p.Unlock()
    41  		t.Fatal("policy processItems not stopping")
    42  	}
    43  	p.Unlock()
    44  }
    45  
    46  func TestPolicyPush(t *testing.T) {
    47  	p := newPolicy(100, 10)
    48  	if !p.Push([]uint64{}) {
    49  		t.Fatal("push empty slice should be good")
    50  	}
    51  	keepCount := 0
    52  	for i := 0; i < 10; i++ {
    53  		if p.Push([]uint64{1, 2, 3, 4, 5}) {
    54  			keepCount++
    55  		}
    56  	}
    57  	if keepCount == 0 {
    58  		t.Fatal("push dropped everything")
    59  	}
    60  }
    61  
    62  func TestPolicyAdd(t *testing.T) {
    63  	p := newPolicy(1000, 100)
    64  	if victims, added := p.Add(1, 101); victims != nil || added {
    65  		t.Fatal("can't add an item bigger than entire cache")
    66  	}
    67  	p.Lock()
    68  	p.evict.add(1, 1)
    69  	p.admit.Increment(1)
    70  	p.admit.Increment(2)
    71  	p.admit.Increment(3)
    72  	p.Unlock()
    73  	if victims, added := p.Add(1, 1); victims != nil || !added {
    74  		t.Fatal("item should already exist")
    75  	}
    76  	if victims, added := p.Add(2, 20); victims != nil || !added {
    77  		t.Fatal("item should be added with no eviction")
    78  	}
    79  	if victims, added := p.Add(3, 90); victims == nil || !added {
    80  		t.Fatal("item should be added with eviction")
    81  	}
    82  	if victims, added := p.Add(4, 20); victims == nil || added {
    83  		t.Fatal("item should not be added")
    84  	}
    85  }
    86  
    87  func TestPolicyHas(t *testing.T) {
    88  	p := newPolicy(100, 10)
    89  	p.Add(1, 1)
    90  	if !p.Has(1) {
    91  		t.Fatal("policy should have key")
    92  	}
    93  	if p.Has(2) {
    94  		t.Fatal("policy shouldn't have key")
    95  	}
    96  }
    97  
    98  func TestPolicyDel(t *testing.T) {
    99  	p := newPolicy(100, 10)
   100  	p.Add(1, 1)
   101  	p.Del(1)
   102  	p.Del(2)
   103  	if p.Has(1) {
   104  		t.Fatal("del didn't delete")
   105  	}
   106  	if p.Has(2) {
   107  		t.Fatal("policy shouldn't have key")
   108  	}
   109  }
   110  
   111  func TestPolicyCap(t *testing.T) {
   112  	p := newPolicy(100, 10)
   113  	p.Add(1, 1)
   114  	if p.Cap() != 9 {
   115  		t.Fatal("cap returned wrong value")
   116  	}
   117  }
   118  
   119  func TestPolicyUpdate(t *testing.T) {
   120  	p := newPolicy(100, 10)
   121  	p.Add(1, 1)
   122  	p.Update(1, 2)
   123  	p.Lock()
   124  	if p.evict.keyCosts[1] != 2 {
   125  		p.Unlock()
   126  		t.Fatal("update failed")
   127  	}
   128  	p.Unlock()
   129  }
   130  
   131  func TestPolicyCost(t *testing.T) {
   132  	p := newPolicy(100, 10)
   133  	p.Add(1, 2)
   134  	if p.Cost(1) != 2 {
   135  		t.Fatal("cost for existing key returned wrong value")
   136  	}
   137  	if p.Cost(2) != -1 {
   138  		t.Fatal("cost for missing key returned wrong value")
   139  	}
   140  }
   141  
   142  func TestPolicyClear(t *testing.T) {
   143  	p := newPolicy(100, 10)
   144  	p.Add(1, 1)
   145  	p.Add(2, 2)
   146  	p.Add(3, 3)
   147  	p.Clear()
   148  	if p.Cap() != 10 || p.Has(1) || p.Has(2) || p.Has(3) {
   149  		t.Fatal("clear didn't clear properly")
   150  	}
   151  }
   152  
   153  func TestPolicyClose(t *testing.T) {
   154  	defer func() {
   155  		if r := recover(); r == nil {
   156  			t.Fatal("close didn't close channels")
   157  		}
   158  	}()
   159  	p := newPolicy(100, 10)
   160  	p.Add(1, 1)
   161  	p.Close()
   162  	p.itemsCh <- []uint64{1}
   163  }
   164  
   165  func TestSampledLFUAdd(t *testing.T) {
   166  	e := newSampledLFU(4)
   167  	e.add(1, 1)
   168  	e.add(2, 2)
   169  	e.add(3, 1)
   170  	if e.used != 4 {
   171  		t.Fatal("used not being incremented")
   172  	}
   173  	if e.keyCosts[2] != 2 {
   174  		t.Fatal("keyCosts not being updated")
   175  	}
   176  }
   177  
   178  func TestSampledLFUDel(t *testing.T) {
   179  	e := newSampledLFU(4)
   180  	e.add(1, 1)
   181  	e.add(2, 2)
   182  	e.del(2)
   183  	if e.used != 1 {
   184  		t.Fatal("del not updating used field")
   185  	}
   186  	if _, ok := e.keyCosts[2]; ok {
   187  		t.Fatal("del not deleting value from keyCosts")
   188  	}
   189  	e.del(4)
   190  }
   191  
   192  func TestSampledLFUUpdate(t *testing.T) {
   193  	e := newSampledLFU(4)
   194  	e.add(1, 1)
   195  	if !e.updateIfHas(1, 2) {
   196  		t.Fatal("update should be possible")
   197  	}
   198  	if e.used != 2 {
   199  		t.Fatal("update not changing used field")
   200  	}
   201  	if e.updateIfHas(2, 2) {
   202  		t.Fatal("update shouldn't be possible")
   203  	}
   204  }
   205  
   206  func TestSampledLFUClear(t *testing.T) {
   207  	e := newSampledLFU(4)
   208  	e.add(1, 1)
   209  	e.add(2, 2)
   210  	e.add(3, 1)
   211  	e.clear()
   212  	if len(e.keyCosts) != 0 || e.used != 0 {
   213  		t.Fatal("clear not deleting keyCosts or zeroing used field")
   214  	}
   215  }
   216  
   217  func TestSampledLFURoom(t *testing.T) {
   218  	e := newSampledLFU(16)
   219  	e.add(1, 1)
   220  	e.add(2, 2)
   221  	e.add(3, 3)
   222  	if e.roomLeft(4) != 6 {
   223  		t.Fatal("roomLeft returning wrong value")
   224  	}
   225  }
   226  
   227  func TestSampledLFUSample(t *testing.T) {
   228  	e := newSampledLFU(16)
   229  	e.add(4, 4)
   230  	e.add(5, 5)
   231  	sample := e.fillSample([]*policyPair{
   232  		{1, 1},
   233  		{2, 2},
   234  		{3, 3},
   235  	})
   236  	k := sample[len(sample)-1].key
   237  	if len(sample) != 5 || k == 1 || k == 2 || k == 3 {
   238  		t.Fatal("fillSample not filling properly")
   239  	}
   240  	if len(sample) != len(e.fillSample(sample)) {
   241  		t.Fatal("fillSample mutating full sample")
   242  	}
   243  	e.del(5)
   244  	if sample = e.fillSample(sample[:len(sample)-2]); len(sample) != 4 {
   245  		t.Fatal("fillSample not returning sample properly")
   246  	}
   247  }
   248  
   249  func TestTinyLFUIncrement(t *testing.T) {
   250  	a := newTinyLFU(4)
   251  	a.Increment(1)
   252  	a.Increment(1)
   253  	a.Increment(1)
   254  	if !a.door.Has(1) {
   255  		t.Fatal("doorkeeper bit not set")
   256  	}
   257  	if a.freq.Estimate(1) != 2 {
   258  		t.Fatal("incorrect counter value")
   259  	}
   260  	a.Increment(1)
   261  	if a.door.Has(1) {
   262  		t.Fatal("doorkeeper bit set after reset")
   263  	}
   264  	if a.freq.Estimate(1) != 1 {
   265  		t.Fatal("counter value not halved after reset")
   266  	}
   267  }
   268  
   269  func TestTinyLFUEstimate(t *testing.T) {
   270  	a := newTinyLFU(8)
   271  	a.Increment(1)
   272  	a.Increment(1)
   273  	a.Increment(1)
   274  	if a.Estimate(1) != 3 {
   275  		t.Fatal("estimate value incorrect")
   276  	}
   277  	if a.Estimate(2) != 0 {
   278  		t.Fatal("estimate value should be 0")
   279  	}
   280  }
   281  
   282  func TestTinyLFUPush(t *testing.T) {
   283  	a := newTinyLFU(16)
   284  	a.Push([]uint64{1, 2, 2, 3, 3, 3})
   285  	if a.Estimate(1) != 1 || a.Estimate(2) != 2 || a.Estimate(3) != 3 {
   286  		t.Fatal("push didn't increment counters properly")
   287  	}
   288  	if a.incrs != 6 {
   289  		t.Fatal("incrs not being incremented")
   290  	}
   291  }
   292  
   293  func TestTinyLFUClear(t *testing.T) {
   294  	a := newTinyLFU(16)
   295  	a.Push([]uint64{1, 3, 3, 3})
   296  	a.clear()
   297  	if a.incrs != 0 || a.Estimate(3) != 0 {
   298  		t.Fatal("clear not clearing")
   299  	}
   300  }