1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 package org.apache.hadoop.hbase.codec.prefixtree.decode.column;
20 
21 import org.apache.hadoop.hbase.classification.InterfaceAudience;
22 import org.apache.hadoop.hbase.codec.prefixtree.PrefixTreeBlockMeta;
23 import org.apache.hadoop.hbase.codec.prefixtree.encode.other.ColumnNodeType;
24 
25 /**
26  * Position one of these appropriately in the data block and you can call its methods to retrieve
27  * the family or qualifier at the current position.
28  */
29 @InterfaceAudience.Private
30 public class ColumnReader {
31 
32   /****************** fields *************************/
33 
34   protected PrefixTreeBlockMeta blockMeta;
35 
36   protected byte[] columnBuffer;
37   protected int columnOffset;
38   protected int columnLength;
39   protected ColumnNodeType nodeType;
40 
41   protected ColumnNodeReader columnNodeReader;
42 
43 
44   /******************** construct *******************/
45 
ColumnReader(byte[] columnBuffer, ColumnNodeType nodeType)46   public ColumnReader(byte[] columnBuffer, ColumnNodeType nodeType) {
47     this.columnBuffer = columnBuffer;
48     this.nodeType = nodeType;
49     this.columnNodeReader = new ColumnNodeReader(columnBuffer, nodeType);
50   }
51 
initOnBlock(PrefixTreeBlockMeta blockMeta, byte[] block)52   public void initOnBlock(PrefixTreeBlockMeta blockMeta, byte[] block) {
53     this.blockMeta = blockMeta;
54     clearColumnBuffer();
55     columnNodeReader.initOnBlock(blockMeta, block);
56   }
57 
58 
59   /********************* methods *******************/
60 
populateBuffer(int offsetIntoColumnData)61   public ColumnReader populateBuffer(int offsetIntoColumnData) {
62     clearColumnBuffer();
63     int nextRelativeOffset = offsetIntoColumnData;
64     while (true) {
65       int absoluteOffset = 0;
66       if (nodeType == ColumnNodeType.FAMILY) {
67         absoluteOffset = blockMeta.getAbsoluteFamilyOffset() + nextRelativeOffset;
68       } else if (nodeType == ColumnNodeType.QUALIFIER) {
69         absoluteOffset = blockMeta.getAbsoluteQualifierOffset() + nextRelativeOffset;
70       } else {
71         absoluteOffset = blockMeta.getAbsoluteTagsOffset() + nextRelativeOffset;
72       }
73       columnNodeReader.positionAt(absoluteOffset);
74       columnOffset -= columnNodeReader.getTokenLength();
75       columnLength += columnNodeReader.getTokenLength();
76       columnNodeReader.prependTokenToBuffer(columnOffset);
77       if (columnNodeReader.isRoot()) {
78         return this;
79       }
80       nextRelativeOffset = columnNodeReader.getParentStartPosition();
81     }
82   }
83 
copyBufferToNewArray()84   public byte[] copyBufferToNewArray() {// for testing
85     byte[] out = new byte[columnLength];
86     System.arraycopy(columnBuffer, columnOffset, out, 0, out.length);
87     return out;
88   }
89 
getColumnLength()90   public int getColumnLength() {
91     return columnLength;
92   }
93 
clearColumnBuffer()94   public void clearColumnBuffer() {
95     columnOffset = columnBuffer.length;
96     columnLength = 0;
97   }
98 
99 
100   /****************************** get/set *************************************/
101 
getColumnOffset()102   public int getColumnOffset() {
103     return columnOffset;
104   }
105 
106 }
107 
108