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  package org.apache.hadoop.hbase.util;
19  
20  
21  import org.apache.hadoop.hbase.classification.InterfaceAudience;
22  import org.apache.hadoop.hbase.classification.InterfaceStability;
23  
24  import com.google.common.annotations.VisibleForTesting;
25  
26  /**
27   * Extends the basic {@link SimpleByteRange} implementation with position
28   * support. {@code position} is considered transient, not fundamental to the
29   * definition of the range, and does not participate in
30   * {@link #compareTo(ByteRange)}, {@link #hashCode()}, or
31   * {@link #equals(Object)}. {@code Position} is retained by copy operations.
32   */
33  @InterfaceAudience.Private
34  @InterfaceStability.Evolving
35  public abstract class AbstractPositionedByteRange extends AbstractByteRange implements
36      PositionedByteRange {
37    /**
38     * The current index into the range. Like {@link java.nio.ByteBuffer} position, it
39     * points to the next value that will be read/written in the array. It
40     * provides the appearance of being 0-indexed, even though its value is
41     * calculated according to offset.
42     * <p>
43     * Position is considered transient and does not participate in
44     * {@link #equals(Object)} or {@link #hashCode()} comparisons.
45     * </p>
46     */
47    protected int position = 0;
48  
49    protected int limit = 0;
50  
51    @Override
52    public abstract PositionedByteRange unset();
53  
54    @Override
55    public PositionedByteRange set(int capacity) {
56      this.position = 0;
57      super.set(capacity);
58      this.limit = capacity;
59      return this;
60    }
61  
62    @Override
63    public PositionedByteRange set(byte[] bytes) {
64      this.position = 0;
65      super.set(bytes);
66      this.limit = bytes.length;
67      return this;
68    }
69  
70    @Override
71    public PositionedByteRange set(byte[] bytes, int offset, int length) {
72      this.position = 0;
73      super.set(bytes, offset, length);
74      limit = length;
75      return this;
76    }
77  
78    /**
79     * Update the beginning of this range. {@code offset + length} may not be
80     * greater than {@code bytes.length}. Resets {@code position} to 0.
81     *
82     * @param offset
83     *          the new start of this range.
84     * @return this.
85     */
86    @Override
87    public PositionedByteRange setOffset(int offset) {
88      this.position = 0;
89      super.setOffset(offset);
90      return this;
91    }
92  
93    /**
94     * Update the length of this range. {@code offset + length} should not be
95     * greater than {@code bytes.length}. If {@code position} is greater than the
96     * new {@code length}, sets {@code position} to {@code length}.
97     *
98     * @param length
99     *          The new length of this range.
100    * @return this.
101    */
102   @Override
103   public PositionedByteRange setLength(int length) {
104     this.position = Math.min(position, length);
105     super.setLength(length);
106     return this;
107   }
108 
109   @Override
110   public int getPosition() {
111     return position;
112   }
113 
114   @Override
115   public PositionedByteRange setPosition(int position) {
116     this.position = position;
117     return this;
118   }
119 
120   @Override
121   public int getRemaining() {
122     return length - position;
123   }
124 
125   @Override
126   public byte peek() {
127     return bytes[offset + position];
128   }
129 
130   @Override
131   public byte get() {
132     return get(position++);
133   }
134 
135   @Override
136   public PositionedByteRange get(byte[] dst) {
137     if (0 == dst.length)
138       return this;
139     return this.get(dst, 0, dst.length); // be clear we're calling self, not
140                                          // super
141   }
142 
143   @Override
144   public PositionedByteRange get(byte[] dst, int offset, int length) {
145     if (0 == length)
146       return this;
147     super.get(this.position, dst, offset, length);
148     this.position += length;
149     return this;
150   }
151 
152   @Override
153   public abstract PositionedByteRange put(byte val);
154 
155   @Override
156   public abstract PositionedByteRange put(byte[] val);
157 
158   @Override
159   public abstract PositionedByteRange put(byte[] val, int offset, int length);
160 
161   @Override
162   public abstract PositionedByteRange putInt(int index, int val);
163 
164   @Override
165   public abstract PositionedByteRange putLong(int index, long val);
166 
167   @Override
168   public abstract PositionedByteRange putShort(int index, short val);
169 
170   @Override
171   public abstract PositionedByteRange putInt(int val);
172 
173   @Override
174   public abstract PositionedByteRange putLong(long val);
175 
176   @Override
177   public abstract PositionedByteRange putShort(short val);
178 
179   @Override
180   public abstract int putVLong(int index, long val);
181 
182   @Override
183   public abstract int putVLong(long val);
184   /**
185    * Similar to {@link java.nio.ByteBuffer#flip()}. Sets length to position, position to
186    * offset.
187    */
188   @VisibleForTesting
189   PositionedByteRange flip() {
190     clearHashCache();
191     length = position;
192     position = offset;
193     return this;
194   }
195 
196   /**
197    * Similar to {@link java.nio.ByteBuffer#clear()}. Sets position to 0, length to
198    * capacity.
199    */
200   @VisibleForTesting
201   PositionedByteRange clear() {
202     clearHashCache();
203     position = 0;
204     length = bytes.length - offset;
205     return this;
206   }
207 
208   // java boilerplate
209 
210   @Override
211   public PositionedByteRange get(int index, byte[] dst) {
212     super.get(index, dst);
213     return this;
214   }
215 
216   @Override
217   public PositionedByteRange get(int index, byte[] dst, int offset, int length) {
218     super.get(index, dst, offset, length);
219     return this;
220   }
221 
222   @Override
223   public short getShort() {
224     short s = getShort(position);
225     position += Bytes.SIZEOF_SHORT;
226     return s;
227   }
228 
229   @Override
230   public int getInt() {
231     int i = getInt(position);
232     position += Bytes.SIZEOF_INT;
233     return i;
234   }
235 
236   @Override
237   public long getLong() {
238     long l = getLong(position);
239     position += Bytes.SIZEOF_LONG;
240     return l;
241   }
242 
243   @Override
244   public long getVLong() {
245     long p = getVLong(position);
246     position += getVLongSize(p);
247     return p;
248   }
249 
250   @Override
251   public abstract PositionedByteRange put(int index, byte val);
252 
253   @Override
254   public abstract PositionedByteRange put(int index, byte[] val);
255 
256   @Override
257   public abstract PositionedByteRange put(int index, byte[] val, int offset, int length);
258 
259   @Override
260   public abstract PositionedByteRange deepCopy();
261 
262   @Override
263   public abstract PositionedByteRange shallowCopy();
264 
265   @Override
266   public abstract PositionedByteRange shallowCopySubRange(int innerOffset, int copyLength);
267 
268   @Override
269   public PositionedByteRange setLimit(int limit) {
270     this.limit = limit;
271     return this;
272   }
273 
274   @Override
275   public int getLimit() {
276     return this.limit;
277   }
278 }