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  import org.apache.hadoop.hbase.classification.InterfaceAudience;
21  import org.apache.hadoop.hbase.classification.InterfaceStability;
22  
23  /**
24   * Extends the basic {@link SimpleByteRange} implementation with position
25   * support. {@code position} is considered transient, not fundamental to the
26   * definition of the range, and does not participate in
27   * {@link #compareTo(ByteRange)}, {@link #hashCode()}, or
28   * {@link #equals(Object)}. {@code Position} is retained by copy operations.
29   */
30  @InterfaceAudience.Private
31  @InterfaceStability.Evolving
32  public abstract class AbstractPositionedByteRange extends AbstractByteRange implements
33      PositionedByteRange {
34    /**
35     * The current index into the range. Like {@link java.nio.ByteBuffer} position, it
36     * points to the next value that will be read/written in the array. It
37     * provides the appearance of being 0-indexed, even though its value is
38     * calculated according to offset.
39     * <p>
40     * Position is considered transient and does not participate in
41     * {@link #equals(Object)} or {@link #hashCode()} comparisons.
42     * </p>
43     */
44    protected int position = 0;
45  
46    protected int limit = 0;
47  
48    @Override
49    public PositionedByteRange set(int capacity) {
50      this.position = 0;
51      super.set(capacity);
52      this.limit = capacity;
53      return this;
54    }
55  
56    @Override
57    public PositionedByteRange set(byte[] bytes) {
58      this.position = 0;
59      super.set(bytes);
60      this.limit = bytes.length;
61      return this;
62    }
63  
64    @Override
65    public PositionedByteRange set(byte[] bytes, int offset, int length) {
66      this.position = 0;
67      super.set(bytes, offset, length);
68      limit = length;
69      return this;
70    }
71  
72    /**
73     * Update the beginning of this range. {@code offset + length} may not be
74     * greater than {@code bytes.length}. Resets {@code position} to 0.
75     *
76     * @param offset
77     *          the new start of this range.
78     * @return this.
79     */
80    @Override
81    public PositionedByteRange setOffset(int offset) {
82      this.position = 0;
83      super.setOffset(offset);
84      return this;
85    }
86  
87    /**
88     * Update the length of this range. {@code offset + length} should not be
89     * greater than {@code bytes.length}. If {@code position} is greater than the
90     * new {@code length}, sets {@code position} to {@code length}.
91     *
92     * @param length
93     *          The new length of this range.
94     * @return this.
95     */
96    @Override
97    public PositionedByteRange setLength(int length) {
98      this.position = Math.min(position, length);
99      super.setLength(length);
100     return this;
101   }
102 
103   @Override
104   public int getPosition() {
105     return position;
106   }
107 
108   @Override
109   public PositionedByteRange setPosition(int position) {
110     this.position = position;
111     return this;
112   }
113 
114   @Override
115   public int getRemaining() {
116     return length - position;
117   }
118 
119   @Override
120   public byte peek() {
121     return bytes[offset + position];
122   }
123 
124   @Override
125   public byte get() {
126     return get(position++);
127   }
128 
129   @Override
130   public PositionedByteRange get(byte[] dst) {
131     if (0 == dst.length) {
132       return this;
133     }
134 
135     return this.get(dst, 0, dst.length); // be clear we're calling self, not super
136   }
137 
138   @Override
139   public PositionedByteRange get(byte[] dst, int offset, int length) {
140     if (0 == length) {
141       return this;
142     }
143 
144     super.get(this.position, dst, offset, length);
145     this.position += length;
146     return this;
147   }
148 
149   // java boilerplate
150 
151   @Override
152   public PositionedByteRange get(int index, byte[] dst) {
153     super.get(index, dst);
154     return this;
155   }
156 
157   @Override
158   public PositionedByteRange get(int index, byte[] dst, int offset, int length) {
159     super.get(index, dst, offset, length);
160     return this;
161   }
162 
163   @Override
164   public short getShort() {
165     short s = getShort(position);
166     position += Bytes.SIZEOF_SHORT;
167     return s;
168   }
169 
170   @Override
171   public int getInt() {
172     int i = getInt(position);
173     position += Bytes.SIZEOF_INT;
174     return i;
175   }
176 
177   @Override
178   public long getLong() {
179     long l = getLong(position);
180     position += Bytes.SIZEOF_LONG;
181     return l;
182   }
183 
184   @Override
185   public long getVLong() {
186     long p = getVLong(position);
187     position += getVLongSize(p);
188     return p;
189   }
190 
191   @Override
192   public PositionedByteRange setLimit(int limit) {
193     this.limit = limit;
194     return this;
195   }
196 
197   @Override
198   public int getLimit() {
199     return this.limit;
200   }
201 }