1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.io.encoding;
19
20 import static org.junit.Assert.assertEquals;
21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25
26 import org.apache.hadoop.fs.Path;
27 import org.apache.hadoop.hbase.Cell;
28 import org.apache.hadoop.hbase.HBaseTestingUtility;
29 import org.apache.hadoop.hbase.HColumnDescriptor;
30 import org.apache.hadoop.hbase.HConstants;
31 import org.apache.hadoop.hbase.HRegionInfo;
32 import org.apache.hadoop.hbase.HTableDescriptor;
33 import org.apache.hadoop.hbase.TableName;
34 import org.apache.hadoop.hbase.client.Put;
35 import org.apache.hadoop.hbase.client.Scan;
36 import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;
37 import org.apache.hadoop.hbase.regionserver.Region;
38 import org.apache.hadoop.hbase.regionserver.RegionScanner;
39 import org.apache.hadoop.hbase.testclassification.SmallTests;
40 import org.apache.hadoop.hbase.util.Bytes;
41 import org.junit.After;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.experimental.categories.Category;
45
46 @Category({ SmallTests.class })
47 public class TestSeekBeforeWithReverseScan {
48 private final HBaseTestingUtility testUtil = new HBaseTestingUtility();
49
50 private Region region;
51
52 private byte[] cfName = Bytes.toBytes("a");
53 private byte[] cqName = Bytes.toBytes("b");
54
55 @Before
56 public void setUp() throws Exception {
57 TableName tableName = TableName.valueOf(getClass().getSimpleName());
58 HTableDescriptor htd = new HTableDescriptor(tableName);
59 htd.addFamily(new HColumnDescriptor(cfName).setDataBlockEncoding(DataBlockEncoding.FAST_DIFF));
60 HRegionInfo info = new HRegionInfo(tableName, null, null, false);
61 Path path = testUtil.getDataTestDir(getClass().getSimpleName());
62 region = HBaseTestingUtility.createRegionAndWAL(info, path, path, testUtil.getConfiguration(), htd);
63 }
64
65 @After
66 public void tearDown() throws Exception {
67 HBaseTestingUtility.closeRegionAndWAL(region);
68 testUtil.cleanupTestDir();
69 }
70
71 @Test
72 public void testReverseScanWithoutPadding() throws Exception {
73 byte[] row1 = Bytes.toBytes("a");
74 byte[] row2 = Bytes.toBytes("ab");
75 byte[] row3 = Bytes.toBytes("b");
76
77 Put put1 = new Put(row1);
78 put1.addColumn(cfName, cqName, HConstants.EMPTY_BYTE_ARRAY);
79 Put put2 = new Put(row2);
80 put2.addColumn(cfName, cqName, HConstants.EMPTY_BYTE_ARRAY);
81 Put put3 = new Put(row3);
82 put3.addColumn(cfName, cqName, HConstants.EMPTY_BYTE_ARRAY);
83
84 region.put(put1);
85 region.put(put2);
86 region.put(put3);
87 region.flush(true);
88 Scan scan = new Scan();
89 scan.setCacheBlocks(false);
90 scan.setReversed(true);
91 scan.setFilter(new FirstKeyOnlyFilter());
92 scan.addFamily(cfName);
93 RegionScanner scanner = region.getScanner(scan);
94 List<Cell> res = new ArrayList<Cell>();
95 int count = 1;
96 while (scanner.next(res)) {
97 count++;
98 }
99 assertEquals(Bytes.toString(res.get(0).getRowArray(), res.get(0).getRowOffset(), res.get(0)
100 .getRowLength()), "b");
101 assertEquals(Bytes.toString(res.get(1).getRowArray(), res.get(1).getRowOffset(), res.get(1)
102 .getRowLength()), "ab");
103 assertEquals(Bytes.toString(res.get(2).getRowArray(), res.get(2).getRowOffset(), res.get(2)
104 .getRowLength()), "a");
105 assertEquals(3, count);
106 }
107
108 @Test
109 public void testReverseScanWithPadding() throws Exception {
110 byte[] terminator = new byte[] { -1 };
111 byte[] row1 = Bytes.add(invert(Bytes.toBytes("a")), terminator);
112 byte[] row2 = Bytes.add(invert(Bytes.toBytes("ab")), terminator);
113 byte[] row3 = Bytes.add(invert(Bytes.toBytes("b")), terminator);
114
115 Put put1 = new Put(row1);
116 put1.addColumn(cfName, cqName, HConstants.EMPTY_BYTE_ARRAY);
117 Put put2 = new Put(row2);
118 put2.addColumn(cfName, cqName, HConstants.EMPTY_BYTE_ARRAY);
119 Put put3 = new Put(row3);
120 put3.addColumn(cfName, cqName, HConstants.EMPTY_BYTE_ARRAY);
121
122 region.put(put1);
123 region.put(put2);
124 region.put(put3);
125 region.flush(true);
126 Scan scan = new Scan();
127 scan.setCacheBlocks(false);
128 scan.setReversed(true);
129 scan.setFilter(new FirstKeyOnlyFilter());
130 scan.addFamily(cfName);
131 RegionScanner scanner = region.getScanner(scan);
132 List<Cell> res = new ArrayList<Cell>();
133 int count = 1;
134 while (scanner.next(res)) {
135 count++;
136 }
137 assertEquals(3, count);
138 }
139
140 private byte[] invert(byte[] bytes) {
141 byte[] newBytes = Arrays.copyOf(bytes, bytes.length);
142 for (int i = 0; i < newBytes.length; i++) {
143 newBytes[i] = (byte) (newBytes[i] ^ 0xFF);
144 }
145 return newBytes;
146 }
147 }