github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/nbs/manifest_cache_test.go (about) 1 // Copyright 2019 Dolthub, Inc. 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 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2016 Attic Labs, Inc. All rights reserved. 19 // Licensed under the Apache License, version 2.0: 20 // http://www.apache.org/licenses/LICENSE-2.0 21 22 package nbs 23 24 import ( 25 "testing" 26 "time" 27 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 ) 31 32 func TestSizeCache(t *testing.T) { 33 defSize := manifestContents{}.size() 34 35 t.Run("GetAndPut", func(t *testing.T) { 36 assert := assert.New(t) 37 38 c := newManifestCache(2 * defSize) 39 t1 := time.Now() 40 dbA, contentsA := "dbA", manifestContents{lock: computeAddr([]byte("lockA"))} 41 dbB, contentsB := "dbB", manifestContents{lock: computeAddr([]byte("lockB"))} 42 43 err := c.Put(dbA, contentsA, t1) 44 require.NoError(t, err) 45 err = c.Put(dbB, contentsB, t1) 46 require.NoError(t, err) 47 48 cont, _, present := c.Get(dbA) 49 assert.True(present) 50 assert.Equal(contentsA, cont) 51 52 cont, _, present = c.Get(dbB) 53 assert.True(present) 54 assert.Equal(contentsB, cont) 55 }) 56 57 t.Run("PutDropsLRU", func(t *testing.T) { 58 assert := assert.New(t) 59 60 capacity := uint64(5) 61 c := newManifestCache(capacity * defSize) 62 keys := []string{"db1", "db2", "db3", "db4", "db5", "db6", "db7", "db8", "db9"} 63 for i, v := range keys { 64 err := c.Put(v, manifestContents{}, time.Now()) 65 require.NoError(t, err) 66 expected := uint64(i + 1) 67 if expected >= capacity { 68 expected = capacity 69 } 70 assert.Equal(expected*defSize, c.totalSize) 71 } 72 73 lru := len(keys) - int(capacity) 74 for _, db := range keys[:lru] { 75 _, _, present := c.Get(db) 76 assert.False(present) 77 } 78 for _, db := range keys[lru:] { 79 _, _, present := c.Get(db) 80 assert.True(present) 81 } 82 83 // Bump |keys[lru]| to the back of the queue, making |keys[lru+1]| the next one to be dropped 84 _, _, ok := c.Get(keys[lru]) 85 assert.True(ok) 86 lru++ 87 err := c.Put("novel", manifestContents{}, time.Now()) 88 require.NoError(t, err) 89 _, _, ok = c.Get(keys[lru]) 90 assert.False(ok) 91 // |keys[lru]| is gone, so |keys[lru+1]| is next 92 lru++ 93 94 // Putting a bigger value will dump multiple existing entries 95 err = c.Put("big", manifestContents{vers: "big version"}, time.Now()) 96 require.NoError(t, err) 97 _, _, ok = c.Get(keys[lru]) 98 assert.False(ok) 99 lru++ 100 _, _, ok = c.Get(keys[lru]) 101 assert.False(ok) 102 lru++ 103 104 // Make sure expected stuff is still in the cache 105 for i := lru; i < len(keys); i++ { 106 _, _, ok := c.Get(keys[i]) 107 assert.True(ok) 108 } 109 for _, key := range []string{"novel", "big"} { 110 _, _, ok := c.Get(key) 111 assert.True(ok) 112 } 113 }) 114 115 t.Run("TooLargeValue", func(t *testing.T) { 116 c := newManifestCache(16) 117 err := c.Put("db", manifestContents{}, time.Now()) 118 require.NoError(t, err) 119 _, _, ok := c.Get("db") 120 assert.False(t, ok) 121 }) 122 123 t.Run("ZeroSizeCache", func(t *testing.T) { 124 c := newManifestCache(0) 125 err := c.Put("db", manifestContents{}, time.Now()) 126 require.NoError(t, err) 127 _, _, ok := c.Get("db") 128 assert.False(t, ok) 129 }) 130 131 }