1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver;
19
20 import static org.apache.hadoop.hbase.HBaseTestingUtility.COLUMNS;
21 import static org.junit.Assert.assertArrayEquals;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.List;
29
30 import org.apache.hadoop.hbase.Cell;
31 import org.apache.hadoop.hbase.CellUtil;
32 import org.apache.hadoop.hbase.HBaseTestingUtility;
33 import org.apache.hadoop.hbase.HConstants;
34 import org.apache.hadoop.hbase.HTableDescriptor;
35 import org.apache.hadoop.hbase.KeepDeletedCells;
36 import org.apache.hadoop.hbase.client.Delete;
37 import org.apache.hadoop.hbase.client.Get;
38 import org.apache.hadoop.hbase.client.Put;
39 import org.apache.hadoop.hbase.client.Result;
40 import org.apache.hadoop.hbase.client.Scan;
41 import org.apache.hadoop.hbase.testclassification.SmallTests;
42 import org.apache.hadoop.hbase.util.Bytes;
43 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
44 import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;
45 import org.apache.hadoop.hbase.util.IncrementingEnvironmentEdge;
46 import org.junit.After;
47 import org.junit.Before;
48 import org.junit.Rule;
49 import org.junit.Test;
50 import org.junit.experimental.categories.Category;
51 import org.junit.rules.TestName;
52
53 @Category(SmallTests.class)
54 public class TestKeepDeletes {
55 HBaseTestingUtility hbu = HBaseTestingUtility.createLocalHTU();
56 private final byte[] T0 = Bytes.toBytes("0");
57 private final byte[] T1 = Bytes.toBytes("1");
58 private final byte[] T2 = Bytes.toBytes("2");
59 private final byte[] T3 = Bytes.toBytes("3");
60 private final byte[] T4 = Bytes.toBytes("4");
61 private final byte[] T5 = Bytes.toBytes("5");
62 private final byte[] T6 = Bytes.toBytes("6");
63
64 private final byte[] c0 = COLUMNS[0];
65 private final byte[] c1 = COLUMNS[1];
66
67 @Rule public TestName name = new TestName();
68
69 @Before
70 public void setUp() throws Exception {
71
72
73
74
75
76
77
78
79
80
81 EnvironmentEdgeManagerTestHelper.injectEdge(new IncrementingEnvironmentEdge());
82 }
83
84 @After
85 public void tearDown() throws Exception {
86 EnvironmentEdgeManager.reset();
87 }
88
89
90
91
92
93
94
95 @Test
96 public void testBasicScenario() throws Exception {
97
98 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 3,
99 HConstants.FOREVER, KeepDeletedCells.TRUE);
100 HRegion region = hbu.createLocalHRegion(htd, null, null);
101
102 long ts = EnvironmentEdgeManager.currentTime();
103 Put p = new Put(T1, ts);
104 p.add(c0, c0, T1);
105 region.put(p);
106 p = new Put(T1, ts+1);
107 p.add(c0, c0, T2);
108 region.put(p);
109 p = new Put(T1, ts+2);
110 p.add(c0, c0, T3);
111 region.put(p);
112 p = new Put(T1, ts+4);
113 p.add(c0, c0, T4);
114 region.put(p);
115
116
117 Delete d = new Delete(T1, ts+2);
118 region.delete(d);
119
120
121
122 assertEquals(3, countDeleteMarkers(region));
123
124
125 Get g = new Get(T1);
126 g.setMaxVersions();
127 g.setTimeRange(0L, ts+2);
128 Result r = region.get(g);
129 checkResult(r, c0, c0, T2,T1);
130
131
132 region.flush(true);
133
134
135 r = region.get(g);
136 checkResult(r, c0, c0, T2);
137
138
139 region.compact(true);
140 region.compact(true);
141
142
143
144 assertEquals(1, countDeleteMarkers(region));
145
146
147 r = region.get(g);
148 checkResult(r, c0, c0, T2);
149
150
151 g.setTimeRange(0L, ts+4);
152 r = region.get(g);
153 assertTrue(r.isEmpty());
154
155
156 p = new Put(T1, ts+5);
157 p.add(c0, c0, T5);
158 region.put(p);
159 p = new Put(T1, ts+6);
160 p.add(c0, c0, T6);
161 region.put(p);
162
163
164
165 p = new Put(T1, ts);
166 p.add(c0, c0, T1);
167 region.put(p);
168 r = region.get(g);
169 assertTrue(r.isEmpty());
170
171 region.flush(true);
172 region.compact(true);
173 region.compact(true);
174
175
176 region.put(p);
177 r = region.get(g);
178 checkResult(r, c0, c0, T1);
179 assertEquals(0, countDeleteMarkers(region));
180
181 HRegion.closeHRegion(region);
182 }
183
184
185
186
187
188
189
190
191
192 @Test
193 public void testRawScanWithoutKeepingDeletes() throws Exception {
194
195 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 3,
196 HConstants.FOREVER, KeepDeletedCells.FALSE);
197 HRegion region = hbu.createLocalHRegion(htd, null, null);
198
199 long ts = EnvironmentEdgeManager.currentTime();
200 Put p = new Put(T1, ts);
201 p.add(c0, c0, T1);
202 region.put(p);
203
204 Delete d = new Delete(T1, ts);
205 d.deleteColumn(c0, c0, ts);
206 region.delete(d);
207
208
209 Scan s = new Scan();
210 s.setRaw(true);
211 s.setMaxVersions();
212 InternalScanner scan = region.getScanner(s);
213 List<Cell> kvs = new ArrayList<Cell>();
214 scan.next(kvs);
215 assertEquals(2, kvs.size());
216
217 region.flush(true);
218 region.compact(true);
219
220
221
222
223 s = new Scan();
224 s.setRaw(true);
225 s.setMaxVersions();
226 scan = region.getScanner(s);
227 kvs = new ArrayList<Cell>();
228 scan.next(kvs);
229 assertTrue(kvs.isEmpty());
230
231 HRegion.closeHRegion(region);
232 }
233
234
235
236
237 @Test
238 public void testWithoutKeepingDeletes() throws Exception {
239
240 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 3,
241 HConstants.FOREVER, KeepDeletedCells.FALSE);
242 HRegion region = hbu.createLocalHRegion(htd, null, null);
243
244 long ts = EnvironmentEdgeManager.currentTime();
245 Put p = new Put(T1, ts);
246 p.add(c0, c0, T1);
247 region.put(p);
248 Delete d = new Delete(T1, ts+2);
249 d.deleteColumn(c0, c0, ts);
250 region.delete(d);
251
252
253 Get g = new Get(T1);
254 g.setMaxVersions();
255 g.setTimeRange(0L, ts+1);
256 Result r = region.get(g);
257 assertTrue(r.isEmpty());
258
259
260 Scan s = new Scan();
261 s.setMaxVersions();
262 s.setTimeRange(0L, ts+1);
263 InternalScanner scanner = region.getScanner(s);
264 List<Cell> kvs = new ArrayList<Cell>();
265 while (scanner.next(kvs))
266 ;
267 assertTrue(kvs.isEmpty());
268
269
270 region.flush(true);
271 region.compact(false);
272 assertEquals(1, countDeleteMarkers(region));
273 region.compact(true);
274
275 assertEquals(0, countDeleteMarkers(region));
276
277 HRegion.closeHRegion(region);
278 }
279
280
281
282
283 @Test
284 public void testRawScanWithColumns() throws Exception {
285 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 3,
286 HConstants.FOREVER, KeepDeletedCells.TRUE);
287 HRegion region = hbu.createLocalHRegion(htd, null, null);
288
289 Scan s = new Scan();
290 s.setRaw(true);
291 s.setMaxVersions();
292 s.addColumn(c0, c0);
293
294 try {
295 region.getScanner(s);
296 fail("raw scanner with columns should have failed");
297 } catch (org.apache.hadoop.hbase.DoNotRetryIOException dnre) {
298
299 }
300
301 HRegion.closeHRegion(region);
302 }
303
304
305
306
307 @Test
308 public void testRawScan() throws Exception {
309 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 3,
310 HConstants.FOREVER, KeepDeletedCells.TRUE);
311 HRegion region = hbu.createLocalHRegion(htd, null, null);
312
313 long ts = EnvironmentEdgeManager.currentTime();
314 Put p = new Put(T1, ts);
315 p.add(c0, c0, T1);
316 region.put(p);
317 p = new Put(T1, ts+2);
318 p.add(c0, c0, T2);
319 region.put(p);
320 p = new Put(T1, ts+4);
321 p.add(c0, c0, T3);
322 region.put(p);
323
324 Delete d = new Delete(T1, ts+1);
325 region.delete(d);
326
327 d = new Delete(T1, ts+2);
328 d.deleteColumn(c0, c0, ts+2);
329 region.delete(d);
330
331 d = new Delete(T1, ts+3);
332 d.deleteColumns(c0, c0, ts+3);
333 region.delete(d);
334
335 Scan s = new Scan();
336 s.setRaw(true);
337 s.setMaxVersions();
338 InternalScanner scan = region.getScanner(s);
339 List<Cell> kvs = new ArrayList<Cell>();
340 scan.next(kvs);
341 assertEquals(8, kvs.size());
342 assertTrue(CellUtil.isDeleteFamily(kvs.get(0)));
343 assertArrayEquals(CellUtil.cloneValue(kvs.get(1)), T3);
344 assertTrue(CellUtil.isDelete(kvs.get(2)));
345 assertTrue(CellUtil.isDelete(kvs.get(3)));
346 assertArrayEquals(CellUtil.cloneValue(kvs.get(4)), T2);
347 assertArrayEquals(CellUtil.cloneValue(kvs.get(5)), T1);
348
349 assertTrue(CellUtil.isDeleteFamily(kvs.get(6)));
350 assertTrue(CellUtil.isDeleteFamily(kvs.get(7)));
351
352
353 s = new Scan();
354 s.setRaw(true);
355 s.setMaxVersions();
356 s.setTimeRange(0, 1);
357 scan = region.getScanner(s);
358 kvs = new ArrayList<Cell>();
359 scan.next(kvs);
360
361 assertTrue(kvs.isEmpty());
362
363
364 s = new Scan();
365 s.setRaw(true);
366 s.setMaxVersions();
367 s.setTimeRange(0, ts+2);
368 scan = region.getScanner(s);
369 kvs = new ArrayList<Cell>();
370 scan.next(kvs);
371 assertEquals(4, kvs.size());
372 assertTrue(CellUtil.isDeleteFamily(kvs.get(0)));
373 assertArrayEquals(CellUtil.cloneValue(kvs.get(1)), T1);
374
375 assertTrue(CellUtil.isDeleteFamily(kvs.get(2)));
376 assertTrue(CellUtil.isDeleteFamily(kvs.get(3)));
377
378
379 s = new Scan();
380 s.setRaw(true);
381 s.setMaxVersions();
382 s.setTimeRange(ts+3, ts+5);
383 scan = region.getScanner(s);
384 kvs = new ArrayList<Cell>();
385 scan.next(kvs);
386 assertEquals(2, kvs.size());
387 assertArrayEquals(CellUtil.cloneValue(kvs.get(0)), T3);
388 assertTrue(CellUtil.isDelete(kvs.get(1)));
389
390
391 HRegion.closeHRegion(region);
392 }
393
394
395
396
397 @Test
398 public void testDeleteMarkerExpirationEmptyStore() throws Exception {
399 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
400 HConstants.FOREVER, KeepDeletedCells.TRUE);
401 HRegion region = hbu.createLocalHRegion(htd, null, null);
402
403 long ts = EnvironmentEdgeManager.currentTime();
404
405 Delete d = new Delete(T1, ts);
406 d.deleteColumns(c0, c0, ts);
407 region.delete(d);
408
409 d = new Delete(T1, ts);
410 d.deleteFamily(c0);
411 region.delete(d);
412
413 d = new Delete(T1, ts);
414 d.deleteColumn(c0, c0, ts+1);
415 region.delete(d);
416
417 d = new Delete(T1, ts);
418 d.deleteColumn(c0, c0, ts+2);
419 region.delete(d);
420
421
422 assertEquals(4, countDeleteMarkers(region));
423
424
425 region.flush(true);
426 assertEquals(4, countDeleteMarkers(region));
427 region.compact(false);
428 assertEquals(4, countDeleteMarkers(region));
429
430
431 region.compact(true);
432 assertEquals(0, countDeleteMarkers(region));
433
434 HRegion.closeHRegion(region);
435 }
436
437
438
439
440 @Test
441 public void testDeleteMarkerExpiration() throws Exception {
442 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
443 HConstants.FOREVER, KeepDeletedCells.TRUE);
444 HRegion region = hbu.createLocalHRegion(htd, null, null);
445
446 long ts = EnvironmentEdgeManager.currentTime();
447
448 Put p = new Put(T1, ts);
449 p.add(c0, c0, T1);
450 region.put(p);
451
452
453 p = new Put(T1, ts-10);
454 p.add(c1, c0, T1);
455 region.put(p);
456
457
458 Delete d = new Delete(T1, ts);
459 d.deleteColumns(c0, c0, ts);
460 region.delete(d);
461
462 d = new Delete(T1, ts);
463 d.deleteFamily(c0, ts);
464 region.delete(d);
465
466 d = new Delete(T1, ts);
467 d.deleteColumn(c0, c0, ts+1);
468 region.delete(d);
469
470 d = new Delete(T1, ts);
471 d.deleteColumn(c0, c0, ts+2);
472 region.delete(d);
473
474
475 assertEquals(4, countDeleteMarkers(region));
476
477 region.flush(true);
478 assertEquals(4, countDeleteMarkers(region));
479 region.compact(false);
480 assertEquals(4, countDeleteMarkers(region));
481
482
483 p = new Put(T1, ts+3);
484 p.add(c0, c0, T1);
485 region.put(p);
486
487 region.flush(true);
488
489 region.compact(true);
490 assertEquals(4, countDeleteMarkers(region));
491
492
493
494 region.compact(true);
495 assertEquals(0, countDeleteMarkers(region));
496
497 HRegion.closeHRegion(region);
498 }
499
500
501
502
503 @Test
504 public void testWithOldRow() throws Exception {
505 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
506 HConstants.FOREVER, KeepDeletedCells.TRUE);
507 HRegion region = hbu.createLocalHRegion(htd, null, null);
508
509 long ts = EnvironmentEdgeManager.currentTime();
510
511 Put p = new Put(T1, ts);
512 p.add(c0, c0, T1);
513 region.put(p);
514
515
516 p = new Put(T2, ts-10);
517 p.add(c0, c0, T1);
518 region.put(p);
519
520
521 Delete d = new Delete(T1, ts);
522 d.deleteColumns(c0, c0, ts);
523 region.delete(d);
524
525 d = new Delete(T1, ts);
526 d.deleteFamily(c0, ts);
527 region.delete(d);
528
529 d = new Delete(T1, ts);
530 d.deleteColumn(c0, c0, ts+1);
531 region.delete(d);
532
533 d = new Delete(T1, ts);
534 d.deleteColumn(c0, c0, ts+2);
535 region.delete(d);
536
537
538 assertEquals(4, countDeleteMarkers(region));
539
540 region.flush(true);
541 assertEquals(4, countDeleteMarkers(region));
542 region.compact(false);
543 assertEquals(4, countDeleteMarkers(region));
544
545
546 p = new Put(T1, ts+3);
547 p.add(c0, c0, T1);
548 region.put(p);
549
550 region.flush(true);
551
552 region.compact(true);
553 assertEquals(4, countDeleteMarkers(region));
554
555
556
557 region.compact(true);
558 assertEquals(4, countDeleteMarkers(region));
559
560
561 p = new Put(T1, ts+4);
562 p.add(c0, c0, T1);
563 region.put(p);
564
565
566
567 region.compact(true);
568 assertEquals(1, countDeleteMarkers(region));
569
570
571
572 region.compact(true);
573 assertEquals(1, countDeleteMarkers(region));
574
575 HRegion.closeHRegion(region);
576 }
577
578
579
580
581 @Test
582 public void testRanges() throws Exception {
583 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 3,
584 HConstants.FOREVER, KeepDeletedCells.TRUE);
585 HRegion region = hbu.createLocalHRegion(htd, null, null);
586
587 long ts = EnvironmentEdgeManager.currentTime();
588 Put p = new Put(T1, ts);
589 p.add(c0, c0, T1);
590 p.add(c0, c1, T1);
591 p.add(c1, c0, T1);
592 p.add(c1, c1, T1);
593 region.put(p);
594
595 p = new Put(T2, ts);
596 p.add(c0, c0, T1);
597 p.add(c0, c1, T1);
598 p.add(c1, c0, T1);
599 p.add(c1, c1, T1);
600 region.put(p);
601
602 p = new Put(T1, ts+1);
603 p.add(c0, c0, T2);
604 p.add(c0, c1, T2);
605 p.add(c1, c0, T2);
606 p.add(c1, c1, T2);
607 region.put(p);
608
609 p = new Put(T2, ts+1);
610 p.add(c0, c0, T2);
611 p.add(c0, c1, T2);
612 p.add(c1, c0, T2);
613 p.add(c1, c1, T2);
614 region.put(p);
615
616 Delete d = new Delete(T1, ts+2);
617 d.deleteColumns(c0, c0, ts+2);
618 region.delete(d);
619
620 d = new Delete(T1, ts+2);
621 d.deleteFamily(c1, ts+2);
622 region.delete(d);
623
624 d = new Delete(T2, ts+2);
625 d.deleteFamily(c0, ts+2);
626 region.delete(d);
627
628
629 d = new Delete(T1, ts-10);
630 d.deleteFamily(c1, ts-10);
631 region.delete(d);
632
633
634 checkGet(region, T1, c0, c0, ts+2, T2, T1);
635 checkGet(region, T1, c0, c1, ts+2, T2, T1);
636 checkGet(region, T1, c1, c0, ts+2, T2, T1);
637 checkGet(region, T1, c1, c1, ts+2, T2, T1);
638
639 checkGet(region, T2, c0, c0, ts+2, T2, T1);
640 checkGet(region, T2, c0, c1, ts+2, T2, T1);
641 checkGet(region, T2, c1, c0, ts+2, T2, T1);
642 checkGet(region, T2, c1, c1, ts+2, T2, T1);
643
644
645 checkGet(region, T1, c0, c0, ts+3);
646 checkGet(region, T1, c0, c1, ts+3, T2, T1);
647 checkGet(region, T1, c1, c0, ts+3);
648 checkGet(region, T1, c1, c1, ts+3);
649
650 checkGet(region, T2, c0, c0, ts+3);
651 checkGet(region, T2, c0, c1, ts+3);
652 checkGet(region, T2, c1, c0, ts+3, T2, T1);
653 checkGet(region, T2, c1, c1, ts+3, T2, T1);
654
655 HRegion.closeHRegion(region);
656 }
657
658
659
660
661
662
663 @Test
664 public void testDeleteMarkerVersioning() throws Exception {
665 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
666 HConstants.FOREVER, KeepDeletedCells.TRUE);
667 HRegion region = hbu.createLocalHRegion(htd, null, null);
668
669 long ts = EnvironmentEdgeManager.currentTime();
670 Put p = new Put(T1, ts);
671 p.add(c0, c0, T1);
672 region.put(p);
673
674
675
676 p = new Put(T1, ts-10);
677 p.add(c0, c1, T1);
678 region.put(p);
679
680 Delete d = new Delete(T1, ts);
681
682 d.deleteColumns(c0, c0, ts);
683 region.delete(d);
684
685 d = new Delete(T1, ts+1);
686 d.deleteColumn(c0, c0, ts+1);
687 region.delete(d);
688
689 d = new Delete(T1, ts+3);
690 d.deleteColumn(c0, c0, ts+3);
691 region.delete(d);
692
693 region.flush(true);
694 region.compact(true);
695 region.compact(true);
696 assertEquals(3, countDeleteMarkers(region));
697
698
699
700
701 p = new Put(T1, ts+2);
702 p.add(c0, c0, T2);
703 region.put(p);
704
705
706 assertEquals(3, countDeleteMarkers(region));
707
708 p = new Put(T1, ts+3);
709 p.add(c0, c0, T3);
710 region.put(p);
711
712
713
714
715
716
717
718
719
720
721
722 assertEquals(1, countDeleteMarkers(region));
723
724
725 region.flush(true);
726
727
728
729
730
731
732 assertEquals(3, countDeleteMarkers(region));
733
734 region.compact(true);
735 assertEquals(3, countDeleteMarkers(region));
736
737
738 p = new Put(T1, ts+4);
739 p.add(c0, c0, T4);
740 region.put(p);
741
742 region.flush(true);
743
744
745 assertEquals(1, countDeleteMarkers(region));
746 region.compact(true);
747 region.compact(true);
748 assertEquals(1, countDeleteMarkers(region));
749
750 HRegion.closeHRegion(region);
751 }
752
753
754
755
756 public void testWithMixedCFs() throws Exception {
757 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
758 HConstants.FOREVER, KeepDeletedCells.TRUE);
759 HRegion region = hbu.createLocalHRegion(htd, null, null);
760
761 long ts = EnvironmentEdgeManager.currentTime();
762
763 Put p = new Put(T1, ts);
764 p.add(c0, c0, T1);
765 p.add(c0, c1, T1);
766 p.add(c1, c0, T1);
767 p.add(c1, c1, T1);
768 region.put(p);
769
770 p = new Put(T2, ts+1);
771 p.add(c0, c0, T2);
772 p.add(c0, c1, T2);
773 p.add(c1, c0, T2);
774 p.add(c1, c1, T2);
775 region.put(p);
776
777
778 Delete d = new Delete(T1, ts+1);
779 region.delete(d);
780
781 d = new Delete(T2, ts+2);
782 region.delete(d);
783
784 Scan s = new Scan(T1);
785 s.setTimeRange(0, ts+1);
786 InternalScanner scanner = region.getScanner(s);
787 List<Cell> kvs = new ArrayList<Cell>();
788 scanner.next(kvs);
789 assertEquals(4, kvs.size());
790 scanner.close();
791
792 s = new Scan(T2);
793 s.setTimeRange(0, ts+2);
794 scanner = region.getScanner(s);
795 kvs = new ArrayList<Cell>();
796 scanner.next(kvs);
797 assertEquals(4, kvs.size());
798 scanner.close();
799
800 HRegion.closeHRegion(region);
801 }
802
803
804
805
806
807 @Test
808 public void testWithMinVersions() throws Exception {
809 HTableDescriptor htd =
810 hbu.createTableDescriptor(name.getMethodName(), 3, 1000, 1, KeepDeletedCells.TRUE);
811 HRegion region = hbu.createLocalHRegion(htd, null, null);
812
813 long ts = EnvironmentEdgeManager.currentTime() - 2000;
814
815 Put p = new Put(T1, ts);
816 p.add(c0, c0, T3);
817 region.put(p);
818 p = new Put(T1, ts-1);
819 p.add(c0, c0, T2);
820 region.put(p);
821 p = new Put(T1, ts-3);
822 p.add(c0, c0, T1);
823 region.put(p);
824 p = new Put(T1, ts-4);
825 p.add(c0, c0, T0);
826 region.put(p);
827
828
829
830
831 Delete d = new Delete(T1, ts-1);
832 region.delete(d);
833
834 d = new Delete(T1, ts-2);
835 d.deleteColumns(c0, c0, ts-1);
836 region.delete(d);
837
838 Get g = new Get(T1);
839 g.setMaxVersions();
840 g.setTimeRange(0L, ts-2);
841 Result r = region.get(g);
842 checkResult(r, c0, c0, T1,T0);
843
844
845 assertEquals(4, countDeleteMarkers(region));
846
847 region.flush(true);
848
849 assertEquals(4, countDeleteMarkers(region));
850
851 r = region.get(g);
852 checkResult(r, c0, c0, T1);
853 p = new Put(T1, ts+1);
854 p.add(c0, c0, T4);
855 region.put(p);
856 region.flush(true);
857
858 assertEquals(4, countDeleteMarkers(region));
859
860 r = region.get(g);
861 checkResult(r, c0, c0, T1);
862
863
864
865 p = new Put(T1, ts+2);
866 p.add(c0, c0, T5);
867 region.put(p);
868
869 region.flush(true);
870 region.compact(true);
871
872 assertEquals(2, countDeleteMarkers(region));
873
874
875
876 region.compact(true);
877 assertEquals(0, countDeleteMarkers(region));
878
879 HRegion.closeHRegion(region);
880 }
881
882
883
884
885
886 @Test
887 public void testWithTTL() throws Exception {
888 HTableDescriptor htd =
889 hbu.createTableDescriptor(name.getMethodName(), 1, 1000, 1, KeepDeletedCells.TTL);
890 HRegion region = hbu.createLocalHRegion(htd, null, null);
891
892 long ts = EnvironmentEdgeManager.currentTime() - 2000;
893
894 Put p = new Put(T1, ts);
895 p.add(c0, c0, T3);
896 region.put(p);
897
898
899 p = new Put(T2, ts-10);
900 p.add(c0, c0, T1);
901 region.put(p);
902
903 checkGet(region, T1, c0, c0, ts+1, T3);
904
905 Delete d = new Delete(T1, ts+2);
906 region.delete(d);
907
908 checkGet(region, T1, c0, c0, ts+1, T3);
909
910
911 assertEquals(3, countDeleteMarkers(region));
912
913 region.flush(true);
914
915 assertEquals(3, countDeleteMarkers(region));
916
917
918 checkGet(region, T1, c0, c0, ts+1);
919
920 region.compact(true);
921
922 assertEquals(0, countDeleteMarkers(region));
923
924 HRegion.closeHRegion(region);
925 }
926
927 private void checkGet(Region region, byte[] row, byte[] fam, byte[] col,
928 long time, byte[]... vals) throws IOException {
929 Get g = new Get(row);
930 g.addColumn(fam, col);
931 g.setMaxVersions();
932 g.setTimeRange(0L, time);
933 Result r = region.get(g);
934 checkResult(r, fam, col, vals);
935
936 }
937
938 private int countDeleteMarkers(Region region) throws IOException {
939 Scan s = new Scan();
940 s.setRaw(true);
941
942 s.setMaxVersions(region.getStores().iterator().next().getScanInfo().getMaxVersions());
943 InternalScanner scan = region.getScanner(s);
944 List<Cell> kvs = new ArrayList<Cell>();
945 int res = 0;
946 boolean hasMore;
947 do {
948 hasMore = scan.next(kvs);
949 for (Cell kv : kvs) {
950 if(CellUtil.isDelete(kv)) res++;
951 }
952 kvs.clear();
953 } while (hasMore);
954 scan.close();
955 return res;
956 }
957
958 private void checkResult(Result r, byte[] fam, byte[] col, byte[] ... vals) {
959 assertEquals(r.size(), vals.length);
960 List<Cell> kvs = r.getColumnCells(fam, col);
961 assertEquals(kvs.size(), vals.length);
962 for (int i=0;i<vals.length;i++) {
963 assertArrayEquals(CellUtil.cloneValue(kvs.get(i)), vals[i]);
964 }
965 }
966
967
968 }
969