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