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