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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 package org
.apache
.hadoop
.hbase
.io
;
21 import java
.io
.DataInput
;
22 import java
.io
.DataOutput
;
23 import java
.io
.IOException
;
24 import java
.util
.Arrays
;
25 import java
.util
.List
;
27 import org
.apache
.hadoop
.io
.BytesWritable
;
28 import org
.apache
.hadoop
.io
.WritableComparable
;
29 import org
.apache
.hadoop
.io
.WritableComparator
;
30 import org
.apache
.yetus
.audience
.InterfaceAudience
;
33 * A byte sequence that is usable as a key or value. Based on
34 * {@link org.apache.hadoop.io.BytesWritable} only this class is NOT resizable
35 * and DOES NOT distinguish between the size of the sequence and the current
36 * capacity as {@link org.apache.hadoop.io.BytesWritable} does. Hence its
37 * comparatively 'immutable'. When creating a new instance of this class,
38 * the underlying byte [] is not copied, just referenced. The backing
39 * buffer is accessed when we go to serialize.
41 @InterfaceAudience.Public
42 @edu.umd
.cs
.findbugs
.annotations
.SuppressWarnings(
43 value
="EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS",
44 justification
="It has been like this forever")
45 public class ImmutableBytesWritable
46 implements WritableComparable
<ImmutableBytesWritable
> {
52 * Create a zero-size sequence.
54 public ImmutableBytesWritable() {
59 * Create a ImmutableBytesWritable using the byte array as the initial value.
60 * @param bytes This array becomes the backing storage for the object.
62 public ImmutableBytesWritable(byte[] bytes
) {
63 this(bytes
, 0, bytes
.length
);
67 * Set the new ImmutableBytesWritable to the contents of the passed
69 * @param ibw the value to set this ImmutableBytesWritable to.
71 public ImmutableBytesWritable(final ImmutableBytesWritable ibw
) {
72 this(ibw
.get(), ibw
.getOffset(), ibw
.getLength());
76 * Set the value to a given byte range
77 * @param bytes the new byte range to set to
78 * @param offset the offset in newData to start at
79 * @param length the number of bytes in the range
81 public ImmutableBytesWritable(final byte[] bytes
, final int offset
,
89 * Get the data from the BytesWritable.
90 * @return The data is only valid between offset and offset+length.
92 public byte [] get() {
93 if (this.bytes
== null) {
94 throw new IllegalStateException("Uninitialiized. Null constructor " +
95 "called w/o accompaying readFields invocation");
101 * @param b Use passed bytes as backing array for this instance.
103 public void set(final byte [] b
) {
108 * @param b Use passed bytes as backing array for this instance.
112 public void set(final byte [] b
, final int offset
, final int length
) {
114 this.offset
= offset
;
115 this.length
= length
;
119 * @return the number of valid bytes in the buffer
121 public int getLength() {
122 if (this.bytes
== null) {
123 throw new IllegalStateException("Uninitialiized. Null constructor " +
124 "called w/o accompaying readFields invocation");
132 public int getOffset(){
137 public void readFields(final DataInput in
) throws IOException
{
138 this.length
= in
.readInt();
139 this.bytes
= new byte[this.length
];
140 in
.readFully(this.bytes
, 0, this.length
);
145 public void write(final DataOutput out
) throws IOException
{
146 out
.writeInt(this.length
);
147 out
.write(this.bytes
, this.offset
, this.length
);
150 // Below methods copied from BytesWritable
152 public int hashCode() {
154 for (int i
= offset
; i
< offset
+ length
; i
++)
155 hash
= (31 * hash
) + (int)bytes
[i
];
160 * Define the sort order of the BytesWritable.
161 * @param that The other bytes writable
162 * @return Positive if left is bigger than right, 0 if they are equal, and
163 * negative if left is smaller than right.
166 public int compareTo(ImmutableBytesWritable that
) {
167 return WritableComparator
.compareBytes(
168 this.bytes
, this.offset
, this.length
,
169 that
.bytes
, that
.offset
, that
.length
);
173 * Compares the bytes in this object to the specified byte array
175 * @return Positive if left is bigger than right, 0 if they are equal, and
176 * negative if left is smaller than right.
178 public int compareTo(final byte [] that
) {
179 return WritableComparator
.compareBytes(
180 this.bytes
, this.offset
, this.length
,
181 that
, 0, that
.length
);
185 * @see java.lang.Object#equals(java.lang.Object)
188 public boolean equals(Object right_obj
) {
189 if (right_obj
instanceof byte []) {
190 return compareTo((byte [])right_obj
) == 0;
192 if (right_obj
instanceof ImmutableBytesWritable
) {
193 return compareTo((ImmutableBytesWritable
)right_obj
) == 0;
199 * @see java.lang.Object#toString()
202 public String
toString() {
203 StringBuilder sb
= new StringBuilder(3*this.length
);
204 final int endIdx
= this.offset
+ this.length
;
205 for (int idx
= this.offset
; idx
< endIdx
; idx
++) {
207 String num
= Integer
.toHexString(0xff & this.bytes
[idx
]);
208 // if it is only one digit, add a leading 0.
209 if (num
.length() < 2) {
214 return sb
.length() > 0 ? sb
.substring(1) : "";
217 /** A Comparator optimized for ImmutableBytesWritable.
219 @InterfaceAudience.Public
220 public static class Comparator
extends WritableComparator
{
221 private BytesWritable
.Comparator comparator
=
222 new BytesWritable
.Comparator();
225 public Comparator() {
226 super(ImmutableBytesWritable
.class);
230 * @see org.apache.hadoop.io.WritableComparator#compare(byte[], int, int, byte[], int, int)
233 public int compare(byte[] b1
, int s1
, int l1
, byte[] b2
, int s2
, int l2
) {
234 return comparator
.compare(b1
, s1
, l1
, b2
, s2
, l2
);
238 static { // register this comparator
239 WritableComparator
.define(ImmutableBytesWritable
.class, new Comparator());
243 * @param array List of byte [].
244 * @return Array of byte [].
246 public static byte [][] toArray(final List
<byte []> array
) {
247 // List#toArray doesn't work on lists of byte [].
248 byte[][] results
= new byte[array
.size()][];
249 for (int i
= 0; i
< array
.size(); i
++) {
250 results
[i
] = array
.get(i
);
256 * Returns a copy of the bytes referred to by this writable
258 public byte[] copyBytes() {
259 return Arrays
.copyOfRange(bytes
, offset
, offset
+length
);