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