1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.codec.prefixtree.row;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.nio.ByteBuffer;
25 import java.util.Collection;
26 import java.util.List;
27
28 import org.apache.hadoop.hbase.Cell;
29 import org.apache.hadoop.hbase.KeyValue;
30 import org.apache.hadoop.hbase.KeyValueUtil;
31 import org.apache.hadoop.hbase.codec.prefixtree.PrefixTreeBlockMeta;
32 import org.apache.hadoop.hbase.codec.prefixtree.decode.PrefixTreeArraySearcher;
33 import org.apache.hadoop.hbase.codec.prefixtree.encode.PrefixTreeEncoder;
34 import org.apache.hadoop.hbase.util.Bytes;
35 import org.junit.Assert;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.junit.runners.Parameterized;
40 import org.junit.runners.Parameterized.Parameters;
41
42 import com.google.common.collect.Lists;
43
44 @RunWith(Parameterized.class)
45 public class TestRowEncoder {
46
47 protected static int BLOCK_START = 7;
48
49 @Parameters
50 public static Collection<Object[]> parameters() {
51 List<Object[]> parameters = Lists.newArrayList();
52 for (TestRowData testRows : TestRowData.InMemory.getAll()) {
53 parameters.add(new Object[] { testRows });
54 }
55 return parameters;
56 }
57
58 protected TestRowData rows;
59 protected List<KeyValue> inputKvs;
60 protected boolean includeMemstoreTS = true;
61 protected ByteArrayOutputStream os;
62 protected PrefixTreeEncoder encoder;
63 protected int totalBytes;
64 protected PrefixTreeBlockMeta blockMetaWriter;
65 protected byte[] outputBytes;
66 protected ByteBuffer buffer;
67 protected ByteArrayInputStream is;
68 protected PrefixTreeBlockMeta blockMetaReader;
69 protected byte[] inputBytes;
70 protected PrefixTreeArraySearcher searcher;
71
72 public TestRowEncoder(TestRowData testRows) {
73 this.rows = testRows;
74 }
75
76 @Before
77 public void compile() throws IOException {
78 os = new ByteArrayOutputStream(1 << 20);
79 encoder = new PrefixTreeEncoder(os, includeMemstoreTS);
80
81 inputKvs = rows.getInputs();
82 for (KeyValue kv : inputKvs) {
83 encoder.write(kv);
84 }
85 encoder.flush();
86 totalBytes = encoder.getTotalBytes();
87 blockMetaWriter = encoder.getBlockMeta();
88 outputBytes = os.toByteArray();
89
90
91 buffer = ByteBuffer.wrap(outputBytes);
92 blockMetaReader = new PrefixTreeBlockMeta(buffer);
93
94 searcher = new PrefixTreeArraySearcher(blockMetaReader, blockMetaReader.getRowTreeDepth(),
95 blockMetaReader.getMaxRowLength(), blockMetaReader.getMaxQualifierLength());
96 searcher.initOnBlock(blockMetaReader, outputBytes, includeMemstoreTS);
97 }
98
99 @Test
100 public void testEncoderOutput() throws IOException {
101 Assert.assertEquals(totalBytes, outputBytes.length);
102 Assert.assertEquals(blockMetaWriter, blockMetaReader);
103 }
104
105 @Test
106 public void testForwardScanner() {
107 int counter = -1;
108 while (searcher.advance()) {
109 ++counter;
110 KeyValue inputKv = rows.getInputs().get(counter);
111 KeyValue outputKv = KeyValueUtil.copyToNewKeyValue(searcher.current());
112 assertKeyAndValueEqual(inputKv, outputKv);
113 }
114
115 Assert.assertEquals(rows.getInputs().size(), counter + 1);
116 }
117
118
119
120
121
122 @Test
123 public void testReverseScanner() {
124 searcher.positionAfterLastCell();
125 int counter = -1;
126 while (searcher.previous()) {
127 ++counter;
128 int oppositeIndex = rows.getInputs().size() - counter - 1;
129 KeyValue inputKv = rows.getInputs().get(oppositeIndex);
130 KeyValue outputKv = KeyValueUtil.copyToNewKeyValue(searcher.current());
131 assertKeyAndValueEqual(inputKv, outputKv);
132 }
133 Assert.assertEquals(rows.getInputs().size(), counter + 1);
134 }
135
136
137
138
139
140
141 @Test
142 public void testReverseScannerWithJitter() {
143 searcher.positionAfterLastCell();
144 int counter = -1;
145 while (true) {
146 boolean foundCell = searcher.previous();
147 if (!foundCell) {
148 break;
149 }
150 ++counter;
151
152
153 if (!searcher.isAfterLast()) {
154 searcher.advance();
155 searcher.previous();
156 }
157
158 int oppositeIndex = rows.getInputs().size() - counter - 1;
159 KeyValue inputKv = rows.getInputs().get(oppositeIndex);
160 KeyValue outputKv = KeyValueUtil.copyToNewKeyValue(searcher.current());
161 assertKeyAndValueEqual(inputKv, outputKv);
162 }
163 Assert.assertEquals(rows.getInputs().size(), counter + 1);
164 }
165
166 @Test
167 public void testIndividualBlockMetaAssertions() {
168 rows.individualBlockMetaAssertions(blockMetaReader);
169 }
170
171
172
173
174 protected void assertKeyAndValueEqual(Cell expected, Cell actual) {
175
176 Assert.assertEquals(expected, actual);
177 if (includeMemstoreTS) {
178 Assert.assertEquals(expected.getMvccVersion(), actual.getMvccVersion());
179 }
180
181 Assert.assertTrue(Bytes.equals(expected.getValueArray(), expected.getValueOffset(),
182 expected.getValueLength(), actual.getValueArray(), actual.getValueOffset(),
183 actual.getValueLength()));
184 }
185
186 }