github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/internal/manifest/version_test.go (about) 1 // Copyright 2012 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package manifest 6 7 import ( 8 "fmt" 9 "strings" 10 "sync" 11 "testing" 12 13 "github.com/petermattis/pebble/internal/base" 14 ) 15 16 func ikey(s string) InternalKey { 17 return base.MakeInternalKey([]byte(s), 0, base.InternalKeyKindSet) 18 } 19 20 func TestIkeyRange(t *testing.T) { 21 testCases := []struct { 22 input, want string 23 }{ 24 { 25 "", 26 "-", 27 }, 28 { 29 "a-e", 30 "a-e", 31 }, 32 { 33 "a-e a-e", 34 "a-e", 35 }, 36 { 37 "c-g a-e", 38 "a-g", 39 }, 40 { 41 "a-e c-g a-e", 42 "a-g", 43 }, 44 { 45 "b-d f-g", 46 "b-g", 47 }, 48 { 49 "d-e b-d", 50 "b-e", 51 }, 52 { 53 "e-e", 54 "e-e", 55 }, 56 { 57 "f-g e-e d-e c-g b-d a-e", 58 "a-g", 59 }, 60 } 61 for _, tc := range testCases { 62 var f []FileMetadata 63 if tc.input != "" { 64 for _, s := range strings.Split(tc.input, " ") { 65 f = append(f, FileMetadata{ 66 Smallest: ikey(s[0:1]), 67 Largest: ikey(s[2:3]), 68 }) 69 } 70 } 71 72 smallest0, largest0 := KeyRange(base.DefaultComparer.Compare, f, nil) 73 got0 := string(smallest0.UserKey) + "-" + string(largest0.UserKey) 74 if got0 != tc.want { 75 t.Errorf("first []fileMetadata is %v\ngot %s\nwant %s", tc.input, got0, tc.want) 76 } 77 78 smallest1, largest1 := KeyRange(base.DefaultComparer.Compare, nil, f) 79 got1 := string(smallest1.UserKey) + "-" + string(largest1.UserKey) 80 if got1 != tc.want { 81 t.Errorf("second []fileMetadata is %v\ngot %s\nwant %s", tc.input, got1, tc.want) 82 } 83 } 84 } 85 86 func TestOverlaps(t *testing.T) { 87 m00 := FileMetadata{ 88 FileNum: 700, 89 Size: 1, 90 Smallest: base.ParseInternalKey("b.SET.7008"), 91 Largest: base.ParseInternalKey("e.SET.7009"), 92 } 93 m01 := FileMetadata{ 94 FileNum: 701, 95 Size: 1, 96 Smallest: base.ParseInternalKey("c.SET.7018"), 97 Largest: base.ParseInternalKey("f.SET.7019"), 98 } 99 m02 := FileMetadata{ 100 FileNum: 702, 101 Size: 1, 102 Smallest: base.ParseInternalKey("f.SET.7028"), 103 Largest: base.ParseInternalKey("g.SET.7029"), 104 } 105 m03 := FileMetadata{ 106 FileNum: 703, 107 Size: 1, 108 Smallest: base.ParseInternalKey("x.SET.7038"), 109 Largest: base.ParseInternalKey("y.SET.7039"), 110 } 111 m04 := FileMetadata{ 112 FileNum: 704, 113 Size: 1, 114 Smallest: base.ParseInternalKey("n.SET.7048"), 115 Largest: base.ParseInternalKey("p.SET.7049"), 116 } 117 m05 := FileMetadata{ 118 FileNum: 705, 119 Size: 1, 120 Smallest: base.ParseInternalKey("p.SET.7058"), 121 Largest: base.ParseInternalKey("p.SET.7059"), 122 } 123 m06 := FileMetadata{ 124 FileNum: 706, 125 Size: 1, 126 Smallest: base.ParseInternalKey("p.SET.7068"), 127 Largest: base.ParseInternalKey("u.SET.7069"), 128 } 129 m07 := FileMetadata{ 130 FileNum: 707, 131 Size: 1, 132 Smallest: base.ParseInternalKey("r.SET.7078"), 133 Largest: base.ParseInternalKey("s.SET.7079"), 134 } 135 136 m10 := FileMetadata{ 137 FileNum: 710, 138 Size: 1, 139 Smallest: base.ParseInternalKey("d.SET.7108"), 140 Largest: base.ParseInternalKey("g.SET.7109"), 141 } 142 m11 := FileMetadata{ 143 FileNum: 711, 144 Size: 1, 145 Smallest: base.ParseInternalKey("g.SET.7118"), 146 Largest: base.ParseInternalKey("j.SET.7119"), 147 } 148 m12 := FileMetadata{ 149 FileNum: 712, 150 Size: 1, 151 Smallest: base.ParseInternalKey("n.SET.7128"), 152 Largest: base.ParseInternalKey("p.SET.7129"), 153 } 154 m13 := FileMetadata{ 155 FileNum: 713, 156 Size: 1, 157 Smallest: base.ParseInternalKey("p.SET.7138"), 158 Largest: base.ParseInternalKey("p.SET.7139"), 159 } 160 m14 := FileMetadata{ 161 FileNum: 714, 162 Size: 1, 163 Smallest: base.ParseInternalKey("p.SET.7148"), 164 Largest: base.ParseInternalKey("u.SET.7149"), 165 } 166 167 v := Version{ 168 Files: [NumLevels][]FileMetadata{ 169 0: {m00, m01, m02, m03, m04, m05, m06, m07}, 170 1: {m10, m11, m12, m13, m14}, 171 }, 172 } 173 174 testCases := []struct { 175 level int 176 ukey0, ukey1 string 177 want string 178 }{ 179 // Level 0: m00=b-e, m01=c-f, m02=f-g, m03=x-y, m04=n-p, m05=p-p, m06=p-u, m07=r-s. 180 // Note that: 181 // - the slice isn't sorted (e.g. m02=f-g, m03=x-y, m04=n-p), 182 // - m00 and m01 overlap (not just touch), 183 // - m06 contains m07, 184 // - m00, m01 and m02 transitively overlap/touch each other, and 185 // - m04, m05, m06 and m07 transitively overlap/touch each other. 186 {0, "a", "a", ""}, 187 {0, "a", "b", "m00 m01 m02"}, 188 {0, "a", "d", "m00 m01 m02"}, 189 {0, "a", "e", "m00 m01 m02"}, 190 {0, "a", "g", "m00 m01 m02"}, 191 {0, "a", "z", "m00 m01 m02 m03 m04 m05 m06 m07"}, 192 {0, "c", "e", "m00 m01 m02"}, 193 {0, "d", "d", "m00 m01 m02"}, 194 {0, "g", "n", "m00 m01 m02 m04 m05 m06 m07"}, 195 {0, "h", "i", ""}, 196 {0, "h", "o", "m04 m05 m06 m07"}, 197 {0, "h", "u", "m04 m05 m06 m07"}, 198 {0, "k", "l", ""}, 199 {0, "k", "o", "m04 m05 m06 m07"}, 200 {0, "k", "p", "m04 m05 m06 m07"}, 201 {0, "n", "o", "m04 m05 m06 m07"}, 202 {0, "n", "z", "m03 m04 m05 m06 m07"}, 203 {0, "o", "z", "m03 m04 m05 m06 m07"}, 204 {0, "p", "z", "m03 m04 m05 m06 m07"}, 205 {0, "q", "z", "m03 m04 m05 m06 m07"}, 206 {0, "r", "s", "m04 m05 m06 m07"}, 207 {0, "r", "z", "m03 m04 m05 m06 m07"}, 208 {0, "s", "z", "m03 m04 m05 m06 m07"}, 209 {0, "u", "z", "m03 m04 m05 m06 m07"}, 210 {0, "y", "z", "m03"}, 211 {0, "z", "z", ""}, 212 213 // Level 1: m10=d-g, m11=g-j, m12=n-p, m13=p-p, m14=p-u. 214 {1, "a", "a", ""}, 215 {1, "a", "b", ""}, 216 {1, "a", "d", "m10"}, 217 {1, "a", "e", "m10"}, 218 {1, "a", "g", "m10 m11"}, 219 {1, "a", "z", "m10 m11 m12 m13 m14"}, 220 {1, "c", "e", "m10"}, 221 {1, "d", "d", "m10"}, 222 {1, "g", "n", "m10 m11 m12"}, 223 {1, "h", "i", "m11"}, 224 {1, "h", "o", "m11 m12"}, 225 {1, "h", "u", "m11 m12 m13 m14"}, 226 {1, "k", "l", ""}, 227 {1, "k", "o", "m12"}, 228 {1, "k", "p", "m12 m13 m14"}, 229 {1, "n", "o", "m12"}, 230 {1, "n", "z", "m12 m13 m14"}, 231 {1, "o", "z", "m12 m13 m14"}, 232 {1, "p", "z", "m12 m13 m14"}, 233 {1, "q", "z", "m14"}, 234 {1, "r", "s", "m14"}, 235 {1, "r", "z", "m14"}, 236 {1, "s", "z", "m14"}, 237 {1, "u", "z", "m14"}, 238 {1, "y", "z", ""}, 239 {1, "z", "z", ""}, 240 241 // Level 2: empty. 242 {2, "a", "z", ""}, 243 } 244 245 cmp := base.DefaultComparer.Compare 246 for _, tc := range testCases { 247 o := v.Overlaps(tc.level, cmp, []byte(tc.ukey0), []byte(tc.ukey1)) 248 s := make([]string, len(o)) 249 for i, meta := range o { 250 s[i] = fmt.Sprintf("m%02d", meta.FileNum%100) 251 } 252 got := strings.Join(s, " ") 253 if got != tc.want { 254 t.Errorf("level=%d, range=%s-%s\ngot %v\nwant %v", tc.level, tc.ukey0, tc.ukey1, got, tc.want) 255 } 256 } 257 } 258 259 func TestVersionUnref(t *testing.T) { 260 list := &VersionList{} 261 list.Init(&sync.Mutex{}) 262 v := &Version{Deleted: func([]uint64) {}} 263 v.Ref() 264 list.PushBack(v) 265 v.Unref() 266 if !list.Empty() { 267 t.Fatalf("expected version list to be empty") 268 } 269 }