1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver;
20
21 import static org.apache.hadoop.hbase.regionserver.StripeStoreFileManager.OPEN_KEY;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27
28 import java.io.IOException;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.Iterator;
34 import java.util.List;
35
36 import org.apache.hadoop.conf.Configuration;
37 import org.apache.hadoop.fs.FileSystem;
38 import org.apache.hadoop.fs.Path;
39 import org.apache.hadoop.hbase.HBaseConfiguration;
40 import org.apache.hadoop.hbase.HBaseTestingUtility;
41 import org.apache.hadoop.hbase.HConstants;
42 import org.apache.hadoop.hbase.KeyValue;
43 import org.apache.hadoop.hbase.KeyValue.KVComparator;
44 import org.apache.hadoop.hbase.testclassification.SmallTests;
45 import org.apache.hadoop.hbase.util.Bytes;
46 import org.junit.After;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.experimental.categories.Category;
50 import org.mockito.Mockito;
51
52
53 @Category(SmallTests.class)
54 public class TestStripeStoreFileManager {
55 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
56 private static final Path BASEDIR =
57 TEST_UTIL.getDataTestDir(TestStripeStoreFileManager.class.getSimpleName());
58 private static final Path CFDIR = HStore.getStoreHomedir(BASEDIR, "region", Bytes.toBytes("cf"));
59
60 private static final byte[] KEY_A = Bytes.toBytes("aaa");
61 private static final byte[] KEY_B = Bytes.toBytes("bbb");
62 private static final byte[] KEY_C = Bytes.toBytes("ccc");
63 private static final byte[] KEY_D = Bytes.toBytes("ddd");
64
65 private static final KeyValue KV_A = new KeyValue(KEY_A, 0L);
66 private static final KeyValue KV_B = new KeyValue(KEY_B, 0L);
67 private static final KeyValue KV_C = new KeyValue(KEY_C, 0L);
68 private static final KeyValue KV_D = new KeyValue(KEY_D, 0L);
69
70 @Before
71 public void setUp() throws Exception {
72 FileSystem fs = TEST_UTIL.getTestFileSystem();
73 if (!fs.mkdirs(CFDIR)) {
74 throw new IOException("Cannot create test directory " + CFDIR);
75 }
76 }
77
78 @After
79 public void tearDown() throws Exception {
80 FileSystem fs = TEST_UTIL.getTestFileSystem();
81 if (fs.exists(CFDIR) && !fs.delete(CFDIR, true)) {
82 throw new IOException("Cannot delete test directory " + CFDIR);
83 }
84 }
85
86 @Test
87 public void testInsertFilesIntoL0() throws Exception {
88 StripeStoreFileManager manager = createManager();
89 MockStoreFile sf = createFile();
90 manager.insertNewFiles(al(sf));
91 assertEquals(1, manager.getStorefileCount());
92 Collection<StoreFile> filesForGet = manager.getFilesForScanOrGet(true, KEY_A, KEY_A);
93 assertEquals(1, filesForGet.size());
94 assertTrue(filesForGet.contains(sf));
95
96
97 manager.addCompactionResults(al(), al(createFile(OPEN_KEY, KEY_B),
98 createFile(KEY_B, OPEN_KEY)));
99 assertTrue(manager.getFilesForScanOrGet(true, KEY_A, KEY_A).contains(sf));
100 assertTrue(manager.getFilesForScanOrGet(true, KEY_C, KEY_C).contains(sf));
101 }
102
103 @Test
104 public void testClearFiles() throws Exception {
105 StripeStoreFileManager manager = createManager();
106 manager.insertNewFiles(al(createFile()));
107 manager.insertNewFiles(al(createFile()));
108 manager.addCompactionResults(al(), al(createFile(OPEN_KEY, KEY_B),
109 createFile(KEY_B, OPEN_KEY)));
110 assertEquals(4, manager.getStorefileCount());
111 Collection<StoreFile> allFiles = manager.clearFiles();
112 assertEquals(4, allFiles.size());
113 assertEquals(0, manager.getStorefileCount());
114 assertEquals(0, manager.getStorefiles().size());
115 }
116
117 private static ArrayList<StoreFile> dumpIterator(Iterator<StoreFile> iter) {
118 ArrayList<StoreFile> result = new ArrayList<StoreFile>();
119 for (; iter.hasNext(); result.add(iter.next()));
120 return result;
121 }
122
123 @Test
124 public void testRowKeyBefore() throws Exception {
125 StripeStoreFileManager manager = createManager();
126 StoreFile l0File = createFile(), l0File2 = createFile();
127 manager.insertNewFiles(al(l0File));
128 manager.insertNewFiles(al(l0File2));
129
130 Iterator<StoreFile> sfs = manager.getCandidateFilesForRowKeyBefore(KV_B);
131 sfs.next();
132 sfs.remove();
133
134 sfs = manager.updateCandidateFilesForRowKeyBefore(sfs, KV_B, KV_A);
135 assertTrue(sfs.hasNext());
136
137 MockStoreFile stripe0a = createFile(0, 100, OPEN_KEY, KEY_B),
138 stripe1 = createFile(KEY_B, OPEN_KEY);
139 manager.addCompactionResults(al(l0File), al(stripe0a, stripe1));
140 manager.removeCompactedFiles(al(l0File));
141
142 ArrayList<StoreFile> sfsDump = dumpIterator(manager.getCandidateFilesForRowKeyBefore(KV_A));
143 assertEquals(2, sfsDump.size());
144 assertTrue(sfsDump.contains(stripe0a));
145 assertFalse(sfsDump.contains(stripe1));
146
147 sfsDump = dumpIterator(manager.getCandidateFilesForRowKeyBefore(KV_B));
148 assertEquals(3, sfsDump.size());
149 assertTrue(sfsDump.contains(stripe1));
150
151 sfsDump = dumpIterator(manager.getCandidateFilesForRowKeyBefore(KV_D));
152 assertEquals(3, sfsDump.size());
153
154
155 sfs = manager.getCandidateFilesForRowKeyBefore(KV_D);
156 sfs.next();
157 sfs.remove();
158 sfs = manager.updateCandidateFilesForRowKeyBefore(sfs, KV_D, KV_C);
159 assertEquals(stripe1, sfs.next());
160 assertFalse(sfs.hasNext());
161
162
163
164 StoreFile stripe0b = createFile(0, 101, OPEN_KEY, KEY_B);
165 manager.addCompactionResults(al(l0File2), al(stripe0b));
166 manager.removeCompactedFiles(al(l0File2));
167 sfs = manager.getCandidateFilesForRowKeyBefore(KV_A);
168 assertEquals(stripe0b, sfs.next());
169 sfs.remove();
170 sfs = manager.updateCandidateFilesForRowKeyBefore(sfs, KV_A, KV_A);
171 assertEquals(stripe0a, sfs.next());
172 }
173
174 @Test
175 public void testGetSplitPointEdgeCases() throws Exception {
176 StripeStoreFileManager manager = createManager();
177
178 assertNull(manager.getSplitPoint());
179
180
181 MockStoreFile sf5 = createFile(5, 0);
182 sf5.splitPoint = new byte[1];
183 manager.insertNewFiles(al(sf5));
184 manager.insertNewFiles(al(createFile(1, 0)));
185 assertEquals(sf5.splitPoint, manager.getSplitPoint());
186
187
188 manager.addCompactionResults(al(), al(createFile(2, 0, OPEN_KEY, OPEN_KEY)));
189 assertEquals(sf5.splitPoint, manager.getSplitPoint());
190
191
192 MockStoreFile sf6 = createFile(6, 0, OPEN_KEY, OPEN_KEY);
193 sf6.splitPoint = new byte[1];
194 manager.addCompactionResults(al(), al(sf6));
195 assertEquals(sf6.splitPoint, manager.getSplitPoint());
196 }
197
198 @Test
199 public void testGetStripeBoundarySplits() throws Exception {
200
201 verifySplitPointScenario(5, false, 0f, 2, 1, 1, 1, 1, 1, 10);
202 verifySplitPointScenario(0, false, 0f, 6, 3, 1, 1, 2);
203 verifySplitPointScenario(2, false, 0f, 1, 1, 1, 1, 2);
204 verifySplitPointScenario(0, false, 0f, 5, 4);
205 verifySplitPointScenario(2, false, 0f, 5, 2, 5, 5, 5);
206 }
207
208 @Test
209 public void testGetUnbalancedSplits() throws Exception {
210
211 verifySplitPointScenario(0, false, 2.1f, 4, 4, 4);
212 verifySplitPointScenario(1, true, 1.5f, 4, 4, 4);
213 verifySplitPointScenario(1, false, 1.1f, 3, 4, 1, 1, 2, 2);
214 verifySplitPointScenario(1, false, 1.1f, 3, 6, 1, 1, 2, 2);
215 verifySplitPointScenario(1, true, 1.1f, 3, 8, 1, 1, 2, 2);
216 verifySplitPointScenario(3, false, 1.1f, 2, 2, 1, 1, 4, 3);
217 verifySplitPointScenario(4, true, 1.1f, 2, 2, 1, 1, 8, 3);
218 verifySplitPointScenario(0, true, 1.5f, 10, 4);
219 verifySplitPointScenario(0, false, 1.4f, 6, 4);
220 verifySplitPointScenario(1, true, 1.5f, 4, 10);
221 verifySplitPointScenario(0, false, 1.4f, 4, 6);
222 }
223
224
225
226
227
228
229
230
231
232
233 private void verifySplitPointScenario(int splitPointAfter, boolean shouldSplitStripe,
234 float splitRatioToVerify, int... sizes) throws Exception {
235 assertTrue(sizes.length > 1);
236 ArrayList<StoreFile> sfs = new ArrayList<StoreFile>();
237 for (int sizeIx = 0; sizeIx < sizes.length; ++sizeIx) {
238 byte[] startKey = (sizeIx == 0) ? OPEN_KEY : Bytes.toBytes(sizeIx - 1);
239 byte[] endKey = (sizeIx == sizes.length - 1) ? OPEN_KEY : Bytes.toBytes(sizeIx);
240 MockStoreFile sf = createFile(sizes[sizeIx], 0, startKey, endKey);
241 sf.splitPoint = Bytes.toBytes(-sizeIx);
242 sfs.add(sf);
243 }
244
245 Configuration conf = HBaseConfiguration.create();
246 if (splitRatioToVerify != 0) {
247 conf.setFloat(StripeStoreConfig.MAX_REGION_SPLIT_IMBALANCE_KEY, splitRatioToVerify);
248 }
249 StripeStoreFileManager manager = createManager(al(), conf);
250 manager.addCompactionResults(al(), sfs);
251 int result = Bytes.toInt(manager.getSplitPoint());
252
253 assertEquals(splitPointAfter * (shouldSplitStripe ? -1 : 1), result);
254 }
255
256 private static byte[] keyAfter(byte[] key) {
257 return Arrays.copyOf(key, key.length + 1);
258 }
259
260 @Test
261 public void testGetFilesForGetAndScan() throws Exception {
262 StripeStoreFileManager manager = createManager();
263 verifyGetAndScanScenario(manager, null, null);
264 verifyGetAndScanScenario(manager, KEY_B, KEY_C);
265
266
267 MockStoreFile sf0 = createFile();
268 manager.insertNewFiles(al(sf0));
269 verifyGetAndScanScenario(manager, null, null, sf0);
270 verifyGetAndScanScenario(manager, null, KEY_C, sf0);
271 verifyGetAndScanScenario(manager, KEY_B, null, sf0);
272 verifyGetAndScanScenario(manager, KEY_B, KEY_C, sf0);
273
274
275 MockStoreFile sfA = createFile(OPEN_KEY, KEY_A);
276 MockStoreFile sfB = createFile(KEY_A, KEY_B);
277 MockStoreFile sfC = createFile(KEY_B, KEY_C);
278 MockStoreFile sfD = createFile(KEY_C, KEY_D);
279 MockStoreFile sfE = createFile(KEY_D, OPEN_KEY);
280 manager.addCompactionResults(al(), al(sfA, sfB, sfC, sfD, sfE));
281
282 verifyGetAndScanScenario(manager, null, null, sf0, sfA, sfB, sfC, sfD, sfE);
283 verifyGetAndScanScenario(manager, keyAfter(KEY_A), null, sf0, sfB, sfC, sfD, sfE);
284 verifyGetAndScanScenario(manager, null, keyAfter(KEY_C), sf0, sfA, sfB, sfC, sfD);
285 verifyGetAndScanScenario(manager, KEY_B, null, sf0, sfC, sfD, sfE);
286 verifyGetAndScanScenario(manager, null, KEY_C, sf0, sfA, sfB, sfC, sfD);
287 verifyGetAndScanScenario(manager, KEY_B, keyAfter(KEY_B), sf0, sfC);
288 verifyGetAndScanScenario(manager, keyAfter(KEY_A), KEY_B, sf0, sfB, sfC);
289 verifyGetAndScanScenario(manager, KEY_D, KEY_D, sf0, sfE);
290 verifyGetAndScanScenario(manager, keyAfter(KEY_B), keyAfter(KEY_C), sf0, sfC, sfD);
291 }
292
293 private void verifyGetAndScanScenario(StripeStoreFileManager manager,
294 byte[] start, byte[] end, StoreFile... results) throws Exception {
295 verifyGetOrScanScenario(manager, true, start, end, results);
296 verifyGetOrScanScenario(manager, false, start, end, results);
297 }
298
299 @Test
300 @SuppressWarnings("unchecked")
301 public void testLoadFilesWithRecoverableBadFiles() throws Exception {
302
303
304
305 ArrayList<StoreFile> validStripeFiles = al(createFile(OPEN_KEY, KEY_B),
306 createFile(KEY_B, KEY_C), createFile(KEY_C, OPEN_KEY),
307 createFile(KEY_C, OPEN_KEY));
308 ArrayList<StoreFile> filesToGoToL0 = al(createFile(), createFile(null, KEY_A),
309 createFile(KEY_D, null), createFile(KEY_D, KEY_A), createFile(keyAfter(KEY_A), KEY_C),
310 createFile(OPEN_KEY, KEY_D), createFile(KEY_D, keyAfter(KEY_D)));
311 ArrayList<StoreFile> allFilesToGo = flattenLists(validStripeFiles, filesToGoToL0);
312 Collections.shuffle(allFilesToGo);
313 StripeStoreFileManager manager = createManager(allFilesToGo);
314 List<StoreFile> l0Files = manager.getLevel0Files();
315 assertEquals(filesToGoToL0.size(), l0Files.size());
316 for (StoreFile sf : filesToGoToL0) {
317 assertTrue(l0Files.contains(sf));
318 }
319 verifyAllFiles(manager, allFilesToGo);
320 }
321
322 @Test
323 public void testLoadFilesWithBadStripe() throws Exception {
324
325
326 ArrayList<StoreFile> allFilesToGo = al(createFile(OPEN_KEY, KEY_B),
327 createFile(KEY_B, KEY_C), createFile(KEY_C, OPEN_KEY),
328 createFile(KEY_B, keyAfter(KEY_B)));
329 Collections.shuffle(allFilesToGo);
330 StripeStoreFileManager manager = createManager(allFilesToGo);
331 assertEquals(allFilesToGo.size(), manager.getLevel0Files().size());
332 }
333
334 @Test
335 public void testLoadFilesWithGaps() throws Exception {
336
337 StripeStoreFileManager manager =
338 createManager(al(createFile(OPEN_KEY, KEY_B), createFile(KEY_C, OPEN_KEY)));
339 assertEquals(2, manager.getLevel0Files().size());
340
341 manager = createManager(al(createFile(OPEN_KEY, OPEN_KEY)));
342 assertEquals(0, manager.getLevel0Files().size());
343 assertEquals(1, manager.getStorefileCount());
344 }
345
346 @Test
347 public void testLoadFilesAfterSplit() throws Exception {
348
349 MockStoreFile sf = createFile(KEY_B, KEY_C);
350 StripeStoreFileManager manager = createManager(al(createFile(OPEN_KEY, KEY_B), sf));
351 assertEquals(0, manager.getLevel0Files().size());
352
353 verifyInvalidCompactionScenario(manager, al(sf), al(createFile(KEY_B, KEY_C)));
354 manager.addCompactionResults(al(sf), al(createFile(KEY_B, OPEN_KEY)));
355 manager.removeCompactedFiles(al(sf));
356
357 manager = createManager(al(sf, createFile(KEY_C, OPEN_KEY)));
358 verifyInvalidCompactionScenario(manager, al(sf), al(createFile(KEY_B, KEY_C)));
359 manager.addCompactionResults(al(sf), al(createFile(OPEN_KEY, KEY_C)));
360 manager.removeCompactedFiles(al(sf));
361 manager = createManager(al(sf));
362 verifyInvalidCompactionScenario(manager, al(sf), al(createFile(KEY_B, KEY_C)));
363 manager.addCompactionResults(al(sf), al(createFile(OPEN_KEY, OPEN_KEY)));
364 }
365
366 @Test
367 public void testAddingCompactionResults() throws Exception {
368 StripeStoreFileManager manager = createManager();
369
370 StoreFile sf_L0_0a = createFile(), sf_L0_0b = createFile();
371 manager.insertNewFiles(al(sf_L0_0a, sf_L0_0b));
372
373
374 verifyInvalidCompactionScenario(manager, al(sf_L0_0a), al(createFile(OPEN_KEY, KEY_B)));
375 verifyInvalidCompactionScenario(manager, al(sf_L0_0a), al(createFile(OPEN_KEY, KEY_B),
376 createFile(KEY_C, OPEN_KEY)));
377 verifyInvalidCompactionScenario(manager, al(sf_L0_0a), al(createFile(OPEN_KEY, KEY_B),
378 createFile(KEY_B, OPEN_KEY), createFile(KEY_A, KEY_D)));
379 verifyInvalidCompactionScenario(manager, al(sf_L0_0a), al(createFile(OPEN_KEY, KEY_B),
380 createFile(KEY_A, KEY_B), createFile(KEY_B, OPEN_KEY)));
381
382 StoreFile sf_i2B_0 = createFile(OPEN_KEY, KEY_B);
383 StoreFile sf_B2C_0 = createFile(KEY_B, KEY_C);
384 StoreFile sf_C2i_0 = createFile(KEY_C, OPEN_KEY);
385 manager.addCompactionResults(al(sf_L0_0a), al(sf_i2B_0, sf_B2C_0, sf_C2i_0));
386 manager.removeCompactedFiles(al(sf_L0_0a));
387 verifyAllFiles(manager, al(sf_L0_0b, sf_i2B_0, sf_B2C_0, sf_C2i_0));
388
389
390 StoreFile sf_L0_1 = createFile();
391 StoreFile sf_i2B_1 = createFile(OPEN_KEY, KEY_B);
392 StoreFile sf_B2C_1 = createFile(KEY_B, KEY_C);
393 manager.insertNewFiles(al(sf_L0_1));
394 manager.addCompactionResults(al(sf_L0_0b, sf_L0_1), al(sf_i2B_1, sf_B2C_1));
395 manager.removeCompactedFiles(al(sf_L0_0b, sf_L0_1));
396 verifyAllFiles(manager, al(sf_i2B_0, sf_B2C_0, sf_C2i_0, sf_i2B_1, sf_B2C_1));
397
398
399 StoreFile sf_L0_2 = createFile(null, null);
400 manager.addCompactionResults(al(), al(sf_L0_2));
401 manager.removeCompactedFiles(al());
402 verifyAllFiles(manager, al(sf_i2B_0, sf_B2C_0, sf_C2i_0, sf_i2B_1, sf_B2C_1, sf_L0_2));
403
404 manager.addCompactionResults(al(sf_L0_2), al());
405 manager.removeCompactedFiles(al(sf_L0_2));
406
407
408 StoreFile sf_i2B_3 = createFile(OPEN_KEY, KEY_B);
409 manager.addCompactionResults(al(sf_i2B_0, sf_i2B_1), al(sf_i2B_3));
410 manager.removeCompactedFiles(al(sf_i2B_0, sf_i2B_1));
411 verifyAllFiles(manager, al(sf_B2C_0, sf_C2i_0, sf_B2C_1, sf_i2B_3));
412
413
414 StoreFile sf_B2D_4 = createFile(KEY_B, KEY_D);
415 StoreFile sf_D2i_4 = createFile(KEY_D, OPEN_KEY);
416 manager.addCompactionResults(al(sf_B2C_0, sf_C2i_0, sf_B2C_1), al(sf_B2D_4, sf_D2i_4));
417 manager.removeCompactedFiles(al(sf_B2C_0, sf_C2i_0, sf_B2C_1));
418 verifyAllFiles(manager, al(sf_i2B_3, sf_B2D_4, sf_D2i_4));
419
420
421 StoreFile sf_i2A_5 = createFile(OPEN_KEY, KEY_A);
422 StoreFile sf_A2B_5 = createFile(KEY_A, KEY_B);
423 manager.addCompactionResults(al(sf_i2B_3), al(sf_i2A_5, sf_A2B_5));
424 manager.removeCompactedFiles(al(sf_i2B_3));
425 verifyAllFiles(manager, al(sf_B2D_4, sf_D2i_4, sf_i2A_5, sf_A2B_5));
426
427
428 StoreFile sf_B2C_6 = createFile(KEY_B, KEY_C);
429 StoreFile sf_C2D_6 = createFile(KEY_C, KEY_D);
430 manager.addCompactionResults(al(sf_B2D_4), al(sf_B2C_6, sf_C2D_6));
431 manager.removeCompactedFiles(al(sf_B2D_4));
432 verifyAllFiles(manager, al(sf_D2i_4, sf_i2A_5, sf_A2B_5, sf_B2C_6, sf_C2D_6));
433
434
435 StoreFile sf_A2C_7 = createFile(KEY_A, KEY_C);
436 manager.addCompactionResults(al(sf_A2B_5, sf_B2C_6), al(sf_A2C_7));
437 manager.removeCompactedFiles(al(sf_A2B_5, sf_B2C_6));
438 verifyAllFiles(manager, al(sf_D2i_4, sf_i2A_5, sf_C2D_6, sf_A2C_7));
439
440
441 StoreFile sf_i2C_8 = createFile(OPEN_KEY, KEY_C);
442 manager.addCompactionResults(al(sf_i2A_5, sf_A2C_7), al(sf_i2C_8));
443 manager.removeCompactedFiles(al(sf_i2A_5, sf_A2C_7));
444 verifyAllFiles(manager, al(sf_D2i_4, sf_C2D_6, sf_i2C_8));
445
446
447 StoreFile sf_i2i_9 = createFile(OPEN_KEY, OPEN_KEY);
448 manager.addCompactionResults(al(sf_D2i_4, sf_C2D_6, sf_i2C_8), al(sf_i2i_9));
449 manager.removeCompactedFiles(al(sf_D2i_4, sf_C2D_6, sf_i2C_8));
450 verifyAllFiles(manager, al(sf_i2i_9));
451 }
452
453 @Test
454 public void testCompactionAndFlushConflict() throws Exception {
455
456 StripeStoreFileManager sfm = createManager();
457 assertEquals(0, sfm.getStripeCount());
458 StoreFile sf_i2c = createFile(OPEN_KEY, KEY_C), sf_c2i = createFile(KEY_C, OPEN_KEY);
459 sfm.insertNewFiles(al(sf_i2c, sf_c2i));
460 assertEquals(2, sfm.getStripeCount());
461
462 StoreFile sf_i2d = createFile(OPEN_KEY, KEY_D), sf_d2i = createFile(KEY_D, OPEN_KEY);
463 sfm.insertNewFiles(al(sf_i2d, sf_d2i));
464 assertEquals(2, sfm.getStripeCount());
465 assertEquals(2, sfm.getLevel0Files().size());
466 verifyGetAndScanScenario(sfm, KEY_C, KEY_C, sf_i2d, sf_d2i, sf_c2i);
467
468 sfm.addCompactionResults(al(sf_i2d, sf_d2i), al());
469 sfm.removeCompactedFiles(al(sf_i2d, sf_d2i));
470 assertEquals(0, sfm.getLevel0Files().size());
471
472
473 StoreFile sf_i2c_2 = createFile(OPEN_KEY, KEY_C);
474 sfm.insertNewFiles(al(sf_i2c_2));
475 sfm.addCompactionResults(al(sf_i2c, sf_c2i), al(sf_i2d, sf_d2i));
476 sfm.removeCompactedFiles(al(sf_i2c, sf_c2i));
477 assertEquals(1, sfm.getLevel0Files().size());
478 verifyGetAndScanScenario(sfm, KEY_C, KEY_C, sf_i2d, sf_i2c_2);
479 }
480
481 @Test
482 public void testEmptyResultsForStripes() throws Exception {
483
484 StripeStoreFileManager manager = createManager();
485 StoreFile sf0a = createFile();
486 StoreFile sf0b = createFile();
487 manager.insertNewFiles(al(sf0a));
488 manager.insertNewFiles(al(sf0b));
489 ArrayList<StoreFile> compacted = al(createFile(OPEN_KEY, KEY_B),
490 createFile(KEY_B, KEY_C), createFile(KEY_C, OPEN_KEY));
491 manager.addCompactionResults(al(sf0a), compacted);
492 manager.removeCompactedFiles(al(sf0a));
493
494 ArrayList<StoreFile> compacted2 = al(createFile(OPEN_KEY, KEY_B), createFile(KEY_C, OPEN_KEY));
495 manager.addCompactionResults(al(sf0b), compacted2);
496 manager.removeCompactedFiles(al(sf0b));
497 compacted.addAll(compacted2);
498 verifyAllFiles(manager, compacted);
499 }
500
501 @Test
502 public void testPriority() throws Exception {
503
504 testPriorityScenario(5, 5, 0, 0, 0);
505 testPriorityScenario(2, 5, 0, 0, 3);
506 testPriorityScenario(4, 25, 5, 1, 0);
507 testPriorityScenario(3, 25, 5, 1, 1);
508 testPriorityScenario(3, 25, 5, 2, 0);
509 testPriorityScenario(2, 25, 5, 4, 0);
510 testPriorityScenario(2, 25, 5, 4, 4);
511 testPriorityScenario(2, 25, 5, 1, 10);
512 testPriorityScenario(0, 25, 5, 4, 5);
513 testPriorityScenario(-5, 25, 5, 6, 0);
514 testPriorityScenario(-1, 25, 0, 0, 26);
515 }
516
517 private void testPriorityScenario(int expectedPriority,
518 int limit, int stripes, int filesInStripe, int l0Files) throws Exception
519 {
520 final byte[][] keys = { KEY_A, KEY_B, KEY_C, KEY_D };
521 assertTrue(stripes <= keys.length + 1);
522 Configuration conf = TEST_UTIL.getConfiguration();
523 conf.setInt("hbase.hstore.blockingStoreFiles", limit);
524 StripeStoreFileManager sfm = createManager(al(), conf);
525 for (int i = 0; i < l0Files; ++i) {
526 sfm.insertNewFiles(al(createFile()));
527 }
528 for (int i = 0; i < filesInStripe; ++i) {
529 ArrayList<StoreFile> stripe = new ArrayList<StoreFile>();
530 for (int j = 0; j < stripes; ++j) {
531 stripe.add(createFile(
532 (j == 0) ? OPEN_KEY : keys[j - 1], (j == stripes - 1) ? OPEN_KEY : keys[j]));
533 }
534 sfm.addCompactionResults(al(), stripe);
535 }
536 assertEquals(expectedPriority, sfm.getStoreCompactionPriority());
537 }
538
539 private void verifyInvalidCompactionScenario(StripeStoreFileManager manager,
540 ArrayList<StoreFile> filesToCompact, ArrayList<StoreFile> filesToInsert) throws Exception {
541 Collection<StoreFile> allFiles = manager.getStorefiles();
542 try {
543 manager.addCompactionResults(filesToCompact, filesToInsert);
544 fail("Should have thrown");
545 } catch (IOException ex) {
546
547 }
548 verifyAllFiles(manager, allFiles);
549 }
550
551 private void verifyGetOrScanScenario(StripeStoreFileManager manager, boolean isGet,
552 byte[] start, byte[] end, StoreFile... results) throws Exception {
553 verifyGetOrScanScenario(manager, isGet, start, end, Arrays.asList(results));
554 }
555
556 private void verifyGetOrScanScenario(StripeStoreFileManager manager, boolean isGet,
557 byte[] start, byte[] end, Collection<StoreFile> results) throws Exception {
558 start = start != null ? start : HConstants.EMPTY_START_ROW;
559 end = end != null ? end : HConstants.EMPTY_END_ROW;
560 Collection<StoreFile> sfs = manager.getFilesForScanOrGet(isGet, start, end);
561 assertEquals(results.size(), sfs.size());
562 for (StoreFile result : results) {
563 assertTrue(sfs.contains(result));
564 }
565 }
566
567 private void verifyAllFiles(
568 StripeStoreFileManager manager, Collection<StoreFile> results) throws Exception {
569 verifyGetOrScanScenario(manager, false, null, null, results);
570 }
571
572
573 private static MockStoreFile createFile(
574 long size, long seqNum, byte[] startKey, byte[] endKey) throws Exception {
575 FileSystem fs = TEST_UTIL.getTestFileSystem();
576 Path testFilePath = StoreFile.getUniqueFile(fs, CFDIR);
577 fs.create(testFilePath).close();
578 MockStoreFile sf = new MockStoreFile(TEST_UTIL, testFilePath, size, 0, false, seqNum);
579 if (startKey != null) {
580 sf.setMetadataValue(StripeStoreFileManager.STRIPE_START_KEY, startKey);
581 }
582 if (endKey != null) {
583 sf.setMetadataValue(StripeStoreFileManager.STRIPE_END_KEY, endKey);
584 }
585 return sf;
586 }
587
588 private static MockStoreFile createFile(long size, long seqNum) throws Exception {
589 return createFile(size, seqNum, null, null);
590 }
591
592 private static MockStoreFile createFile(byte[] startKey, byte[] endKey) throws Exception {
593 return createFile(0, 0, startKey, endKey);
594 }
595
596 private static MockStoreFile createFile() throws Exception {
597 return createFile(null, null);
598 }
599
600 private static StripeStoreFileManager createManager() throws Exception {
601 return createManager(new ArrayList<StoreFile>());
602 }
603
604 private static StripeStoreFileManager createManager(ArrayList<StoreFile> sfs) throws Exception {
605 return createManager(sfs, TEST_UTIL.getConfiguration());
606 }
607
608 private static StripeStoreFileManager createManager(
609 ArrayList<StoreFile> sfs, Configuration conf) throws Exception {
610 StripeStoreConfig config = new StripeStoreConfig(
611 conf, Mockito.mock(StoreConfigInformation.class));
612 StripeStoreFileManager result = new StripeStoreFileManager(new KVComparator(), conf, config);
613 result.loadFiles(sfs);
614 return result;
615 }
616
617 private static ArrayList<StoreFile> al(StoreFile... sfs) {
618 return new ArrayList<StoreFile>(Arrays.asList(sfs));
619 }
620
621 private static ArrayList<StoreFile> flattenLists(ArrayList<StoreFile>... sfls) {
622 ArrayList<StoreFile> result = new ArrayList<StoreFile>();
623 for (ArrayList<StoreFile> sfl : sfls) {
624 result.addAll(sfl);
625 }
626 return result;
627 }
628 }