1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.regionserver;
21
22 import static org.apache.hadoop.hbase.regionserver.KeyValueScanFixture.scanFixture;
23
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.NavigableSet;
30 import java.util.TreeSet;
31 import java.util.concurrent.atomic.AtomicInteger;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.hadoop.conf.Configuration;
36 import org.apache.hadoop.hbase.Cell;
37 import org.apache.hadoop.hbase.CellUtil;
38 import org.apache.hadoop.hbase.HBaseConfiguration;
39 import org.apache.hadoop.hbase.HConstants;
40 import org.apache.hadoop.hbase.KeepDeletedCells;
41 import org.apache.hadoop.hbase.KeyValue;
42 import org.apache.hadoop.hbase.KeyValue.KVComparator;
43 import org.apache.hadoop.hbase.KeyValueTestUtil;
44 import org.apache.hadoop.hbase.KeyValueUtil;
45 import org.apache.hadoop.hbase.client.Get;
46 import org.apache.hadoop.hbase.client.Scan;
47 import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;
48 import org.apache.hadoop.hbase.testclassification.MediumTests;
49 import org.apache.hadoop.hbase.util.Bytes;
50 import org.apache.hadoop.hbase.util.EnvironmentEdge;
51 import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;
52 import org.junit.experimental.categories.Category;
53
54 import junit.framework.TestCase;
55
56
57 @Category(MediumTests.class)
58 public class TestStoreScanner extends TestCase {
59 private static final Log LOG = LogFactory.getLog(TestStoreScanner.class);
60 private static final String CF_STR = "cf";
61 final static byte [] CF = Bytes.toBytes(CF_STR);
62 static Configuration CONF = HBaseConfiguration.create();
63 private ScanInfo scanInfo = new ScanInfo(CONF, CF, 0, Integer.MAX_VALUE,
64 Long.MAX_VALUE, KeepDeletedCells.FALSE, 0, KeyValue.COMPARATOR);
65 private ScanType scanType = ScanType.USER_SCAN;
66
67 public void setUp() throws Exception {
68 super.setUp();
69 }
70
71
72
73
74
75
76
77
78 private static final byte [] ZERO = new byte [] {'0'};
79 private static final byte [] ZERO_POINT_ZERO = new byte [] {'0', '.', '0'};
80 private static final byte [] ONE = new byte [] {'1'};
81 private static final byte [] TWO = new byte [] {'2'};
82 private static final byte [] TWO_POINT_TWO = new byte [] {'2', '.', '2'};
83 private static final byte [] THREE = new byte [] {'3'};
84 private static final byte [] FOUR = new byte [] {'4'};
85 private static final byte [] FIVE = new byte [] {'5'};
86 private static final byte [] VALUE = new byte [] {'v'};
87 private static final int CELL_GRID_BLOCK2_BOUNDARY = 4;
88 private static final int CELL_GRID_BLOCK3_BOUNDARY = 11;
89 private static final int CELL_GRID_BLOCK4_BOUNDARY = 15;
90 private static final int CELL_GRID_BLOCK5_BOUNDARY = 19;
91
92
93
94
95
96
97
98
99 private static final KeyValue [] CELL_GRID = new KeyValue [] {
100 new KeyValue(ONE, CF, ONE, 1L, KeyValue.Type.Put, VALUE),
101 new KeyValue(ONE, CF, TWO, 1L, KeyValue.Type.Put, VALUE),
102 new KeyValue(ONE, CF, THREE, 1L, KeyValue.Type.Put, VALUE),
103 new KeyValue(ONE, CF, FOUR, 1L, KeyValue.Type.Put, VALUE),
104
105 new KeyValue(TWO, CF, ONE, 1L, KeyValue.Type.Put, VALUE),
106 new KeyValue(TWO, CF, TWO, 1L, KeyValue.Type.Put, VALUE),
107 new KeyValue(TWO, CF, THREE, 1L, KeyValue.Type.Put, VALUE),
108 new KeyValue(TWO, CF, FOUR, 1L, KeyValue.Type.Put, VALUE),
109 new KeyValue(TWO_POINT_TWO, CF, ZERO, 1L, KeyValue.Type.Put, VALUE),
110 new KeyValue(TWO_POINT_TWO, CF, ZERO_POINT_ZERO, 1L, KeyValue.Type.Put, VALUE),
111 new KeyValue(TWO_POINT_TWO, CF, FIVE, 1L, KeyValue.Type.Put, VALUE),
112
113 new KeyValue(THREE, CF, ONE, 1L, KeyValue.Type.Put, VALUE),
114 new KeyValue(THREE, CF, TWO, 1L, KeyValue.Type.Put, VALUE),
115 new KeyValue(THREE, CF, THREE, 1L, KeyValue.Type.Put, VALUE),
116 new KeyValue(THREE, CF, FOUR, 1L, KeyValue.Type.Put, VALUE),
117
118 new KeyValue(FOUR, CF, ONE, 1L, KeyValue.Type.Put, VALUE),
119 new KeyValue(FOUR, CF, TWO, 1L, KeyValue.Type.Put, VALUE),
120 new KeyValue(FOUR, CF, THREE, 1L, KeyValue.Type.Put, VALUE),
121 new KeyValue(FOUR, CF, FOUR, 1L, KeyValue.Type.Put, VALUE),
122
123 new KeyValue(FOUR, CF, FIVE, 1L, KeyValue.Type.Put, VALUE),
124 new KeyValue(FIVE, CF, ZERO, 1L, KeyValue.Type.Put, VALUE),
125 };
126
127 private static class KeyValueHeapWithCount extends KeyValueHeap {
128
129 final AtomicInteger count;
130
131 public KeyValueHeapWithCount(List<? extends KeyValueScanner> scanners,
132 KVComparator comparator, AtomicInteger count) throws IOException {
133 super(scanners, comparator);
134 this.count = count;
135 }
136
137 @Override
138 public Cell peek() {
139 this.count.incrementAndGet();
140 return super.peek();
141 }
142 }
143
144
145
146
147
148 private static class CellGridStoreScanner extends StoreScanner {
149
150 AtomicInteger count;
151 final AtomicInteger optimization = new AtomicInteger(0);
152
153 CellGridStoreScanner(final Scan scan, ScanInfo scanInfo, ScanType scanType)
154 throws IOException {
155 super(scan, scanInfo, scanType, scan.getFamilyMap().get(CF),
156 Arrays.<KeyValueScanner>asList(
157 new KeyValueScanner[] {new KeyValueScanFixture(KeyValue.COMPARATOR, CELL_GRID)}));
158 }
159
160 protected void resetKVHeap(List<? extends KeyValueScanner> scanners,
161 KVComparator comparator) throws IOException {
162 if (count == null) {
163 count = new AtomicInteger(0);
164 }
165 heap = new KeyValueHeapWithCount(scanners, comparator, count);
166 }
167
168 protected boolean trySkipToNextRow(Cell cell) throws IOException {
169 boolean optimized = super.trySkipToNextRow(cell);
170 LOG.info("Cell=" + cell + ", nextIndex=" + CellUtil.toString(getNextIndexedKey(), false)
171 + ", optimized=" + optimized);
172 if (optimized) {
173 optimization.incrementAndGet();
174 }
175 return optimized;
176 }
177
178 protected boolean trySkipToNextColumn(Cell cell) throws IOException {
179 boolean optimized = super.trySkipToNextColumn(cell);
180 LOG.info("Cell=" + cell + ", nextIndex=" + CellUtil.toString(getNextIndexedKey(), false)
181 + ", optimized=" + optimized);
182 if (optimized) {
183 optimization.incrementAndGet();
184 }
185 return optimized;
186 }
187
188 @Override
189 public Cell getNextIndexedKey() {
190
191 return count.get() > CELL_GRID_BLOCK4_BOUNDARY?
192 KeyValueUtil.createFirstOnRow(CELL_GRID[CELL_GRID_BLOCK5_BOUNDARY].getRow()):
193 count.get() > CELL_GRID_BLOCK3_BOUNDARY?
194 KeyValueUtil.createFirstOnRow(CELL_GRID[CELL_GRID_BLOCK4_BOUNDARY].getRow()):
195 count.get() > CELL_GRID_BLOCK2_BOUNDARY?
196 KeyValueUtil.createFirstOnRow(CELL_GRID[CELL_GRID_BLOCK3_BOUNDARY].getRow()):
197 KeyValueUtil.createFirstOnRow(CELL_GRID[CELL_GRID_BLOCK2_BOUNDARY].getRow());
198 }
199 };
200
201 private static final int CELL_WITH_VERSIONS_BLOCK2_BOUNDARY = 4;
202
203 private static final KeyValue [] CELL_WITH_VERSIONS = new KeyValue [] {
204 new KeyValue(ONE, CF, ONE, 2L, KeyValue.Type.Put, VALUE),
205 new KeyValue(ONE, CF, ONE, 1L, KeyValue.Type.Put, VALUE),
206 new KeyValue(ONE, CF, TWO, 2L, KeyValue.Type.Put, VALUE),
207 new KeyValue(ONE, CF, TWO, 1L, KeyValue.Type.Put, VALUE),
208
209 new KeyValue(TWO, CF, ONE, 1L, KeyValue.Type.Put, VALUE),
210 new KeyValue(TWO, CF, TWO, 1L, KeyValue.Type.Put, VALUE),
211 };
212
213 private static class CellWithVersionsStoreScanner extends StoreScanner {
214
215 final AtomicInteger optimization = new AtomicInteger(0);
216
217 CellWithVersionsStoreScanner(final Scan scan, ScanInfo scanInfo, ScanType scanType)
218 throws IOException {
219 super(scan, scanInfo, scanType, scan.getFamilyMap().get(CF), Arrays
220 .<KeyValueScanner> asList(new KeyValueScanner[] { new KeyValueScanFixture(
221 KeyValue.COMPARATOR, CELL_WITH_VERSIONS) }));
222 }
223
224 protected boolean trySkipToNextColumn(Cell cell) throws IOException {
225 boolean optimized = super.trySkipToNextColumn(cell);
226 LOG.info("Cell=" + cell + ", nextIndex=" + CellUtil.toString(getNextIndexedKey(), false)
227 + ", optimized=" + optimized);
228 if (optimized) {
229 optimization.incrementAndGet();
230 }
231 return optimized;
232 }
233
234 @Override
235 public Cell getNextIndexedKey() {
236
237 return KeyValueUtil.createFirstOnRow(CELL_WITH_VERSIONS[CELL_WITH_VERSIONS_BLOCK2_BOUNDARY].getRow());
238 }
239 };
240
241 private static class CellWithVersionsNoOptimizeStoreScanner extends StoreScanner {
242
243 final AtomicInteger optimization = new AtomicInteger(0);
244
245 CellWithVersionsNoOptimizeStoreScanner(final Scan scan, ScanInfo scanInfo, ScanType scanType)
246 throws IOException {
247 super(scan, scanInfo, scanType, scan.getFamilyMap().get(CF), Arrays
248 .<KeyValueScanner> asList(new KeyValueScanner[] { new KeyValueScanFixture(
249 KeyValue.COMPARATOR, CELL_WITH_VERSIONS) }));
250 }
251
252 protected boolean trySkipToNextColumn(Cell cell) throws IOException {
253 boolean optimized = super.trySkipToNextColumn(cell);
254 LOG.info("Cell=" + cell + ", nextIndex=" + CellUtil.toString(getNextIndexedKey(), false)
255 + ", optimized=" + optimized);
256 if (optimized) {
257 optimization.incrementAndGet();
258 }
259 return optimized;
260 }
261
262 @Override
263 public Cell getNextIndexedKey() {
264 return null;
265 }
266 };
267
268 public void testWithColumnCountGetFilter() throws Exception {
269 Get get = new Get(ONE);
270 get.setMaxVersions();
271 get.addFamily(CF);
272 get.setFilter(new ColumnCountGetFilter(2));
273
274 CellWithVersionsNoOptimizeStoreScanner scannerNoOptimize = new CellWithVersionsNoOptimizeStoreScanner(
275 new Scan(get), this.scanInfo, this.scanType);
276 try {
277 List<Cell> results = new ArrayList<>();
278 while (scannerNoOptimize.next(results)) {
279 continue;
280 }
281 assertEquals(2, results.size());
282 assertTrue(CellUtil.matchingColumn(results.get(0), CELL_WITH_VERSIONS[0]));
283 assertTrue(CellUtil.matchingColumn(results.get(1), CELL_WITH_VERSIONS[2]));
284 assertTrue("Optimize should do some optimizations",
285 scannerNoOptimize.optimization.get() == 0);
286 } finally {
287 scannerNoOptimize.close();
288 }
289
290 get.setFilter(new ColumnCountGetFilter(2));
291 CellWithVersionsStoreScanner scanner = new CellWithVersionsStoreScanner(new Scan(get),
292 this.scanInfo, this.scanType);
293 try {
294 List<Cell> results = new ArrayList<>();
295 while (scanner.next(results)) {
296 continue;
297 }
298 assertEquals(2, results.size());
299 assertTrue(CellUtil.matchingColumn(results.get(0), CELL_WITH_VERSIONS[0]));
300 assertTrue(CellUtil.matchingColumn(results.get(1), CELL_WITH_VERSIONS[2]));
301 assertTrue("Optimize should do some optimizations", scanner.optimization.get() > 0);
302 } finally {
303 scanner.close();
304 }
305 }
306
307 public void testFullRowGetDoesNotOverreadWhenRowInsideOneBlock() throws IOException {
308
309
310 Get get = new Get(TWO);
311 Scan scan = new Scan(get);
312 CellGridStoreScanner scanner = new CellGridStoreScanner(scan, this.scanInfo, this.scanType);
313 try {
314 List<Cell> results = new ArrayList<>();
315 while (scanner.next(results)) {
316 continue;
317 }
318
319
320 assertEquals(4, results.size());
321
322
323 assertEquals(5, scanner.count.get());
324
325 assertEquals(0, scanner.optimization.get());
326 } finally {
327 scanner.close();
328 }
329 }
330
331 public void testFullRowSpansBlocks() throws IOException {
332
333 Get get = new Get(FOUR);
334 Scan scan = new Scan(get);
335 CellGridStoreScanner scanner = new CellGridStoreScanner(scan, this.scanInfo, this.scanType);
336 try {
337 List<Cell> results = new ArrayList<>();
338 while (scanner.next(results)) {
339 continue;
340 }
341
342
343 assertEquals(5, results.size());
344
345
346 assertEquals(6, scanner.count.get());
347
348 assertEquals(0, scanner.optimization.get());
349 } finally {
350 scanner.close();
351 }
352 }
353
354
355
356
357
358
359 public void testOptimize() throws IOException {
360 Scan scan = new Scan();
361
362 scan.addColumn(CF, ONE);
363 CellGridStoreScanner scanner = new CellGridStoreScanner(scan, this.scanInfo, this.scanType);
364 try {
365 List<Cell> results = new ArrayList<>();
366 while (scanner.next(results)) {
367 continue;
368 }
369
370
371 assertEquals(4, results.size());
372 for (Cell cell: results) {
373 assertTrue(Bytes.equals(ONE, 0, ONE.length,
374 cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()));
375 }
376 assertTrue("Optimize should do some optimizations", scanner.optimization.get() > 0);
377 } finally {
378 scanner.close();
379 }
380 }
381
382
383
384
385
386
387
388
389 public void testOptimizeAndGet() throws IOException {
390
391
392 Get get = new Get(TWO);
393 get.addColumn(CF, TWO);
394 get.addColumn(CF, THREE);
395 Scan scan = new Scan(get);
396 CellGridStoreScanner scanner = new CellGridStoreScanner(scan, this.scanInfo, this.scanType);
397 try {
398 List<Cell> results = new ArrayList<>();
399
400 assertEquals(false, scanner.next(results));
401
402 assertEquals(2, results.size());
403
404 assertEquals("First qcode is SEEK_NEXT_COL and second INCLUDE_AND_SEEK_NEXT_ROW",
405 3, scanner.count.get());
406 } finally {
407 scanner.close();
408 }
409 }
410
411
412
413
414
415
416
417
418
419
420 public void testOptimizeAndGetWithFakedNextBlockIndexStart() throws IOException {
421
422
423 Get get = new Get(THREE);
424 get.addColumn(CF, TWO);
425 Scan scan = new Scan(get);
426 CellGridStoreScanner scanner = new CellGridStoreScanner(scan, this.scanInfo, this.scanType);
427 try {
428 List<Cell> results = new ArrayList<>();
429
430 assertEquals(false, scanner.next(results));
431
432 assertEquals(1, results.size());
433
434 assertEquals("First qcode is SEEK_NEXT_COL and second INCLUDE_AND_SEEK_NEXT_ROW",
435 2, scanner.count.get());
436 } finally {
437 scanner.close();
438 }
439 }
440
441
442
443
444
445
446 NavigableSet<byte[]> getCols(String ...strCols) {
447 NavigableSet<byte[]> cols = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
448 for (String col : strCols) {
449 byte[] bytes = Bytes.toBytes(col);
450 cols.add(bytes);
451 }
452 return cols;
453 }
454
455 public void testScanTimeRange() throws IOException {
456 String r1 = "R1";
457
458 KeyValue [] kvs = new KeyValue[] {
459 KeyValueTestUtil.create(r1, CF_STR, "a", 1, KeyValue.Type.Put, "dont-care"),
460 KeyValueTestUtil.create(r1, CF_STR, "a", 2, KeyValue.Type.Put, "dont-care"),
461 KeyValueTestUtil.create(r1, CF_STR, "a", 3, KeyValue.Type.Put, "dont-care"),
462 KeyValueTestUtil.create(r1, CF_STR, "a", 4, KeyValue.Type.Put, "dont-care"),
463 KeyValueTestUtil.create(r1, CF_STR, "a", 5, KeyValue.Type.Put, "dont-care"),
464 };
465 List<KeyValueScanner> scanners = Arrays.<KeyValueScanner>asList(
466 new KeyValueScanner[] {
467 new KeyValueScanFixture(KeyValue.COMPARATOR, kvs)
468 });
469 Scan scanSpec = new Scan(Bytes.toBytes(r1));
470 scanSpec.setTimeRange(0, 6);
471 scanSpec.setMaxVersions();
472 StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
473 getCols("a"), scanners);
474 List<Cell> results = new ArrayList<Cell>();
475 assertEquals(true, scan.next(results));
476 assertEquals(5, results.size());
477 assertEquals(kvs[kvs.length - 1], results.get(0));
478
479 scanSpec = new Scan(Bytes.toBytes(r1));
480 scanSpec.setTimeRange(1, 3);
481 scanSpec.setMaxVersions();
482 scan = new StoreScanner(scanSpec, scanInfo, scanType, getCols("a"),
483 scanners);
484 results = new ArrayList<Cell>();
485 assertEquals(true, scan.next(results));
486 assertEquals(2, results.size());
487
488 scanSpec = new Scan(Bytes.toBytes(r1));
489 scanSpec.setTimeRange(5, 10);
490 scanSpec.setMaxVersions();
491 scan = new StoreScanner(scanSpec, scanInfo, scanType, getCols("a"),
492 scanners);
493 results = new ArrayList<Cell>();
494 assertEquals(true, scan.next(results));
495 assertEquals(1, results.size());
496
497
498 scanSpec = new Scan(Bytes.toBytes(r1));
499 scanSpec.setTimeRange(0, 10);
500 scanSpec.setMaxVersions(3);
501 scan = new StoreScanner(scanSpec, scanInfo, scanType, getCols("a"),
502 scanners);
503 results = new ArrayList<Cell>();
504 assertEquals(true, scan.next(results));
505 assertEquals(3, results.size());
506 }
507
508 public void testScanSameTimestamp() throws IOException {
509
510 KeyValue [] kvs = new KeyValue[] {
511 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
512 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
513 };
514 List<KeyValueScanner> scanners = Arrays.asList(
515 new KeyValueScanner[] {
516 new KeyValueScanFixture(KeyValue.COMPARATOR, kvs)
517 });
518
519 Scan scanSpec = new Scan(Bytes.toBytes("R1"));
520
521 StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
522 getCols("a"), scanners);
523
524 List<Cell> results = new ArrayList<Cell>();
525 assertEquals(true, scan.next(results));
526 assertEquals(1, results.size());
527 assertEquals(kvs[0], results.get(0));
528 }
529
530
531
532
533
534
535
536
537 public void testWontNextToNext() throws IOException {
538
539 KeyValue [] kvs = new KeyValue[] {
540 KeyValueTestUtil.create("R1", "cf", "a", 2, KeyValue.Type.Put, "dont-care"),
541 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
542 KeyValueTestUtil.create("R2", "cf", "a", 1, KeyValue.Type.Put, "dont-care")
543 };
544 List<KeyValueScanner> scanners = scanFixture(kvs);
545
546 Scan scanSpec = new Scan(Bytes.toBytes("R1"));
547
548 StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
549 getCols("a"), scanners);
550
551 List<Cell> results = new ArrayList<Cell>();
552 scan.next(results);
553 assertEquals(1, results.size());
554 assertEquals(kvs[0], results.get(0));
555
556
557 results.clear();
558 scan.next(results);
559 assertEquals(1, results.size());
560 assertEquals(kvs[2], results.get(0));
561
562 results.clear();
563 scan.next(results);
564 assertEquals(0, results.size());
565
566 }
567
568
569 public void testDeleteVersionSameTimestamp() throws IOException {
570 KeyValue [] kvs = new KeyValue [] {
571 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
572 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Delete, "dont-care"),
573 };
574 List<KeyValueScanner> scanners = scanFixture(kvs);
575 Scan scanSpec = new Scan(Bytes.toBytes("R1"));
576 StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
577 getCols("a"), scanners);
578
579 List<Cell> results = new ArrayList<Cell>();
580 assertFalse(scan.next(results));
581 assertEquals(0, results.size());
582 }
583
584
585
586
587
588 public void testDeletedRowThenGoodRow() throws IOException {
589 KeyValue [] kvs = new KeyValue [] {
590 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
591 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Delete, "dont-care"),
592 KeyValueTestUtil.create("R2", "cf", "a", 20, KeyValue.Type.Put, "dont-care")
593 };
594 List<KeyValueScanner> scanners = scanFixture(kvs);
595 Scan scanSpec = new Scan(Bytes.toBytes("R1"));
596 StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
597 getCols("a"), scanners);
598
599 List<Cell> results = new ArrayList<Cell>();
600 assertEquals(true, scan.next(results));
601 assertEquals(0, results.size());
602
603 assertEquals(true, scan.next(results));
604 assertEquals(1, results.size());
605 assertEquals(kvs[2], results.get(0));
606
607 assertEquals(false, scan.next(results));
608 }
609
610 public void testDeleteVersionMaskingMultiplePuts() throws IOException {
611 long now = System.currentTimeMillis();
612 KeyValue [] kvs1 = new KeyValue[] {
613 KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Put, "dont-care"),
614 KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Delete, "dont-care")
615 };
616 KeyValue [] kvs2 = new KeyValue[] {
617 KeyValueTestUtil.create("R1", "cf", "a", now-500, KeyValue.Type.Put, "dont-care"),
618 KeyValueTestUtil.create("R1", "cf", "a", now-100, KeyValue.Type.Put, "dont-care"),
619 KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Put, "dont-care")
620 };
621 List<KeyValueScanner> scanners = scanFixture(kvs1, kvs2);
622
623 StoreScanner scan = new StoreScanner(new Scan(Bytes.toBytes("R1")),
624 scanInfo, scanType, getCols("a"), scanners);
625 List<Cell> results = new ArrayList<Cell>();
626
627
628
629 assertEquals(true, scan.next(results));
630 assertEquals(1, results.size());
631 assertEquals(kvs2[1], results.get(0));
632 }
633 public void testDeleteVersionsMixedAndMultipleVersionReturn() throws IOException {
634 long now = System.currentTimeMillis();
635 KeyValue [] kvs1 = new KeyValue[] {
636 KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Put, "dont-care"),
637 KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Delete, "dont-care")
638 };
639 KeyValue [] kvs2 = new KeyValue[] {
640 KeyValueTestUtil.create("R1", "cf", "a", now-500, KeyValue.Type.Put, "dont-care"),
641 KeyValueTestUtil.create("R1", "cf", "a", now+500, KeyValue.Type.Put, "dont-care"),
642 KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Put, "dont-care"),
643 KeyValueTestUtil.create("R2", "cf", "z", now, KeyValue.Type.Put, "dont-care")
644 };
645 List<KeyValueScanner> scanners = scanFixture(kvs1, kvs2);
646
647 Scan scanSpec = new Scan(Bytes.toBytes("R1")).setMaxVersions(2);
648 StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
649 getCols("a"), scanners);
650 List<Cell> results = new ArrayList<Cell>();
651 assertEquals(true, scan.next(results));
652 assertEquals(2, results.size());
653 assertEquals(kvs2[1], results.get(0));
654 assertEquals(kvs2[0], results.get(1));
655 }
656
657 public void testWildCardOneVersionScan() throws IOException {
658 KeyValue [] kvs = new KeyValue [] {
659 KeyValueTestUtil.create("R1", "cf", "a", 2, KeyValue.Type.Put, "dont-care"),
660 KeyValueTestUtil.create("R1", "cf", "b", 1, KeyValue.Type.Put, "dont-care"),
661 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.DeleteColumn, "dont-care"),
662 };
663 List<KeyValueScanner> scanners = scanFixture(kvs);
664 StoreScanner scan = new StoreScanner(new Scan(Bytes.toBytes("R1")),
665 scanInfo, scanType, null, scanners);
666 List<Cell> results = new ArrayList<Cell>();
667 assertEquals(true, scan.next(results));
668 assertEquals(2, results.size());
669 assertEquals(kvs[0], results.get(0));
670 assertEquals(kvs[1], results.get(1));
671 }
672
673 public void testWildCardScannerUnderDeletes() throws IOException {
674 KeyValue [] kvs = new KeyValue [] {
675 KeyValueTestUtil.create("R1", "cf", "a", 2, KeyValue.Type.Put, "dont-care"),
676
677 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.DeleteColumn, "dont-care"),
678
679 KeyValueTestUtil.create("R1", "cf", "b", 2, KeyValue.Type.Put, "dont-care"),
680 KeyValueTestUtil.create("R1", "cf", "b", 1, KeyValue.Type.Put, "dont-care"),
681
682 KeyValueTestUtil.create("R1", "cf", "c", 10, KeyValue.Type.Delete, "dont-care"),
683 KeyValueTestUtil.create("R1", "cf", "c", 10, KeyValue.Type.Put, "dont-care"),
684 KeyValueTestUtil.create("R1", "cf", "c", 9, KeyValue.Type.Put, "dont-care"),
685
686 KeyValueTestUtil.create("R1", "cf", "d", 11, KeyValue.Type.Put, "dont-care"),
687 KeyValueTestUtil.create("R1", "cf", "d", 10, KeyValue.Type.DeleteColumn, "dont-care"),
688 KeyValueTestUtil.create("R1", "cf", "d", 9, KeyValue.Type.Put, "dont-care"),
689 KeyValueTestUtil.create("R1", "cf", "d", 8, KeyValue.Type.Put, "dont-care"),
690
691 };
692 List<KeyValueScanner> scanners = scanFixture(kvs);
693 StoreScanner scan = new StoreScanner(new Scan().setMaxVersions(2),
694 scanInfo, scanType, null, scanners);
695 List<Cell> results = new ArrayList<Cell>();
696 assertEquals(true, scan.next(results));
697 assertEquals(5, results.size());
698 assertEquals(kvs[0], results.get(0));
699 assertEquals(kvs[2], results.get(1));
700 assertEquals(kvs[3], results.get(2));
701 assertEquals(kvs[6], results.get(3));
702 assertEquals(kvs[7], results.get(4));
703 }
704
705 public void testDeleteFamily() throws IOException {
706 KeyValue [] kvs = new KeyValue[] {
707 KeyValueTestUtil.create("R1", "cf", "a", 100, KeyValue.Type.DeleteFamily, "dont-care"),
708 KeyValueTestUtil.create("R1", "cf", "b", 11, KeyValue.Type.Put, "dont-care"),
709 KeyValueTestUtil.create("R1", "cf", "c", 11, KeyValue.Type.Put, "dont-care"),
710 KeyValueTestUtil.create("R1", "cf", "d", 11, KeyValue.Type.Put, "dont-care"),
711 KeyValueTestUtil.create("R1", "cf", "e", 11, KeyValue.Type.Put, "dont-care"),
712 KeyValueTestUtil.create("R1", "cf", "e", 11, KeyValue.Type.DeleteColumn, "dont-care"),
713 KeyValueTestUtil.create("R1", "cf", "f", 11, KeyValue.Type.Put, "dont-care"),
714 KeyValueTestUtil.create("R1", "cf", "g", 11, KeyValue.Type.Put, "dont-care"),
715 KeyValueTestUtil.create("R1", "cf", "g", 11, KeyValue.Type.Delete, "dont-care"),
716 KeyValueTestUtil.create("R1", "cf", "h", 11, KeyValue.Type.Put, "dont-care"),
717 KeyValueTestUtil.create("R1", "cf", "i", 11, KeyValue.Type.Put, "dont-care"),
718 KeyValueTestUtil.create("R2", "cf", "a", 11, KeyValue.Type.Put, "dont-care"),
719 };
720 List<KeyValueScanner> scanners = scanFixture(kvs);
721 StoreScanner scan = new StoreScanner(
722 new Scan().setMaxVersions(Integer.MAX_VALUE), scanInfo, scanType, null,
723 scanners);
724 List<Cell> results = new ArrayList<Cell>();
725 assertEquals(true, scan.next(results));
726 assertEquals(0, results.size());
727 assertEquals(true, scan.next(results));
728 assertEquals(1, results.size());
729 assertEquals(kvs[kvs.length-1], results.get(0));
730
731 assertEquals(false, scan.next(results));
732 }
733
734 public void testDeleteColumn() throws IOException {
735 KeyValue [] kvs = new KeyValue[] {
736 KeyValueTestUtil.create("R1", "cf", "a", 10, KeyValue.Type.DeleteColumn, "dont-care"),
737 KeyValueTestUtil.create("R1", "cf", "a", 9, KeyValue.Type.Delete, "dont-care"),
738 KeyValueTestUtil.create("R1", "cf", "a", 8, KeyValue.Type.Put, "dont-care"),
739 KeyValueTestUtil.create("R1", "cf", "b", 5, KeyValue.Type.Put, "dont-care")
740 };
741 List<KeyValueScanner> scanners = scanFixture(kvs);
742 StoreScanner scan = new StoreScanner(new Scan(), scanInfo, scanType, null,
743 scanners);
744 List<Cell> results = new ArrayList<Cell>();
745 assertEquals(true, scan.next(results));
746 assertEquals(1, results.size());
747 assertEquals(kvs[3], results.get(0));
748 }
749
750 private static final KeyValue [] kvs = new KeyValue[] {
751 KeyValueTestUtil.create("R1", "cf", "a", 11, KeyValue.Type.Put, "dont-care"),
752 KeyValueTestUtil.create("R1", "cf", "b", 11, KeyValue.Type.Put, "dont-care"),
753 KeyValueTestUtil.create("R1", "cf", "c", 11, KeyValue.Type.Put, "dont-care"),
754 KeyValueTestUtil.create("R1", "cf", "d", 11, KeyValue.Type.Put, "dont-care"),
755 KeyValueTestUtil.create("R1", "cf", "e", 11, KeyValue.Type.Put, "dont-care"),
756 KeyValueTestUtil.create("R1", "cf", "f", 11, KeyValue.Type.Put, "dont-care"),
757 KeyValueTestUtil.create("R1", "cf", "g", 11, KeyValue.Type.Put, "dont-care"),
758 KeyValueTestUtil.create("R1", "cf", "h", 11, KeyValue.Type.Put, "dont-care"),
759 KeyValueTestUtil.create("R1", "cf", "i", 11, KeyValue.Type.Put, "dont-care"),
760 KeyValueTestUtil.create("R2", "cf", "a", 11, KeyValue.Type.Put, "dont-care"),
761 };
762
763 public void testSkipColumn() throws IOException {
764 List<KeyValueScanner> scanners = scanFixture(kvs);
765 StoreScanner scan = new StoreScanner(new Scan(), scanInfo, scanType,
766 getCols("a", "d"), scanners);
767
768 List<Cell> results = new ArrayList<Cell>();
769 assertEquals(true, scan.next(results));
770 assertEquals(2, results.size());
771 assertEquals(kvs[0], results.get(0));
772 assertEquals(kvs[3], results.get(1));
773 results.clear();
774
775 assertEquals(true, scan.next(results));
776 assertEquals(1, results.size());
777 assertEquals(kvs[kvs.length-1], results.get(0));
778
779 results.clear();
780 assertEquals(false, scan.next(results));
781 }
782
783
784
785
786
787 public void testWildCardTtlScan() throws IOException {
788 long now = System.currentTimeMillis();
789 KeyValue [] kvs = new KeyValue[] {
790 KeyValueTestUtil.create("R1", "cf", "a", now-1000, KeyValue.Type.Put, "dont-care"),
791 KeyValueTestUtil.create("R1", "cf", "b", now-10, KeyValue.Type.Put, "dont-care"),
792 KeyValueTestUtil.create("R1", "cf", "c", now-200, KeyValue.Type.Put, "dont-care"),
793 KeyValueTestUtil.create("R1", "cf", "d", now-10000, KeyValue.Type.Put, "dont-care"),
794 KeyValueTestUtil.create("R2", "cf", "a", now, KeyValue.Type.Put, "dont-care"),
795 KeyValueTestUtil.create("R2", "cf", "b", now-10, KeyValue.Type.Put, "dont-care"),
796 KeyValueTestUtil.create("R2", "cf", "c", now-200, KeyValue.Type.Put, "dont-care"),
797 KeyValueTestUtil.create("R2", "cf", "c", now-1000, KeyValue.Type.Put, "dont-care")
798 };
799 List<KeyValueScanner> scanners = scanFixture(kvs);
800 Scan scan = new Scan();
801 scan.setMaxVersions(1);
802 ScanInfo scanInfo = new ScanInfo(CONF, CF, 0, 1, 500, KeepDeletedCells.FALSE, 0,
803 KeyValue.COMPARATOR);
804 ScanType scanType = ScanType.USER_SCAN;
805 StoreScanner scanner =
806 new StoreScanner(scan, scanInfo, scanType,
807 null, scanners);
808
809 List<Cell> results = new ArrayList<Cell>();
810 assertEquals(true, scanner.next(results));
811 assertEquals(2, results.size());
812 assertEquals(kvs[1], results.get(0));
813 assertEquals(kvs[2], results.get(1));
814 results.clear();
815
816 assertEquals(true, scanner.next(results));
817 assertEquals(3, results.size());
818 assertEquals(kvs[4], results.get(0));
819 assertEquals(kvs[5], results.get(1));
820 assertEquals(kvs[6], results.get(2));
821 results.clear();
822
823 assertEquals(false, scanner.next(results));
824 }
825
826 public void testScannerReseekDoesntNPE() throws Exception {
827 List<KeyValueScanner> scanners = scanFixture(kvs);
828 StoreScanner scan = new StoreScanner(new Scan(), scanInfo, scanType,
829 getCols("a", "d"), scanners);
830
831
832
833
834
835 scan.updateReaders(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
836
837 scan.updateReaders(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
838
839 scan.peek();
840 }
841
842
843
844
845
846 public void SKIP_testPeek() throws Exception {
847 KeyValue [] kvs = new KeyValue [] {
848 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
849 KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Delete, "dont-care"),
850 };
851 List<KeyValueScanner> scanners = scanFixture(kvs);
852 Scan scanSpec = new Scan(Bytes.toBytes("R1"));
853 StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
854 getCols("a"), scanners);
855 assertNull(scan.peek());
856 }
857
858
859
860
861 public void testExpiredDeleteFamily() throws Exception {
862 long now = System.currentTimeMillis();
863 KeyValue [] kvs = new KeyValue[] {
864 new KeyValue(Bytes.toBytes("R1"), Bytes.toBytes("cf"), null, now-1000,
865 KeyValue.Type.DeleteFamily),
866 KeyValueTestUtil.create("R1", "cf", "a", now-10, KeyValue.Type.Put,
867 "dont-care"),
868 };
869 List<KeyValueScanner> scanners = scanFixture(kvs);
870 Scan scan = new Scan();
871 scan.setMaxVersions(1);
872
873 ScanInfo scanInfo = new ScanInfo(CONF, CF, 0, 1, 500, KeepDeletedCells.FALSE, 0,
874 KeyValue.COMPARATOR);
875 ScanType scanType = ScanType.USER_SCAN;
876 StoreScanner scanner =
877 new StoreScanner(scan, scanInfo, scanType, null, scanners);
878
879 List<Cell> results = new ArrayList<Cell>();
880 assertEquals(true, scanner.next(results));
881 assertEquals(1, results.size());
882 assertEquals(kvs[1], results.get(0));
883 results.clear();
884
885 assertEquals(false, scanner.next(results));
886 }
887
888 public void testDeleteMarkerLongevity() throws Exception {
889 try {
890 final long now = System.currentTimeMillis();
891 EnvironmentEdgeManagerTestHelper.injectEdge(new EnvironmentEdge() {
892 public long currentTime() {
893 return now;
894 }
895 });
896 KeyValue[] kvs = new KeyValue[]{
897
898 now - 100, KeyValue.Type.DeleteFamily),
899
900 now - 1000, KeyValue.Type.DeleteFamily),
901
902 KeyValue.Type.Put, "v3"),
903
904 KeyValue.Type.Delete, "dontcare"),
905
906 KeyValue.Type.Put, "deleted-version v2"),
907
908 KeyValue.Type.Put, "v1"),
909
910 KeyValue.Type.Put, "v0"),
911
912 now - 100, KeyValue.Type.DeleteColumn, "dont-care"),
913
914 KeyValue.Type.DeleteColumn, "dont-care"),
915
916 KeyValue.Type.Put, "v2"),
917
918 KeyValue.Type.Put, "v1"),
919
920 KeyValue.Type.Delete, "dontcare"),
921
922 KeyValue.Type.Put, "v1"),
923
924 KeyValue.Type.Delete, "dontcare"),
925
926 KeyValue.Type.Put, "expired put"),
927
928 KeyValue.Type.Delete, "not-expired delete"),
929 };
930 List<KeyValueScanner> scanners = scanFixture(kvs);
931 Scan scan = new Scan();
932 scan.setMaxVersions(2);
933 ScanInfo scanInfo = new ScanInfo(CONF, Bytes.toBytes("cf"),
934 0
935 2
936 KeepDeletedCells.FALSE
937 200,
938 KeyValue.COMPARATOR);
939 StoreScanner scanner =
940 new StoreScanner(scan, scanInfo,
941 ScanType.COMPACT_DROP_DELETES, null, scanners,
942 HConstants.OLDEST_TIMESTAMP);
943 List<Cell> results = new ArrayList<Cell>();
944 results = new ArrayList<Cell>();
945 assertEquals(true, scanner.next(results));
946 assertEquals(kvs[0], results.get(0));
947 assertEquals(kvs[2], results.get(1));
948 assertEquals(kvs[3], results.get(2));
949 assertEquals(kvs[5], results.get(3));
950 assertEquals(kvs[9], results.get(4));
951 assertEquals(kvs[14], results.get(5));
952 assertEquals(kvs[15], results.get(6));
953 assertEquals(7, results.size());
954 scanner.close();
955 }finally{
956 EnvironmentEdgeManagerTestHelper.reset();
957 }
958 }
959
960 }
961