github.com/matrixorigin/matrixone@v0.7.0/pkg/lockservice/storage_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 lockservice
    16  
    17  import (
    18  	"encoding/binary"
    19  	"math/rand"
    20  	"testing"
    21  
    22  	"github.com/stretchr/testify/assert"
    23  )
    24  
    25  var (
    26  	storages = map[string]func() LockStorage{
    27  		"btree": newBtreeBasedStorage,
    28  	}
    29  )
    30  
    31  func TestAdd(t *testing.T) {
    32  	for name, factory := range storages {
    33  		t.Run(name, func(t *testing.T) {
    34  			s := factory()
    35  
    36  			k1 := []byte("k1")
    37  			s.Add(k1, Lock{txnID: k1})
    38  			assert.Equal(t, 1, s.Len())
    39  
    40  			v, ok := s.Get(k1)
    41  			assert.True(t, ok)
    42  			assert.Equal(t, k1, v.txnID)
    43  		})
    44  	}
    45  }
    46  
    47  func TestDelete(t *testing.T) {
    48  	for name, factory := range storages {
    49  		t.Run(name, func(t *testing.T) {
    50  			s := factory()
    51  
    52  			k1 := []byte("k1")
    53  			k2 := []byte("k2")
    54  			s.Add(k1, Lock{})
    55  			s.Add(k2, Lock{})
    56  
    57  			s.Delete(k1)
    58  			assert.Equal(t, 1, s.Len())
    59  			v, ok := s.Get(k1)
    60  			assert.False(t, ok)
    61  			assert.Empty(t, v)
    62  
    63  			s.Delete(k2)
    64  			assert.Equal(t, 0, s.Len())
    65  			v, ok = s.Get(k2)
    66  			assert.False(t, ok)
    67  			assert.Empty(t, v)
    68  		})
    69  	}
    70  }
    71  
    72  func TestSeek(t *testing.T) {
    73  	for name, factory := range storages {
    74  		t.Run(name, func(t *testing.T) {
    75  			s := factory()
    76  
    77  			k1 := []byte("k1")
    78  			k2 := []byte("k2")
    79  			k3 := []byte("k3")
    80  
    81  			checkSeek(t, s, k1, nil, nil)
    82  
    83  			s.Add(k1, Lock{txnID: k1})
    84  			checkSeek(t, s, k1, k1, k1)
    85  			checkSeek(t, s, k2, nil, nil)
    86  			checkSeek(t, s, k3, nil, nil)
    87  
    88  			s.Add(k2, Lock{txnID: k2})
    89  			checkSeek(t, s, k1, k1, k1)
    90  			checkSeek(t, s, k2, k2, k2)
    91  			checkSeek(t, s, k3, nil, nil)
    92  
    93  			s.Add(k3, Lock{txnID: k3})
    94  			checkSeek(t, s, k1, k1, k1)
    95  			checkSeek(t, s, k2, k2, k2)
    96  			checkSeek(t, s, k3, k3, k3)
    97  		})
    98  	}
    99  }
   100  
   101  func BenchmarkAdd(b *testing.B) {
   102  	for name, factory := range storages {
   103  		b.Run(name, func(b *testing.B) {
   104  			s := factory()
   105  			keys := make([][]byte, b.N)
   106  			for i := 0; i < b.N; i++ {
   107  				keys[i] = make([]byte, 4)
   108  				binary.BigEndian.PutUint32(keys[i], rand.Uint32())
   109  			}
   110  
   111  			b.ResetTimer()
   112  			for i := 0; i < b.N; i++ {
   113  				s.Add(keys[i], Lock{txnID: keys[i]})
   114  			}
   115  		})
   116  	}
   117  }
   118  
   119  func BenchmarkSeek(b *testing.B) {
   120  	for name, factory := range storages {
   121  		b.Run(name, func(b *testing.B) {
   122  			s := factory()
   123  			keys := make([][]byte, b.N)
   124  			for i := 0; i < b.N; i++ {
   125  				keys[i] = make([]byte, 4)
   126  				binary.BigEndian.PutUint32(keys[i], rand.Uint32())
   127  			}
   128  
   129  			b.ResetTimer()
   130  			for i := 0; i < b.N; i++ {
   131  				s.Seek(keys[i])
   132  			}
   133  		})
   134  	}
   135  }
   136  
   137  func BenchmarkDelete(b *testing.B) {
   138  	for name, factory := range storages {
   139  		b.Run(name, func(b *testing.B) {
   140  			s := factory()
   141  			keys := make([][]byte, b.N)
   142  			for i := 0; i < b.N; i++ {
   143  				keys[i] = make([]byte, 4)
   144  				binary.BigEndian.PutUint32(keys[i], rand.Uint32())
   145  				s.Add(keys[i], Lock{txnID: keys[i]})
   146  			}
   147  
   148  			b.ResetTimer()
   149  			for i := 0; i < b.N; i++ {
   150  				s.Delete(keys[i])
   151  			}
   152  		})
   153  	}
   154  }
   155  
   156  func checkSeek(t *testing.T, s LockStorage, key []byte, expectKey, expectValue []byte) {
   157  	k, v, ok := s.Seek(key)
   158  	if len(expectKey) == 0 {
   159  		assert.Empty(t, k)
   160  		assert.Empty(t, v)
   161  		assert.False(t, ok)
   162  		return
   163  	}
   164  	assert.Equal(t, expectKey, k)
   165  	assert.Equal(t, expectValue, v.txnID)
   166  	assert.True(t, ok)
   167  }