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.currentTimeMillis();
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.flushcache();
133
134
135 r = region.get(g);
136 checkResult(r, c0, c0, T2);
137
138
139 region.compactStores(true);
140 region.compactStores(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.flushcache();
172 region.compactStores(true);
173 region.compactStores(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.currentTimeMillis();
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.flushcache();
218 region.compactStores(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.currentTimeMillis();
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 assertTrue(kvs.isEmpty());
267
268
269 region.flushcache();
270 region.compactStores();
271 assertEquals(1, countDeleteMarkers(region));
272 region.compactStores(true);
273
274 assertEquals(0, countDeleteMarkers(region));
275
276 HRegion.closeHRegion(region);
277 }
278
279
280
281
282 @Test
283 public void testRawScanWithColumns() throws Exception {
284 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 3,
285 HConstants.FOREVER, KeepDeletedCells.TRUE);
286 HRegion region = hbu.createLocalHRegion(htd, null, null);
287
288 Scan s = new Scan();
289 s.setRaw(true);
290 s.setMaxVersions();
291 s.addColumn(c0, c0);
292
293 try {
294 region.getScanner(s);
295 fail("raw scanner with columns should have failed");
296 } catch (org.apache.hadoop.hbase.DoNotRetryIOException dnre) {
297
298 }
299
300 HRegion.closeHRegion(region);
301 }
302
303
304
305
306 @Test
307 public void testRawScan() throws Exception {
308 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 3,
309 HConstants.FOREVER, KeepDeletedCells.TRUE);
310 HRegion region = hbu.createLocalHRegion(htd, null, null);
311
312 long ts = EnvironmentEdgeManager.currentTimeMillis();
313 Put p = new Put(T1, ts);
314 p.add(c0, c0, T1);
315 region.put(p);
316 p = new Put(T1, ts+2);
317 p.add(c0, c0, T2);
318 region.put(p);
319 p = new Put(T1, ts+4);
320 p.add(c0, c0, T3);
321 region.put(p);
322
323 Delete d = new Delete(T1, ts+1);
324 region.delete(d);
325
326 d = new Delete(T1, ts+2);
327 d.deleteColumn(c0, c0, ts+2);
328 region.delete(d);
329
330 d = new Delete(T1, ts+3);
331 d.deleteColumns(c0, c0, ts+3);
332 region.delete(d);
333
334 Scan s = new Scan();
335 s.setRaw(true);
336 s.setMaxVersions();
337 InternalScanner scan = region.getScanner(s);
338 List<Cell> kvs = new ArrayList<Cell>();
339 scan.next(kvs);
340 assertEquals(8, kvs.size());
341 assertTrue(CellUtil.isDeleteFamily(kvs.get(0)));
342 assertArrayEquals(CellUtil.cloneValue(kvs.get(1)), T3);
343 assertTrue(CellUtil.isDelete(kvs.get(2)));
344 assertTrue(CellUtil.isDelete(kvs.get(3)));
345 assertArrayEquals(CellUtil.cloneValue(kvs.get(4)), T2);
346 assertArrayEquals(CellUtil.cloneValue(kvs.get(5)), T1);
347
348 assertTrue(CellUtil.isDeleteFamily(kvs.get(6)));
349 assertTrue(CellUtil.isDeleteFamily(kvs.get(7)));
350
351
352 s = new Scan();
353 s.setRaw(true);
354 s.setMaxVersions();
355 s.setTimeRange(0, 1);
356 scan = region.getScanner(s);
357 kvs = new ArrayList<Cell>();
358 scan.next(kvs);
359
360 assertTrue(kvs.isEmpty());
361
362
363 s = new Scan();
364 s.setRaw(true);
365 s.setMaxVersions();
366 s.setTimeRange(0, ts+2);
367 scan = region.getScanner(s);
368 kvs = new ArrayList<Cell>();
369 scan.next(kvs);
370 assertEquals(4, kvs.size());
371 assertTrue(CellUtil.isDeleteFamily(kvs.get(0)));
372 assertArrayEquals(CellUtil.cloneValue(kvs.get(1)), T1);
373
374 assertTrue(CellUtil.isDeleteFamily(kvs.get(2)));
375 assertTrue(CellUtil.isDeleteFamily(kvs.get(3)));
376
377
378 s = new Scan();
379 s.setRaw(true);
380 s.setMaxVersions();
381 s.setTimeRange(ts+3, ts+5);
382 scan = region.getScanner(s);
383 kvs = new ArrayList<Cell>();
384 scan.next(kvs);
385 assertEquals(2, kvs.size());
386 assertArrayEquals(CellUtil.cloneValue(kvs.get(0)), T3);
387 assertTrue(CellUtil.isDelete(kvs.get(1)));
388
389
390 HRegion.closeHRegion(region);
391 }
392
393
394
395
396 @Test
397 public void testDeleteMarkerExpirationEmptyStore() throws Exception {
398 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
399 HConstants.FOREVER, KeepDeletedCells.TRUE);
400 HRegion region = hbu.createLocalHRegion(htd, null, null);
401
402 long ts = EnvironmentEdgeManager.currentTimeMillis();
403
404 Delete d = new Delete(T1, ts);
405 d.deleteColumns(c0, c0, ts);
406 region.delete(d);
407
408 d = new Delete(T1, ts);
409 d.deleteFamily(c0);
410 region.delete(d);
411
412 d = new Delete(T1, ts);
413 d.deleteColumn(c0, c0, ts+1);
414 region.delete(d);
415
416 d = new Delete(T1, ts);
417 d.deleteColumn(c0, c0, ts+2);
418 region.delete(d);
419
420
421 assertEquals(4, countDeleteMarkers(region));
422
423
424 region.flushcache();
425 assertEquals(4, countDeleteMarkers(region));
426 region.compactStores(false);
427 assertEquals(4, countDeleteMarkers(region));
428
429
430 region.compactStores(true);
431 assertEquals(0, countDeleteMarkers(region));
432
433 HRegion.closeHRegion(region);
434 }
435
436
437
438
439 @Test
440 public void testDeleteMarkerExpiration() throws Exception {
441 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
442 HConstants.FOREVER, KeepDeletedCells.TRUE);
443 HRegion region = hbu.createLocalHRegion(htd, null, null);
444
445 long ts = EnvironmentEdgeManager.currentTimeMillis();
446
447 Put p = new Put(T1, ts);
448 p.add(c0, c0, T1);
449 region.put(p);
450
451
452 p = new Put(T1, ts-10);
453 p.add(c1, c0, T1);
454 region.put(p);
455
456
457 Delete d = new Delete(T1, ts);
458 d.deleteColumns(c0, c0, ts);
459 region.delete(d);
460
461 d = new Delete(T1, ts);
462 d.deleteFamily(c0, ts);
463 region.delete(d);
464
465 d = new Delete(T1, ts);
466 d.deleteColumn(c0, c0, ts+1);
467 region.delete(d);
468
469 d = new Delete(T1, ts);
470 d.deleteColumn(c0, c0, ts+2);
471 region.delete(d);
472
473
474 assertEquals(4, countDeleteMarkers(region));
475
476 region.flushcache();
477 assertEquals(4, countDeleteMarkers(region));
478 region.compactStores(false);
479 assertEquals(4, countDeleteMarkers(region));
480
481
482 p = new Put(T1, ts+3);
483 p.add(c0, c0, T1);
484 region.put(p);
485
486 region.flushcache();
487
488 region.compactStores(true);
489 assertEquals(4, countDeleteMarkers(region));
490
491
492
493 region.compactStores(true);
494 assertEquals(0, countDeleteMarkers(region));
495
496 HRegion.closeHRegion(region);
497 }
498
499
500
501
502 @Test
503 public void testWithOldRow() throws Exception {
504 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
505 HConstants.FOREVER, KeepDeletedCells.TRUE);
506 HRegion region = hbu.createLocalHRegion(htd, null, null);
507
508 long ts = EnvironmentEdgeManager.currentTimeMillis();
509
510 Put p = new Put(T1, ts);
511 p.add(c0, c0, T1);
512 region.put(p);
513
514
515 p = new Put(T2, ts-10);
516 p.add(c0, c0, T1);
517 region.put(p);
518
519
520 Delete d = new Delete(T1, ts);
521 d.deleteColumns(c0, c0, ts);
522 region.delete(d);
523
524 d = new Delete(T1, ts);
525 d.deleteFamily(c0, ts);
526 region.delete(d);
527
528 d = new Delete(T1, ts);
529 d.deleteColumn(c0, c0, ts+1);
530 region.delete(d);
531
532 d = new Delete(T1, ts);
533 d.deleteColumn(c0, c0, ts+2);
534 region.delete(d);
535
536
537 assertEquals(4, countDeleteMarkers(region));
538
539 region.flushcache();
540 assertEquals(4, countDeleteMarkers(region));
541 region.compactStores(false);
542 assertEquals(4, countDeleteMarkers(region));
543
544
545 p = new Put(T1, ts+3);
546 p.add(c0, c0, T1);
547 region.put(p);
548
549 region.flushcache();
550
551 region.compactStores(true);
552 assertEquals(4, countDeleteMarkers(region));
553
554
555
556 region.compactStores(true);
557 assertEquals(4, countDeleteMarkers(region));
558
559
560 p = new Put(T1, ts+4);
561 p.add(c0, c0, T1);
562 region.put(p);
563
564
565
566 region.compactStores(true);
567 assertEquals(1, countDeleteMarkers(region));
568
569
570
571 region.compactStores(true);
572 assertEquals(1, countDeleteMarkers(region));
573
574 HRegion.closeHRegion(region);
575 }
576
577
578
579
580 @Test
581 public void testRanges() throws Exception {
582 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 3,
583 HConstants.FOREVER, KeepDeletedCells.TRUE);
584 HRegion region = hbu.createLocalHRegion(htd, null, null);
585
586 long ts = EnvironmentEdgeManager.currentTimeMillis();
587 Put p = new Put(T1, ts);
588 p.add(c0, c0, T1);
589 p.add(c0, c1, T1);
590 p.add(c1, c0, T1);
591 p.add(c1, c1, T1);
592 region.put(p);
593
594 p = new Put(T2, ts);
595 p.add(c0, c0, T1);
596 p.add(c0, c1, T1);
597 p.add(c1, c0, T1);
598 p.add(c1, c1, T1);
599 region.put(p);
600
601 p = new Put(T1, ts+1);
602 p.add(c0, c0, T2);
603 p.add(c0, c1, T2);
604 p.add(c1, c0, T2);
605 p.add(c1, c1, T2);
606 region.put(p);
607
608 p = new Put(T2, ts+1);
609 p.add(c0, c0, T2);
610 p.add(c0, c1, T2);
611 p.add(c1, c0, T2);
612 p.add(c1, c1, T2);
613 region.put(p);
614
615 Delete d = new Delete(T1, ts+2);
616 d.deleteColumns(c0, c0, ts+2);
617 region.delete(d);
618
619 d = new Delete(T1, ts+2);
620 d.deleteFamily(c1, ts+2);
621 region.delete(d);
622
623 d = new Delete(T2, ts+2);
624 d.deleteFamily(c0, ts+2);
625 region.delete(d);
626
627
628 d = new Delete(T1, ts-10);
629 d.deleteFamily(c1, ts-10);
630 region.delete(d);
631
632
633 checkGet(region, T1, c0, c0, ts+2, T2, T1);
634 checkGet(region, T1, c0, c1, ts+2, T2, T1);
635 checkGet(region, T1, c1, c0, ts+2, T2, T1);
636 checkGet(region, T1, c1, c1, ts+2, T2, T1);
637
638 checkGet(region, T2, c0, c0, ts+2, T2, T1);
639 checkGet(region, T2, c0, c1, ts+2, T2, T1);
640 checkGet(region, T2, c1, c0, ts+2, T2, T1);
641 checkGet(region, T2, c1, c1, ts+2, T2, T1);
642
643
644 checkGet(region, T1, c0, c0, ts+3);
645 checkGet(region, T1, c0, c1, ts+3, T2, T1);
646 checkGet(region, T1, c1, c0, ts+3);
647 checkGet(region, T1, c1, c1, ts+3);
648
649 checkGet(region, T2, c0, c0, ts+3);
650 checkGet(region, T2, c0, c1, ts+3);
651 checkGet(region, T2, c1, c0, ts+3, T2, T1);
652 checkGet(region, T2, c1, c1, ts+3, T2, T1);
653
654 HRegion.closeHRegion(region);
655 }
656
657
658
659
660
661
662 @Test
663 public void testDeleteMarkerVersioning() throws Exception {
664 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
665 HConstants.FOREVER, KeepDeletedCells.TRUE);
666 HRegion region = hbu.createLocalHRegion(htd, null, null);
667
668 long ts = EnvironmentEdgeManager.currentTimeMillis();
669 Put p = new Put(T1, ts);
670 p.add(c0, c0, T1);
671 region.put(p);
672
673
674
675 p = new Put(T1, ts-10);
676 p.add(c0, c1, T1);
677 region.put(p);
678
679 Delete d = new Delete(T1, ts);
680
681 d.deleteColumns(c0, c0, ts);
682 region.delete(d);
683
684 d = new Delete(T1, ts+1);
685 d.deleteColumn(c0, c0, ts+1);
686 region.delete(d);
687
688 d = new Delete(T1, ts+3);
689 d.deleteColumn(c0, c0, ts+3);
690 region.delete(d);
691
692 region.flushcache();
693 region.compactStores(true);
694 region.compactStores(true);
695 assertEquals(3, countDeleteMarkers(region));
696
697
698
699
700 p = new Put(T1, ts+2);
701 p.add(c0, c0, T2);
702 region.put(p);
703
704
705 assertEquals(3, countDeleteMarkers(region));
706
707 p = new Put(T1, ts+3);
708 p.add(c0, c0, T3);
709 region.put(p);
710
711
712
713
714
715
716
717
718
719
720
721 assertEquals(1, countDeleteMarkers(region));
722
723
724 region.flushcache();
725
726
727
728
729
730
731 assertEquals(3, countDeleteMarkers(region));
732
733 region.compactStores(true);
734 assertEquals(3, countDeleteMarkers(region));
735
736
737 p = new Put(T1, ts+4);
738 p.add(c0, c0, T4);
739 region.put(p);
740
741 region.flushcache();
742
743
744 assertEquals(1, countDeleteMarkers(region));
745 region.compactStores(true);
746 region.compactStores(true);
747 assertEquals(1, countDeleteMarkers(region));
748
749 HRegion.closeHRegion(region);
750 }
751
752
753
754
755 public void testWithMixedCFs() throws Exception {
756 HTableDescriptor htd = hbu.createTableDescriptor(name.getMethodName(), 0, 1,
757 HConstants.FOREVER, KeepDeletedCells.TRUE);
758 HRegion region = hbu.createLocalHRegion(htd, null, null);
759
760 long ts = EnvironmentEdgeManager.currentTimeMillis();
761
762 Put p = new Put(T1, ts);
763 p.add(c0, c0, T1);
764 p.add(c0, c1, T1);
765 p.add(c1, c0, T1);
766 p.add(c1, c1, T1);
767 region.put(p);
768
769 p = new Put(T2, ts+1);
770 p.add(c0, c0, T2);
771 p.add(c0, c1, T2);
772 p.add(c1, c0, T2);
773 p.add(c1, c1, T2);
774 region.put(p);
775
776
777 Delete d = new Delete(T1, ts+1);
778 region.delete(d);
779
780 d = new Delete(T2, ts+2);
781 region.delete(d);
782
783 Scan s = new Scan(T1);
784 s.setTimeRange(0, ts+1);
785 InternalScanner scanner = region.getScanner(s);
786 List<Cell> kvs = new ArrayList<Cell>();
787 scanner.next(kvs);
788 assertEquals(4, kvs.size());
789 scanner.close();
790
791 s = new Scan(T2);
792 s.setTimeRange(0, ts+2);
793 scanner = region.getScanner(s);
794 kvs = new ArrayList<Cell>();
795 scanner.next(kvs);
796 assertEquals(4, kvs.size());
797 scanner.close();
798
799 HRegion.closeHRegion(region);
800 }
801
802
803
804
805
806 @Test
807 public void testWithMinVersions() throws Exception {
808 HTableDescriptor htd =
809 hbu.createTableDescriptor(name.getMethodName(), 3, 1000, 1, KeepDeletedCells.TRUE);
810 HRegion region = hbu.createLocalHRegion(htd, null, null);
811
812 long ts = EnvironmentEdgeManager.currentTimeMillis() - 2000;
813
814 Put p = new Put(T1, ts);
815 p.add(c0, c0, T3);
816 region.put(p);
817 p = new Put(T1, ts-1);
818 p.add(c0, c0, T2);
819 region.put(p);
820 p = new Put(T1, ts-3);
821 p.add(c0, c0, T1);
822 region.put(p);
823 p = new Put(T1, ts-4);
824 p.add(c0, c0, T0);
825 region.put(p);
826
827
828
829
830 Delete d = new Delete(T1, ts-1);
831 region.delete(d);
832
833 d = new Delete(T1, ts-2);
834 d.deleteColumns(c0, c0, ts-1);
835 region.delete(d);
836
837 Get g = new Get(T1);
838 g.setMaxVersions();
839 g.setTimeRange(0L, ts-2);
840 Result r = region.get(g);
841 checkResult(r, c0, c0, T1,T0);
842
843
844 assertEquals(4, countDeleteMarkers(region));
845
846 region.flushcache();
847
848 assertEquals(4, countDeleteMarkers(region));
849
850 r = region.get(g);
851 checkResult(r, c0, c0, T1);
852 p = new Put(T1, ts+1);
853 p.add(c0, c0, T4);
854 region.put(p);
855 region.flushcache();
856
857 assertEquals(4, countDeleteMarkers(region));
858
859 r = region.get(g);
860 checkResult(r, c0, c0, T1);
861
862
863
864 p = new Put(T1, ts+2);
865 p.add(c0, c0, T5);
866 region.put(p);
867
868 region.flushcache();
869 region.compactStores(true);
870
871 assertEquals(2, countDeleteMarkers(region));
872
873
874
875 region.compactStores(true);
876 assertEquals(0, countDeleteMarkers(region));
877
878 HRegion.closeHRegion(region);
879 }
880
881
882
883
884
885 @Test
886 public void testWithTTL() throws Exception {
887 HTableDescriptor htd =
888 hbu.createTableDescriptor(name.getMethodName(), 1, 1000, 1, KeepDeletedCells.TTL);
889 HRegion region = hbu.createLocalHRegion(htd, null, null);
890
891 long ts = EnvironmentEdgeManager.currentTimeMillis() - 2000;
892
893 Put p = new Put(T1, ts);
894 p.add(c0, c0, T3);
895 region.put(p);
896
897
898 p = new Put(T2, ts-10);
899 p.add(c0, c0, T1);
900 region.put(p);
901
902 checkGet(region, T1, c0, c0, ts+1, T3);
903
904 Delete d = new Delete(T1, ts+2);
905 region.delete(d);
906
907 checkGet(region, T1, c0, c0, ts+1, T3);
908
909
910 assertEquals(3, countDeleteMarkers(region));
911
912 region.flushcache();
913
914 assertEquals(3, countDeleteMarkers(region));
915
916
917 checkGet(region, T1, c0, c0, ts+1);
918
919 region.compactStores(true);
920
921 assertEquals(0, countDeleteMarkers(region));
922
923 HRegion.closeHRegion(region);
924 }
925
926 private void checkGet(HRegion region, byte[] row, byte[] fam, byte[] col,
927 long time, byte[]... vals) throws IOException {
928 Get g = new Get(row);
929 g.addColumn(fam, col);
930 g.setMaxVersions();
931 g.setTimeRange(0L, time);
932 Result r = region.get(g);
933 checkResult(r, fam, col, vals);
934
935 }
936
937 private int countDeleteMarkers(HRegion region) throws IOException {
938 Scan s = new Scan();
939 s.setRaw(true);
940
941 s.setMaxVersions(region.getStores().values().iterator().next().getScanInfo().getMaxVersions());
942 InternalScanner scan = region.getScanner(s);
943 List<Cell> kvs = new ArrayList<Cell>();
944 int res = 0;
945 boolean hasMore;
946 do {
947 hasMore = scan.next(kvs);
948 for (Cell kv : kvs) {
949 if(CellUtil.isDelete(kv)) res++;
950 }
951 kvs.clear();
952 } while (hasMore);
953 scan.close();
954 return res;
955 }
956
957 private void checkResult(Result r, byte[] fam, byte[] col, byte[] ... vals) {
958 assertEquals(r.size(), vals.length);
959 List<Cell> kvs = r.getColumnCells(fam, col);
960 assertEquals(kvs.size(), vals.length);
961 for (int i=0;i<vals.length;i++) {
962 assertArrayEquals(CellUtil.cloneValue(kvs.get(i)), vals[i]);
963 }
964 }
965
966
967 }
968