View Javadoc

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;
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.scanner.ReversibleCellScanner;
24  
25  /**
26   * Methods for going backwards through a PrefixTree block.  This class is split out on its own to
27   * simplify the Scanner superclass and Searcher subclass.
28   */
29  @InterfaceAudience.Private
30  public class PrefixTreeArrayReversibleScanner extends PrefixTreeArrayScanner implements
31      ReversibleCellScanner {
32  
33    /***************** construct ******************************/
34  
35    public PrefixTreeArrayReversibleScanner(PrefixTreeBlockMeta blockMeta, int rowTreeDepth,
36        int rowBufferLength, int qualifierBufferLength, int tagsBufferLength) {
37      super(blockMeta, rowTreeDepth, rowBufferLength, qualifierBufferLength, tagsBufferLength);
38    }
39  
40  
41    /***************** Object methods ***************************/
42  
43    @Override
44    public boolean equals(Object obj) {
45      //trivial override to confirm intent (findbugs)
46      return super.equals(obj);
47    }
48  
49  
50    /***************** methods **********************************/
51  
52    @Override
53    public boolean previous() {
54      if (afterLast) {
55        afterLast = false;
56        positionAtLastCell();
57        return true;
58      }
59      if (beforeFirst) {
60        return false;
61      }
62      if (isFirstCellInRow()) {
63        previousRowInternal();
64        if (beforeFirst) {
65          return false;
66        }
67        populateLastNonRowFields();
68        return true;
69      }
70      populatePreviousNonRowFields();
71      return true;
72    }
73  
74    @Override
75    public boolean previousRow(boolean endOfRow) {
76      previousRowInternal();
77      if(beforeFirst){
78        return false;
79      }
80      if(endOfRow){
81        populateLastNonRowFields();
82      }else{
83        populateFirstNonRowFields();
84      }
85      return true;
86    }
87  
88    private boolean previousRowInternal() {
89      if (beforeFirst) {
90        return false;
91      }
92      if (afterLast) {
93        positionAtLastRow();
94        return true;
95      }
96      if (currentRowNode.hasOccurrences()) {
97        discardCurrentRowNode(false);
98        if(currentRowNode==null){
99          return false;
100       }
101     }
102     while (!beforeFirst) {
103       if (isDirectlyAfterNub()) {//we are about to back up to the nub
104         currentRowNode.resetFanIndex();//sets it to -1, which is before the first leaf
105         nubCellsRemain = true;//this positions us on the nub
106         return true;
107       }
108       if (currentRowNode.hasPreviousFanNodes()) {
109         followPreviousFan();
110         descendToLastRowFromCurrentPosition();
111       } else {// keep going up the stack until we find previous fan positions
112         discardCurrentRowNode(false);
113         if(currentRowNode==null){
114           return false;
115         }
116       }
117       if (currentRowNode.hasOccurrences()) {// escape clause
118         currentRowNode.resetFanIndex();
119         return true;// found some values
120       }
121     }
122     return false;// went past the beginning
123   }
124   
125   protected boolean isDirectlyAfterNub() {
126     return currentRowNode.isNub() && currentRowNode.getFanIndex()==0;
127   }
128 
129   protected void positionAtLastRow() {
130     reInitFirstNode();
131     descendToLastRowFromCurrentPosition();
132   }
133 
134   protected void descendToLastRowFromCurrentPosition() {
135     while (currentRowNode.hasChildren()) {
136       followLastFan();
137     }
138   }
139 
140   protected void positionAtLastCell() {
141     positionAtLastRow();
142     populateLastNonRowFields();
143   }
144 
145 }