github.com/iotexproject/iotex-core@v1.14.1-rc1/db/range_index_test.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package db 7 8 import ( 9 "context" 10 "math/rand" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 15 "github.com/iotexproject/iotex-core/testutil" 16 ) 17 18 func TestRangeIndex(t *testing.T) { 19 require := require.New(t) 20 21 rangeTests := []struct { 22 k uint64 23 v []byte 24 }{ 25 {1, []byte("beyond")}, 26 {7, []byte("seven")}, 27 {29, []byte("twenty-nine")}, 28 {100, []byte("hundred")}, 29 {999, []byte("nine-nine-nine")}, 30 } 31 32 path := "test-indexer" 33 testPath, err := testutil.PathOfTempFile(path) 34 require.NoError(err) 35 cfg := DefaultConfig 36 cfg.DbPath = testPath 37 defer testutil.CleanupPath(testPath) 38 39 kv := NewBoltDB(cfg) 40 require.NotNil(kv) 41 42 require.NoError(kv.Start(context.Background())) 43 defer func() { 44 require.NoError(kv.Stop(context.Background())) 45 }() 46 47 index, err := NewRangeIndex(kv, []byte("test"), NotExist) 48 require.NoError(err) 49 v, err := index.Get(0) 50 require.NoError(err) 51 require.Equal(NotExist, v) 52 v, err = index.Get(1) 53 require.NoError(err) 54 require.Equal(NotExist, v) 55 56 // cannot insert 0 57 require.Error(index.Insert(0, NotExist)) 58 59 for i, e := range rangeTests { 60 require.NoError(index.Insert(e.k, e.v)) 61 if i == 0 { 62 v, err = index.Get(rangeTests[0].k) 63 require.NoError(err) 64 require.Equal(rangeTests[0].v, v) 65 continue 66 } 67 // test 5 random keys between the new and previous insertion 68 gap := e.k - rangeTests[i-1].k 69 for j := 0; j < 5; j++ { 70 k := rangeTests[i-1].k + uint64(rand.Intn(int(gap))) 71 v, err = index.Get(k) 72 require.NoError(err) 73 require.Equal(rangeTests[i-1].v, v) 74 } 75 v, err = index.Get(e.k - 1) 76 require.NoError(err) 77 require.Equal(rangeTests[i-1].v, v) 78 v, err = index.Get(e.k) 79 require.NoError(err) 80 require.Equal(e.v, v) 81 82 // test 5 random keys beyond new insertion 83 for j := 0; j < 5; j++ { 84 k := e.k + uint64(rand.Int()) 85 v, err = index.Get(k) 86 require.NoError(err) 87 require.Equal(e.v, v) 88 } 89 } 90 91 // delete rangeTests[1].k 92 require.NoError(index.Delete(rangeTests[0].k)) 93 require.NoError(index.Delete(rangeTests[1].k)) 94 v, err = index.Get(rangeTests[1].k) 95 require.NoError(err) 96 require.Equal(NotExist, v) 97 for i := 2; i < len(rangeTests); i++ { 98 v, err = index.Get(rangeTests[i].k) 99 require.NoError(err) 100 require.Equal(rangeTests[i].v, v) 101 v, err = index.Get(rangeTests[i].k + 1) 102 require.NoError(err) 103 require.Equal(rangeTests[i].v, v) 104 } 105 106 // delete rangeTests[3].k 107 require.NoError(index.Delete(rangeTests[3].k)) 108 for i := 2; i <= 3; i++ { 109 v, err = index.Get(rangeTests[i].k) 110 require.NoError(err) 111 require.Equal(rangeTests[2].v, v) 112 v, err = index.Get(rangeTests[i].k + 1) 113 require.NoError(err) 114 require.Equal(rangeTests[2].v, v) 115 } 116 117 // key 4 not affected 118 v, err = index.Get(rangeTests[4].k) 119 require.NoError(err) 120 require.Equal(rangeTests[4].v, v) 121 v, err = index.Get(rangeTests[4].k + 1) 122 require.NoError(err) 123 require.Equal(rangeTests[4].v, v) 124 125 // add rangeTests[3].k back with a diff value 126 rangeTests[3].v = []byte("not-hundred") 127 require.NoError(index.Insert(rangeTests[3].k, rangeTests[3].v)) 128 for i := 2; i < len(rangeTests); i++ { 129 v, err = index.Get(rangeTests[i].k) 130 require.NoError(err) 131 require.Equal(rangeTests[i].v, v) 132 v, err = index.Get(rangeTests[i].k + 1) 133 require.NoError(err) 134 require.Equal(rangeTests[i].v, v) 135 } 136 137 // purge rangeTests[3].k 138 require.NoError(index.Purge(rangeTests[3].k)) 139 for i := 1; i <= 3; i++ { 140 v, err = index.Get(rangeTests[i].k) 141 require.NoError(err) 142 require.Equal(NotExist, v) 143 v, err = index.Get(rangeTests[i].k + 1) 144 require.NoError(err) 145 require.Equal(NotExist, v) 146 } 147 148 // key 4 not affected 149 v, err = index.Get(rangeTests[4].k) 150 require.NoError(err) 151 require.Equal(rangeTests[4].v, v) 152 v, err = index.Get(rangeTests[4].k + 1) 153 require.NoError(err) 154 require.Equal(rangeTests[4].v, v) 155 } 156 157 func TestRangeIndex2(t *testing.T) { 158 require := require.New(t) 159 160 path := "test-ranger" 161 testPath, err := testutil.PathOfTempFile(path) 162 require.NoError(err) 163 cfg := DefaultConfig 164 cfg.DbPath = testPath 165 defer testutil.CleanupPath(testPath) 166 167 kv := NewBoltDB(cfg) 168 require.NotNil(kv) 169 170 require.NoError(kv.Start(context.Background())) 171 defer func() { 172 require.NoError(kv.Stop(context.Background())) 173 }() 174 175 testNS := []byte("test") 176 index, err := NewRangeIndex(kv, testNS, NotExist) 177 require.NoError(err) 178 // special case: insert 1 179 require.NoError(index.Insert(1, []byte("1"))) 180 v, err := index.Get(5) 181 require.NoError(err) 182 require.Equal([]byte("1"), v) 183 // remove 1 184 require.NoError(index.Purge(1)) 185 // insert 7 186 require.NoError(index.Insert(7, []byte("7"))) 187 // Case I: key before 7 188 for i := uint64(1); i < 6; i++ { 189 v, err = index.Get(i) 190 require.NoError(err) 191 require.Equal(v, NotExist) 192 } 193 // Case II: key is 7 and greater than 7 194 for i := uint64(7); i < 10; i++ { 195 v, err = index.Get(i) 196 require.NoError(err) 197 require.Equal([]byte("7"), v) 198 } 199 // Case III: duplicate key 200 require.NoError(index.Insert(7, []byte("7777"))) 201 for i := uint64(7); i < 10; i++ { 202 v, err = index.Get(i) 203 require.NoError(err) 204 require.Equal([]byte("7777"), v) 205 } 206 // Case IV: delete key less than 7 207 require.NoError(index.Insert(66, []byte("66"))) 208 for i := uint64(1); i < 7; i++ { 209 err = index.Delete(i) 210 require.NoError(err) 211 } 212 v, err = index.Get(7) 213 require.NoError(err) 214 require.Equal([]byte("7777"), v) 215 // Case V: delete key 7 216 require.NoError(index.Purge(10)) 217 for i := uint64(1); i < 66; i++ { 218 v, err = index.Get(i) 219 require.NoError(err) 220 require.Equal(v, NotExist) 221 } 222 for i := uint64(66); i < 70; i++ { 223 v, err = index.Get(i) 224 require.NoError(err) 225 require.Equal([]byte("66"), v) 226 } 227 // Case VI: delete key before 80,all keys deleted 228 require.NoError(index.Insert(70, []byte("70"))) 229 require.NoError(index.Insert(80, []byte("80"))) 230 require.NoError(index.Insert(91, []byte("91"))) 231 require.NoError(index.Purge(79)) 232 for i := uint64(1); i < 80; i++ { 233 v, err = index.Get(i) 234 require.NoError(err) 235 require.Equal(v, NotExist) 236 } 237 for i := uint64(80); i < 91; i++ { 238 v, err = index.Get(i) 239 require.NoError(err) 240 require.Equal([]byte("80"), v) 241 } 242 for i := uint64(91); i < 100; i++ { 243 v, err = index.Get(i) 244 require.NoError(err) 245 require.Equal([]byte("91"), v) 246 } 247 }