github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/nbs/table_set_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 "context" 26 "testing" 27 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 ) 31 32 var testChunks = [][]byte{[]byte("hello2"), []byte("goodbye2"), []byte("badbye2")} 33 34 func TestTableSetPrependEmpty(t *testing.T) { 35 ts := newFakeTableSet().Prepend(context.Background(), newMemTable(testMemTableSize), &Stats{}) 36 specs, err := ts.ToSpecs() 37 require.NoError(t, err) 38 assert.Empty(t, specs) 39 } 40 41 func TestTableSetPrepend(t *testing.T) { 42 assert := assert.New(t) 43 ts := newFakeTableSet() 44 specs, err := ts.ToSpecs() 45 require.NoError(t, err) 46 assert.Empty(specs) 47 mt := newMemTable(testMemTableSize) 48 mt.addChunk(computeAddr(testChunks[0]), testChunks[0]) 49 ts = ts.Prepend(context.Background(), mt, &Stats{}) 50 51 firstSpecs, err := ts.ToSpecs() 52 require.NoError(t, err) 53 assert.Len(firstSpecs, 1) 54 55 mt = newMemTable(testMemTableSize) 56 mt.addChunk(computeAddr(testChunks[1]), testChunks[1]) 57 mt.addChunk(computeAddr(testChunks[2]), testChunks[2]) 58 ts = ts.Prepend(context.Background(), mt, &Stats{}) 59 60 secondSpecs, err := ts.ToSpecs() 61 require.NoError(t, err) 62 assert.Len(secondSpecs, 2) 63 assert.Equal(firstSpecs, secondSpecs[1:]) 64 } 65 66 func TestTableSetToSpecsExcludesEmptyTable(t *testing.T) { 67 assert := assert.New(t) 68 ts := newFakeTableSet() 69 specs, err := ts.ToSpecs() 70 require.NoError(t, err) 71 assert.Empty(specs) 72 mt := newMemTable(testMemTableSize) 73 mt.addChunk(computeAddr(testChunks[0]), testChunks[0]) 74 ts = ts.Prepend(context.Background(), mt, &Stats{}) 75 76 mt = newMemTable(testMemTableSize) 77 ts = ts.Prepend(context.Background(), mt, &Stats{}) 78 79 mt = newMemTable(testMemTableSize) 80 mt.addChunk(computeAddr(testChunks[1]), testChunks[1]) 81 mt.addChunk(computeAddr(testChunks[2]), testChunks[2]) 82 ts = ts.Prepend(context.Background(), mt, &Stats{}) 83 84 specs, err = ts.ToSpecs() 85 require.NoError(t, err) 86 assert.Len(specs, 2) 87 } 88 89 func TestTableSetFlattenExcludesEmptyTable(t *testing.T) { 90 assert := assert.New(t) 91 ts := newFakeTableSet() 92 specs, err := ts.ToSpecs() 93 require.NoError(t, err) 94 assert.Empty(specs) 95 mt := newMemTable(testMemTableSize) 96 mt.addChunk(computeAddr(testChunks[0]), testChunks[0]) 97 ts = ts.Prepend(context.Background(), mt, &Stats{}) 98 99 mt = newMemTable(testMemTableSize) 100 ts = ts.Prepend(context.Background(), mt, &Stats{}) 101 102 mt = newMemTable(testMemTableSize) 103 mt.addChunk(computeAddr(testChunks[1]), testChunks[1]) 104 mt.addChunk(computeAddr(testChunks[2]), testChunks[2]) 105 ts = ts.Prepend(context.Background(), mt, &Stats{}) 106 107 ts, err = ts.Flatten() 108 require.NoError(t, err) 109 assert.EqualValues(ts.Size(), 2) 110 } 111 112 func TestTableSetExtract(t *testing.T) { 113 assert := assert.New(t) 114 ts := newFakeTableSet() 115 specs, err := ts.ToSpecs() 116 require.NoError(t, err) 117 assert.Empty(specs) 118 119 // Put in one table 120 mt := newMemTable(testMemTableSize) 121 mt.addChunk(computeAddr(testChunks[0]), testChunks[0]) 122 ts = ts.Prepend(context.Background(), mt, &Stats{}) 123 124 // Put in a second 125 mt = newMemTable(testMemTableSize) 126 mt.addChunk(computeAddr(testChunks[1]), testChunks[1]) 127 mt.addChunk(computeAddr(testChunks[2]), testChunks[2]) 128 ts = ts.Prepend(context.Background(), mt, &Stats{}) 129 130 chunkChan := make(chan extractRecord) 131 go func() { 132 defer close(chunkChan) 133 err := ts.extract(context.Background(), chunkChan) 134 135 require.NoError(t, err) 136 }() 137 i := 0 138 for rec := range chunkChan { 139 a := computeAddr(testChunks[i]) 140 assert.NotNil(rec.data, "Nothing for", a) 141 assert.Equal(testChunks[i], rec.data, "Item %d: %s != %s", i, string(testChunks[i]), string(rec.data)) 142 assert.Equal(a, rec.a) 143 i++ 144 } 145 } 146 147 func TestTableSetRebase(t *testing.T) { 148 assert := assert.New(t) 149 persister := newFakeTablePersister() 150 151 insert := func(ts tableSet, chunks ...[]byte) tableSet { 152 for _, c := range chunks { 153 mt := newMemTable(testMemTableSize) 154 mt.addChunk(computeAddr(c), c) 155 ts = ts.Prepend(context.Background(), mt, &Stats{}) 156 } 157 return ts 158 } 159 fullTS := newTableSet(persister) 160 specs, err := fullTS.ToSpecs() 161 require.NoError(t, err) 162 assert.Empty(specs) 163 fullTS = insert(fullTS, testChunks...) 164 fullTS, err = fullTS.Flatten() 165 require.NoError(t, err) 166 167 ts := newTableSet(persister) 168 ts = insert(ts, testChunks[0]) 169 assert.Equal(1, ts.Size()) 170 ts, err = ts.Flatten() 171 require.NoError(t, err) 172 ts = insert(ts, []byte("novel")) 173 174 specs, err = fullTS.ToSpecs() 175 require.NoError(t, err) 176 ts, err = ts.Rebase(context.Background(), specs, nil) 177 require.NoError(t, err) 178 assert.Equal(4, ts.Size()) 179 } 180 181 func TestTableSetPhysicalLen(t *testing.T) { 182 assert := assert.New(t) 183 ts := newFakeTableSet() 184 specs, err := ts.ToSpecs() 185 require.NoError(t, err) 186 assert.Empty(specs) 187 mt := newMemTable(testMemTableSize) 188 mt.addChunk(computeAddr(testChunks[0]), testChunks[0]) 189 ts = ts.Prepend(context.Background(), mt, &Stats{}) 190 191 mt = newMemTable(testMemTableSize) 192 mt.addChunk(computeAddr(testChunks[1]), testChunks[1]) 193 mt.addChunk(computeAddr(testChunks[2]), testChunks[2]) 194 ts = ts.Prepend(context.Background(), mt, &Stats{}) 195 196 assert.True(mustUint64(ts.physicalLen()) > indexSize(mustUint32(ts.count()))) 197 }