github.com/etecs-ru/ristretto@v0.9.1/policy_test.go (about)

     1  package ristretto
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func TestPolicy(t *testing.T) {
    11  	defer func() {
    12  		require.Nil(t, recover())
    13  	}()
    14  	newPolicy(100, 10)
    15  }
    16  
    17  func TestPolicyMetrics(t *testing.T) {
    18  	p := newPolicy(100, 10)
    19  	p.CollectMetrics(newMetrics())
    20  	require.NotNil(t, p.metrics)
    21  	require.NotNil(t, p.costs.metrics)
    22  }
    23  
    24  func TestPolicyProcessItems(t *testing.T) {
    25  	p := newPolicy(100, 10)
    26  	p.itemsCh <- []uint64{1, 2, 2}
    27  	time.Sleep(wait)
    28  	p.Lock()
    29  	require.Equal(t, int64(2), p.admit.Estimate(2))
    30  	require.Equal(t, int64(1), p.admit.Estimate(1))
    31  	p.Unlock()
    32  
    33  	p.stop <- struct{}{}
    34  	p.itemsCh <- []uint64{3, 3, 3}
    35  	time.Sleep(wait)
    36  	p.Lock()
    37  	require.Equal(t, int64(0), p.admit.Estimate(3))
    38  	p.Unlock()
    39  }
    40  
    41  func TestPolicyPush(t *testing.T) {
    42  	p := newPolicy(100, 10)
    43  	require.True(t, p.Push([]uint64{}))
    44  
    45  	keepCount := 0
    46  	for i := 0; i < 10; i++ {
    47  		if p.Push([]uint64{1, 2, 3, 4, 5}) {
    48  			keepCount++
    49  		}
    50  	}
    51  	require.NotEqual(t, 0, keepCount)
    52  }
    53  
    54  func TestPolicyAdd(t *testing.T) {
    55  	p := newPolicy(1000, 100)
    56  	if victims, added := p.Add(1, 101); victims != nil || added {
    57  		t.Fatal("can't add an item bigger than entire cache")
    58  	}
    59  	p.Lock()
    60  	p.costs.add(1, 1)
    61  	p.admit.Increment(1)
    62  	p.admit.Increment(2)
    63  	p.admit.Increment(3)
    64  	p.Unlock()
    65  
    66  	victims, added := p.Add(1, 1)
    67  	require.Nil(t, victims)
    68  	require.False(t, added)
    69  
    70  	victims, added = p.Add(2, 20)
    71  	require.Nil(t, victims)
    72  	require.True(t, added)
    73  
    74  	victims, added = p.Add(3, 90)
    75  	require.NotNil(t, victims)
    76  	require.True(t, added)
    77  
    78  	victims, added = p.Add(4, 20)
    79  	require.NotNil(t, victims)
    80  	require.False(t, added)
    81  }
    82  
    83  func TestPolicyHas(t *testing.T) {
    84  	p := newPolicy(100, 10)
    85  	p.Add(1, 1)
    86  	require.True(t, p.Has(1))
    87  	require.False(t, p.Has(2))
    88  }
    89  
    90  func TestPolicyDel(t *testing.T) {
    91  	p := newPolicy(100, 10)
    92  	p.Add(1, 1)
    93  	p.Del(1)
    94  	p.Del(2)
    95  	require.False(t, p.Has(1))
    96  	require.False(t, p.Has(2))
    97  }
    98  
    99  func TestPolicyCap(t *testing.T) {
   100  	p := newPolicy(100, 10)
   101  	p.Add(1, 1)
   102  	require.Equal(t, int64(9), p.Cap())
   103  }
   104  
   105  func TestPolicyUpdate(t *testing.T) {
   106  	p := newPolicy(100, 10)
   107  	p.Add(1, 1)
   108  	p.Update(1, 2)
   109  	p.Lock()
   110  	require.Equal(t, int64(2), p.costs.keyCosts[1])
   111  	p.Unlock()
   112  }
   113  
   114  func TestPolicyCost(t *testing.T) {
   115  	p := newPolicy(100, 10)
   116  	p.Add(1, 2)
   117  	require.Equal(t, int64(2), p.Cost(1))
   118  	require.Equal(t, int64(-1), p.Cost(2))
   119  }
   120  
   121  func TestPolicyClear(t *testing.T) {
   122  	p := newPolicy(100, 10)
   123  	p.Add(1, 1)
   124  	p.Add(2, 2)
   125  	p.Add(3, 3)
   126  	p.Clear()
   127  	require.Equal(t, int64(10), p.Cap())
   128  	require.False(t, p.Has(1))
   129  	require.False(t, p.Has(2))
   130  	require.False(t, p.Has(3))
   131  }
   132  
   133  func TestPolicyClose(t *testing.T) {
   134  	defer func() {
   135  		require.NotNil(t, recover())
   136  	}()
   137  
   138  	p := newPolicy(100, 10)
   139  	p.Add(1, 1)
   140  	p.Close()
   141  	p.itemsCh <- []uint64{1}
   142  }
   143  
   144  func TestPushAfterClose(t *testing.T) {
   145  	p := newPolicy(100, 10)
   146  	p.Close()
   147  	require.False(t, p.Push([]uint64{1, 2}))
   148  }
   149  
   150  func TestAddAfterClose(t *testing.T) {
   151  	p := newPolicy(100, 10)
   152  	p.Close()
   153  	p.Add(1, 1)
   154  }
   155  
   156  func TestSampledLFUAdd(t *testing.T) {
   157  	e := newSampledLFU(4)
   158  	e.add(1, 1)
   159  	e.add(2, 2)
   160  	e.add(3, 1)
   161  	require.Equal(t, int64(4), e.used)
   162  	require.Equal(t, int64(2), e.keyCosts[2])
   163  }
   164  
   165  func TestSampledLFUDel(t *testing.T) {
   166  	e := newSampledLFU(4)
   167  	e.add(1, 1)
   168  	e.add(2, 2)
   169  	e.del(2)
   170  	require.Equal(t, int64(1), e.used)
   171  	_, ok := e.keyCosts[2]
   172  	require.False(t, ok)
   173  	e.del(4)
   174  }
   175  
   176  func TestSampledLFUUpdate(t *testing.T) {
   177  	e := newSampledLFU(4)
   178  	e.add(1, 1)
   179  	require.True(t, e.updateIfHas(1, 2))
   180  	require.Equal(t, int64(2), e.used)
   181  	require.False(t, e.updateIfHas(2, 2))
   182  }
   183  
   184  func TestSampledLFUClear(t *testing.T) {
   185  	e := newSampledLFU(4)
   186  	e.add(1, 1)
   187  	e.add(2, 2)
   188  	e.add(3, 1)
   189  	e.clear()
   190  	require.Equal(t, 0, len(e.keyCosts))
   191  	require.Equal(t, int64(0), e.used)
   192  }
   193  
   194  func TestSampledLFURoom(t *testing.T) {
   195  	e := newSampledLFU(16)
   196  	e.add(1, 1)
   197  	e.add(2, 2)
   198  	e.add(3, 3)
   199  	require.Equal(t, int64(6), e.roomLeft(4))
   200  }
   201  
   202  func TestSampledLFUSample(t *testing.T) {
   203  	e := newSampledLFU(16)
   204  	e.add(4, 4)
   205  	e.add(5, 5)
   206  	sample := e.fillSample([]*policyPair{
   207  		{1, 1},
   208  		{2, 2},
   209  		{3, 3},
   210  	})
   211  	k := sample[len(sample)-1].key
   212  	require.Equal(t, 5, len(sample))
   213  	require.NotEqual(t, 1, k)
   214  	require.NotEqual(t, 2, k)
   215  	require.NotEqual(t, 3, k)
   216  	require.Equal(t, len(sample), len(e.fillSample(sample)))
   217  	e.del(5)
   218  	sample = e.fillSample(sample[:len(sample)-2])
   219  	require.Equal(t, 4, len(sample))
   220  }
   221  
   222  func TestTinyLFUIncrement(t *testing.T) {
   223  	a := newTinyLFU(4)
   224  	a.Increment(1)
   225  	a.Increment(1)
   226  	a.Increment(1)
   227  	require.True(t, a.door.Has(1))
   228  	require.Equal(t, int64(2), a.freq.Estimate(1))
   229  
   230  	a.Increment(1)
   231  	require.False(t, a.door.Has(1))
   232  	require.Equal(t, int64(1), a.freq.Estimate(1))
   233  }
   234  
   235  func TestTinyLFUEstimate(t *testing.T) {
   236  	a := newTinyLFU(8)
   237  	a.Increment(1)
   238  	a.Increment(1)
   239  	a.Increment(1)
   240  	require.Equal(t, int64(3), a.Estimate(1))
   241  	require.Equal(t, int64(0), a.Estimate(2))
   242  }
   243  
   244  func TestTinyLFUPush(t *testing.T) {
   245  	a := newTinyLFU(16)
   246  	a.Push([]uint64{1, 2, 2, 3, 3, 3})
   247  	require.Equal(t, int64(1), a.Estimate(1))
   248  	require.Equal(t, int64(2), a.Estimate(2))
   249  	require.Equal(t, int64(3), a.Estimate(3))
   250  	require.Equal(t, int64(6), a.incrs)
   251  }
   252  
   253  func TestTinyLFUClear(t *testing.T) {
   254  	a := newTinyLFU(16)
   255  	a.Push([]uint64{1, 3, 3, 3})
   256  	a.clear()
   257  	require.Equal(t, int64(0), a.incrs)
   258  	require.Equal(t, int64(0), a.Estimate(3))
   259  }