github.com/matrixorigin/matrixone@v1.2.0/pkg/fileservice/memorycache/lrucache/lru_test.go (about)

     1  // Copyright 2022 Matrix Origin
     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  
    15  package lrucache
    16  
    17  import (
    18  	"context"
    19  	"sync"
    20  	"testing"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/pb/query"
    23  	"github.com/stretchr/testify/assert"
    24  )
    25  
    26  func TestLRU(t *testing.T) {
    27  	l := New[int, Bytes](1, nil, nil, nil)
    28  	ctx := context.Background()
    29  
    30  	l.Set(ctx, 1, []byte{42})
    31  	val, _ := l.Get(ctx, 1)
    32  	assert.Equal(t, Bytes([]byte{42}), val)
    33  
    34  	l.Set(ctx, 2, []byte{43})
    35  	val, _ = l.Get(ctx, 2)
    36  	assert.Equal(t, Bytes([]byte{43}), val)
    37  }
    38  
    39  func TestLRUCallbacks(t *testing.T) {
    40  	ctx := context.Background()
    41  
    42  	postSetInvokedMap := make(map[int]bool)
    43  
    44  	evictEntryMap := make(map[int][]byte)
    45  	postEvictInvokedMap := make(map[int]bool)
    46  
    47  	l := New(1,
    48  		func(key int, _ Bytes) {
    49  			postSetInvokedMap[key] = true
    50  		},
    51  		nil,
    52  		func(key int, value Bytes) {
    53  			evictEntryMap[key] = value
    54  			postEvictInvokedMap[key] = true
    55  		})
    56  	s := &l.shards[0]
    57  	s.capacity = 1
    58  
    59  	// PostSet
    60  	h := l.hasher.Hash(1)
    61  	s.Set(ctx, h, 1, []byte{42})
    62  	assert.True(t, postSetInvokedMap[1])
    63  	postSetInvokedMap[1] = false // resetting
    64  	assert.False(t, postEvictInvokedMap[1])
    65  
    66  	// PostSet and PostEvict
    67  	h = l.hasher.Hash(2)
    68  	s.Set(ctx, h, 2, []byte{44})
    69  	assert.True(t, postEvictInvokedMap[1])        //postEvictInvokedMap is updated by PostEvict
    70  	assert.Equal(t, []byte{42}, evictEntryMap[1]) //evictEntryMap is updated by PostEvict
    71  }
    72  
    73  func BenchmarkLRUSet(b *testing.B) {
    74  	var k query.CacheKey
    75  
    76  	k.Path = "tmp"
    77  	ctx := context.Background()
    78  	const capacity = 1024
    79  	l := New[query.CacheKey, Bytes](capacity, nil, nil, nil)
    80  	v := make([]byte, 1)
    81  	b.ResetTimer()
    82  	for i := 0; i < b.N; i++ {
    83  		k.Offset = int64(i) % (capacity)
    84  		v[0] = byte(i)
    85  		l.Set(ctx, k, v)
    86  	}
    87  }
    88  
    89  func BenchmarkLRUParallelSet(b *testing.B) {
    90  	ctx := context.Background()
    91  	const capacity = 1024
    92  	l := New[query.CacheKey, Bytes](capacity, nil, nil, nil)
    93  	b.ResetTimer()
    94  	b.RunParallel(func(pb *testing.PB) {
    95  		var k query.CacheKey
    96  
    97  		k.Path = "tmp"
    98  		v := make([]byte, 1)
    99  		for i := 0; pb.Next(); i++ {
   100  			k.Offset = int64(i) % (capacity)
   101  			v[0] = byte(i)
   102  			l.Set(ctx, k, v)
   103  		}
   104  	})
   105  }
   106  
   107  func BenchmarkLRUParallelSetOrGet(b *testing.B) {
   108  	ctx := context.Background()
   109  	const capacity = 1024
   110  	l := New[query.CacheKey, Bytes](capacity, nil, nil, nil)
   111  	b.ResetTimer()
   112  	b.RunParallel(func(pb *testing.PB) {
   113  		var k query.CacheKey
   114  
   115  		k.Path = "tmp"
   116  		v := make([]byte, 1)
   117  		for i := 0; pb.Next(); i++ {
   118  			k.Offset = int64(i) % (capacity)
   119  			v[0] = byte(i)
   120  			l.Set(ctx, k, v)
   121  			if i%2 == 0 {
   122  				l.Get(ctx, k)
   123  			}
   124  		}
   125  	})
   126  }
   127  
   128  func BenchmarkLRULargeParallelSetOrGet(b *testing.B) {
   129  	var wg sync.WaitGroup
   130  
   131  	ctx := context.Background()
   132  	const capacity = 1024
   133  	l := New[query.CacheKey, Bytes](capacity, nil, nil, nil)
   134  	b.ResetTimer()
   135  	for i := 0; i < 1000; i++ {
   136  		wg.Add(1)
   137  		go func() {
   138  			defer wg.Done()
   139  			var k query.CacheKey
   140  			k.Path = "tmp"
   141  			v := make([]byte, 1)
   142  			for i := 0; i < b.N; i++ {
   143  				k.Offset = int64(i) % (capacity * 10)
   144  				v[0] = byte(i)
   145  				l.Set(ctx, k, v)
   146  				if i%2 == 0 {
   147  					l.Get(ctx, k)
   148  				}
   149  			}
   150  		}()
   151  	}
   152  	wg.Wait()
   153  }