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 static com.google.common.base.Preconditions.checkArgument;
21  import static com.google.common.base.Preconditions.checkNotNull;
22  import static com.google.common.base.Preconditions.checkPositionIndex;
23  
24  import java.io.DataInput;
25  import java.io.DataOutput;
26  import java.io.IOException;
27  import java.lang.reflect.Field;
28  import java.math.BigDecimal;
29  import java.math.BigInteger;
30  import java.nio.ByteBuffer;
31  import java.nio.ByteOrder;
32  import java.security.AccessController;
33  import java.security.PrivilegedAction;
34  import java.security.SecureRandom;
35  import java.util.Arrays;
36  import java.util.Collection;
37  import java.util.Comparator;
38  import java.util.Iterator;
39  import java.util.List;
40  
41  import org.apache.commons.logging.Log;
42  import org.apache.commons.logging.LogFactory;
43  import org.apache.hadoop.classification.InterfaceAudience;
44  import org.apache.hadoop.classification.InterfaceStability;
45  import org.apache.hadoop.hbase.HConstants;
46  import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
47  import org.apache.hadoop.io.RawComparator;
48  import org.apache.hadoop.io.WritableComparator;
49  import org.apache.hadoop.io.WritableUtils;
50  
51  import sun.misc.Unsafe;
52  
53  import com.google.common.annotations.VisibleForTesting;
54  import com.google.common.collect.Lists;
55  
56  /**
57   * Utility class that handles byte arrays, conversions to/from other types,
58   * comparisons, hash code generation, manufacturing keys for HashMaps or
59   * HashSets, etc.
60   */
61  @InterfaceAudience.Public
62  @InterfaceStability.Stable
63  public class Bytes {
64  
65    private static final Log LOG = LogFactory.getLog(Bytes.class);
66  
67    /**
68     * Size of boolean in bytes
69     */
70    public static final int SIZEOF_BOOLEAN = Byte.SIZE / Byte.SIZE;
71  
72    /**
73     * Size of byte in bytes
74     */
75    public static final int SIZEOF_BYTE = SIZEOF_BOOLEAN;
76  
77    /**
78     * Size of char in bytes
79     */
80    public static final int SIZEOF_CHAR = Character.SIZE / Byte.SIZE;
81  
82    /**
83     * Size of double in bytes
84     */
85    public static final int SIZEOF_DOUBLE = Double.SIZE / Byte.SIZE;
86  
87    /**
88     * Size of float in bytes
89     */
90    public static final int SIZEOF_FLOAT = Float.SIZE / Byte.SIZE;
91  
92    /**
93     * Size of int in bytes
94     */
95    public static final int SIZEOF_INT = Integer.SIZE / Byte.SIZE;
96  
97    /**
98     * Size of long in bytes
99     */
100   public static final int SIZEOF_LONG = Long.SIZE / Byte.SIZE;
101 
102   /**
103    * Size of short in bytes
104    */
105   public static final int SIZEOF_SHORT = Short.SIZE / Byte.SIZE;
106 
107 
108   /**
109    * Estimate of size cost to pay beyond payload in jvm for instance of byte [].
110    * Estimate based on study of jhat and jprofiler numbers.
111    */
112   // JHat says BU is 56 bytes.
113   // SizeOf which uses java.lang.instrument says 24 bytes. (3 longs?)
114   public static final int ESTIMATED_HEAP_TAX = 16;
115 
116   /**
117    * Byte array comparator class.
118    */
119   public static class ByteArrayComparator implements RawComparator<byte []> {
120     /**
121      * Constructor
122      */
123     public ByteArrayComparator() {
124       super();
125     }
126     @Override
127     public int compare(byte [] left, byte [] right) {
128       return compareTo(left, right);
129     }
130     @Override
131     public int compare(byte [] b1, int s1, int l1, byte [] b2, int s2, int l2) {
132       return LexicographicalComparerHolder.BEST_COMPARER.
133         compareTo(b1, s1, l1, b2, s2, l2);
134     }
135   }
136 
137   /**
138    * A {@link ByteArrayComparator} that treats the empty array as the largest value.
139    * This is useful for comparing row end keys for regions.
140    */
141   // TODO: unfortunately, HBase uses byte[0] as both start and end keys for region
142   // boundaries. Thus semantically, we should treat empty byte array as the smallest value
143   // while comparing row keys, start keys etc; but as the largest value for comparing
144   // region boundaries for endKeys.
145   public static class RowEndKeyComparator extends ByteArrayComparator {
146     @Override
147     public int compare(byte[] left, byte[] right) {
148       return compare(left, 0, left.length, right, 0, right.length);
149     }
150     @Override
151     public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
152       if (b1 == b2 && s1 == s2 && l1 == l2) {
153         return 0;
154       }
155       if (l1 == 0) {
156         return l2; //0 or positive
157       }
158       if (l2 == 0) {
159         return -1;
160       }
161       return super.compare(b1, s1, l1, b2, s2, l2);
162     }
163   }
164 
165   /**
166    * Pass this to TreeMaps where byte [] are keys.
167    */
168   public static Comparator<byte []> BYTES_COMPARATOR =
169     new ByteArrayComparator();
170 
171   /**
172    * Use comparing byte arrays, byte-by-byte
173    */
174   public static RawComparator<byte []> BYTES_RAWCOMPARATOR =
175     new ByteArrayComparator();
176 
177   /**
178    * Read byte-array written with a WritableableUtils.vint prefix.
179    * @param in Input to read from.
180    * @return byte array read off <code>in</code>
181    * @throws IOException e
182    */
183   public static byte [] readByteArray(final DataInput in)
184   throws IOException {
185     int len = WritableUtils.readVInt(in);
186     if (len < 0) {
187       throw new NegativeArraySizeException(Integer.toString(len));
188     }
189     byte [] result = new byte[len];
190     in.readFully(result, 0, len);
191     return result;
192   }
193 
194   /**
195    * Read byte-array written with a WritableableUtils.vint prefix.
196    * IOException is converted to a RuntimeException.
197    * @param in Input to read from.
198    * @return byte array read off <code>in</code>
199    */
200   public static byte [] readByteArrayThrowsRuntime(final DataInput in) {
201     try {
202       return readByteArray(in);
203     } catch (Exception e) {
204       throw new RuntimeException(e);
205     }
206   }
207 
208   /**
209    * Write byte-array with a WritableableUtils.vint prefix.
210    * @param out output stream to be written to
211    * @param b array to write
212    * @throws IOException e
213    */
214   public static void writeByteArray(final DataOutput out, final byte [] b)
215   throws IOException {
216     if(b == null) {
217       WritableUtils.writeVInt(out, 0);
218     } else {
219       writeByteArray(out, b, 0, b.length);
220     }
221   }
222 
223   /**
224    * Write byte-array to out with a vint length prefix.
225    * @param out output stream
226    * @param b array
227    * @param offset offset into array
228    * @param length length past offset
229    * @throws IOException e
230    */
231   public static void writeByteArray(final DataOutput out, final byte [] b,
232       final int offset, final int length)
233   throws IOException {
234     WritableUtils.writeVInt(out, length);
235     out.write(b, offset, length);
236   }
237 
238   /**
239    * Write byte-array from src to tgt with a vint length prefix.
240    * @param tgt target array
241    * @param tgtOffset offset into target array
242    * @param src source array
243    * @param srcOffset source offset
244    * @param srcLength source length
245    * @return New offset in src array.
246    */
247   public static int writeByteArray(final byte [] tgt, final int tgtOffset,
248       final byte [] src, final int srcOffset, final int srcLength) {
249     byte [] vint = vintToBytes(srcLength);
250     System.arraycopy(vint, 0, tgt, tgtOffset, vint.length);
251     int offset = tgtOffset + vint.length;
252     System.arraycopy(src, srcOffset, tgt, offset, srcLength);
253     return offset + srcLength;
254   }
255 
256   /**
257    * Put bytes at the specified byte array position.
258    * @param tgtBytes the byte array
259    * @param tgtOffset position in the array
260    * @param srcBytes array to write out
261    * @param srcOffset source offset
262    * @param srcLength source length
263    * @return incremented offset
264    */
265   public static int putBytes(byte[] tgtBytes, int tgtOffset, byte[] srcBytes,
266       int srcOffset, int srcLength) {
267     System.arraycopy(srcBytes, srcOffset, tgtBytes, tgtOffset, srcLength);
268     return tgtOffset + srcLength;
269   }
270 
271   /**
272    * Write a single byte out to the specified byte array position.
273    * @param bytes the byte array
274    * @param offset position in the array
275    * @param b byte to write out
276    * @return incremented offset
277    */
278   public static int putByte(byte[] bytes, int offset, byte b) {
279     bytes[offset] = b;
280     return offset + 1;
281   }
282 
283   /**
284    * Returns a new byte array, copied from the given {@code buf},
285    * from the index 0 (inclusive) to the limit (exclusive),
286    * regardless of the current position.
287    * The position and the other index parameters are not changed.
288    *
289    * @param buf a byte buffer
290    * @return the byte array
291    * @see #getBytes(ByteBuffer)
292    */
293   public static byte[] toBytes(ByteBuffer buf) {
294     ByteBuffer dup = buf.duplicate();
295     dup.position(0);
296     return readBytes(dup);
297   }
298 
299   private static byte[] readBytes(ByteBuffer buf) {
300     byte [] result = new byte[buf.remaining()];
301     buf.get(result);
302     return result;
303   }
304 
305   /**
306    * @param b Presumed UTF-8 encoded byte array.
307    * @return String made from <code>b</code>
308    */
309   public static String toString(final byte [] b) {
310     if (b == null) {
311       return null;
312     }
313     return toString(b, 0, b.length);
314   }
315 
316   /**
317    * Joins two byte arrays together using a separator.
318    * @param b1 The first byte array.
319    * @param sep The separator to use.
320    * @param b2 The second byte array.
321    */
322   public static String toString(final byte [] b1,
323                                 String sep,
324                                 final byte [] b2) {
325     return toString(b1, 0, b1.length) + sep + toString(b2, 0, b2.length);
326   }
327 
328   /**
329    * This method will convert utf8 encoded bytes into a string. If
330    * the given byte array is null, this method will return null.
331    *
332    * @param b Presumed UTF-8 encoded byte array.
333    * @param off offset into array
334    * @param len length of utf-8 sequence
335    * @return String made from <code>b</code> or null
336    */
337   public static String toString(final byte [] b, int off, int len) {
338     if (b == null) {
339       return null;
340     }
341     if (len == 0) {
342       return "";
343     }
344     return new String(b, off, len, HConstants.UTF8_CHARSET);
345   }
346 
347   /**
348    * Write a printable representation of a byte array.
349    *
350    * @param b byte array
351    * @return string
352    * @see #toStringBinary(byte[], int, int)
353    */
354   public static String toStringBinary(final byte [] b) {
355     if (b == null)
356       return "null";
357     return toStringBinary(b, 0, b.length);
358   }
359 
360   /**
361    * Converts the given byte buffer to a printable representation,
362    * from the index 0 (inclusive) to the limit (exclusive),
363    * regardless of the current position.
364    * The position and the other index parameters are not changed.
365    *
366    * @param buf a byte buffer
367    * @return a string representation of the buffer's binary contents
368    * @see #toBytes(ByteBuffer)
369    * @see #getBytes(ByteBuffer)
370    */
371   public static String toStringBinary(ByteBuffer buf) {
372     if (buf == null)
373       return "null";
374     if (buf.hasArray()) {
375       return toStringBinary(buf.array(), buf.arrayOffset(), buf.limit());
376     }
377     return toStringBinary(toBytes(buf));
378   }
379 
380   /**
381    * Write a printable representation of a byte array. Non-printable
382    * characters are hex escaped in the format \\x%02X, eg:
383    * \x00 \x05 etc
384    *
385    * @param b array to write out
386    * @param off offset to start at
387    * @param len length to write
388    * @return string output
389    */
390   public static String toStringBinary(final byte [] b, int off, int len) {
391     StringBuilder result = new StringBuilder();
392     // Just in case we are passed a 'len' that is > buffer length...
393     if (off >= b.length) return result.toString();
394     if (off + len > b.length) len = b.length - off;
395     for (int i = off; i < off + len ; ++i ) {
396       int ch = b[i] & 0xFF;
397       if ( (ch >= '0' && ch <= '9')
398           || (ch >= 'A' && ch <= 'Z')
399           || (ch >= 'a' && ch <= 'z')
400           || " `~!@#$%^&*()-_=+[]{}|;:'\",.<>/?".indexOf(ch) >= 0 ) {
401         result.append((char)ch);
402       } else {
403         result.append(String.format("\\x%02X", ch));
404       }
405     }
406     return result.toString();
407   }
408 
409   private static boolean isHexDigit(char c) {
410     return
411         (c >= 'A' && c <= 'F') ||
412         (c >= '0' && c <= '9');
413   }
414 
415   /**
416    * Takes a ASCII digit in the range A-F0-9 and returns
417    * the corresponding integer/ordinal value.
418    * @param ch  The hex digit.
419    * @return The converted hex value as a byte.
420    */
421   public static byte toBinaryFromHex(byte ch) {
422     if ( ch >= 'A' && ch <= 'F' )
423       return (byte) ((byte)10 + (byte) (ch - 'A'));
424     // else
425     return (byte) (ch - '0');
426   }
427 
428   public static byte [] toBytesBinary(String in) {
429     // this may be bigger than we need, but let's be safe.
430     byte [] b = new byte[in.length()];
431     int size = 0;
432     for (int i = 0; i < in.length(); ++i) {
433       char ch = in.charAt(i);
434       if (ch == '\\' && in.length() > i+1 && in.charAt(i+1) == 'x') {
435         // ok, take next 2 hex digits.
436         char hd1 = in.charAt(i+2);
437         char hd2 = in.charAt(i+3);
438 
439         // they need to be A-F0-9:
440         if (!isHexDigit(hd1) ||
441             !isHexDigit(hd2)) {
442           // bogus escape code, ignore:
443           continue;
444         }
445         // turn hex ASCII digit -> number
446         byte d = (byte) ((toBinaryFromHex((byte)hd1) << 4) + toBinaryFromHex((byte)hd2));
447 
448         b[size++] = d;
449         i += 3; // skip 3
450       } else {
451         b[size++] = (byte) ch;
452       }
453     }
454     // resize:
455     byte [] b2 = new byte[size];
456     System.arraycopy(b, 0, b2, 0, size);
457     return b2;
458   }
459 
460   /**
461    * Converts a string to a UTF-8 byte array.
462    * @param s string
463    * @return the byte array
464    */
465   public static byte[] toBytes(String s) {
466     return s.getBytes(HConstants.UTF8_CHARSET);
467   }
468 
469   /**
470    * Convert a boolean to a byte array. True becomes -1
471    * and false becomes 0.
472    *
473    * @param b value
474    * @return <code>b</code> encoded in a byte array.
475    */
476   public static byte [] toBytes(final boolean b) {
477     return new byte[] { b ? (byte) -1 : (byte) 0 };
478   }
479 
480   /**
481    * Reverses {@link #toBytes(boolean)}
482    * @param b array
483    * @return True or false.
484    */
485   public static boolean toBoolean(final byte [] b) {
486     if (b.length != 1) {
487       throw new IllegalArgumentException("Array has wrong size: " + b.length);
488     }
489     return b[0] != (byte) 0;
490   }
491 
492   /**
493    * Convert a long value to a byte array using big-endian.
494    *
495    * @param val value to convert
496    * @return the byte array
497    */
498   public static byte[] toBytes(long val) {
499     byte [] b = new byte[8];
500     for (int i = 7; i > 0; i--) {
501       b[i] = (byte) val;
502       val >>>= 8;
503     }
504     b[0] = (byte) val;
505     return b;
506   }
507 
508   /**
509    * Converts a byte array to a long value. Reverses
510    * {@link #toBytes(long)}
511    * @param bytes array
512    * @return the long value
513    */
514   public static long toLong(byte[] bytes) {
515     return toLong(bytes, 0, SIZEOF_LONG);
516   }
517 
518   /**
519    * Converts a byte array to a long value. Assumes there will be
520    * {@link #SIZEOF_LONG} bytes available.
521    *
522    * @param bytes bytes
523    * @param offset offset
524    * @return the long value
525    */
526   public static long toLong(byte[] bytes, int offset) {
527     return toLong(bytes, offset, SIZEOF_LONG);
528   }
529 
530   /**
531    * Converts a byte array to a long value.
532    *
533    * @param bytes array of bytes
534    * @param offset offset into array
535    * @param length length of data (must be {@link #SIZEOF_LONG})
536    * @return the long value
537    * @throws IllegalArgumentException if length is not {@link #SIZEOF_LONG} or
538    * if there's not enough room in the array at the offset indicated.
539    */
540   public static long toLong(byte[] bytes, int offset, final int length) {
541     if (length != SIZEOF_LONG || offset + length > bytes.length) {
542       throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_LONG);
543     }
544     long l = 0;
545     for(int i = offset; i < offset + length; i++) {
546       l <<= 8;
547       l ^= bytes[i] & 0xFF;
548     }
549     return l;
550   }
551 
552   private static IllegalArgumentException
553     explainWrongLengthOrOffset(final byte[] bytes,
554                                final int offset,
555                                final int length,
556                                final int expectedLength) {
557     String reason;
558     if (length != expectedLength) {
559       reason = "Wrong length: " + length + ", expected " + expectedLength;
560     } else {
561      reason = "offset (" + offset + ") + length (" + length + ") exceed the"
562         + " capacity of the array: " + bytes.length;
563     }
564     return new IllegalArgumentException(reason);
565   }
566 
567   /**
568    * Put a long value out to the specified byte array position.
569    * @param bytes the byte array
570    * @param offset position in the array
571    * @param val long to write out
572    * @return incremented offset
573    * @throws IllegalArgumentException if the byte array given doesn't have
574    * enough room at the offset specified.
575    */
576   public static int putLong(byte[] bytes, int offset, long val) {
577     if (bytes.length - offset < SIZEOF_LONG) {
578       throw new IllegalArgumentException("Not enough room to put a long at"
579           + " offset " + offset + " in a " + bytes.length + " byte array");
580     }
581     for(int i = offset + 7; i > offset; i--) {
582       bytes[i] = (byte) val;
583       val >>>= 8;
584     }
585     bytes[offset] = (byte) val;
586     return offset + SIZEOF_LONG;
587   }
588 
589   /**
590    * Presumes float encoded as IEEE 754 floating-point "single format"
591    * @param bytes byte array
592    * @return Float made from passed byte array.
593    */
594   public static float toFloat(byte [] bytes) {
595     return toFloat(bytes, 0);
596   }
597 
598   /**
599    * Presumes float encoded as IEEE 754 floating-point "single format"
600    * @param bytes array to convert
601    * @param offset offset into array
602    * @return Float made from passed byte array.
603    */
604   public static float toFloat(byte [] bytes, int offset) {
605     return Float.intBitsToFloat(toInt(bytes, offset, SIZEOF_INT));
606   }
607 
608   /**
609    * @param bytes byte array
610    * @param offset offset to write to
611    * @param f float value
612    * @return New offset in <code>bytes</code>
613    */
614   public static int putFloat(byte [] bytes, int offset, float f) {
615     return putInt(bytes, offset, Float.floatToRawIntBits(f));
616   }
617 
618   /**
619    * @param f float value
620    * @return the float represented as byte []
621    */
622   public static byte [] toBytes(final float f) {
623     // Encode it as int
624     return Bytes.toBytes(Float.floatToRawIntBits(f));
625   }
626 
627   /**
628    * @param bytes byte array
629    * @return Return double made from passed bytes.
630    */
631   public static double toDouble(final byte [] bytes) {
632     return toDouble(bytes, 0);
633   }
634 
635   /**
636    * @param bytes byte array
637    * @param offset offset where double is
638    * @return Return double made from passed bytes.
639    */
640   public static double toDouble(final byte [] bytes, final int offset) {
641     return Double.longBitsToDouble(toLong(bytes, offset, SIZEOF_LONG));
642   }
643 
644   /**
645    * @param bytes byte array
646    * @param offset offset to write to
647    * @param d value
648    * @return New offset into array <code>bytes</code>
649    */
650   public static int putDouble(byte [] bytes, int offset, double d) {
651     return putLong(bytes, offset, Double.doubleToLongBits(d));
652   }
653 
654   /**
655    * Serialize a double as the IEEE 754 double format output. The resultant
656    * array will be 8 bytes long.
657    *
658    * @param d value
659    * @return the double represented as byte []
660    */
661   public static byte [] toBytes(final double d) {
662     // Encode it as a long
663     return Bytes.toBytes(Double.doubleToRawLongBits(d));
664   }
665 
666   /**
667    * Convert an int value to a byte array.  Big-endian.  Same as what DataOutputStream.writeInt
668    * does.
669    *
670    * @param val value
671    * @return the byte array
672    */
673   public static byte[] toBytes(int val) {
674     byte [] b = new byte[4];
675     for(int i = 3; i > 0; i--) {
676       b[i] = (byte) val;
677       val >>>= 8;
678     }
679     b[0] = (byte) val;
680     return b;
681   }
682 
683   /**
684    * Converts a byte array to an int value
685    * @param bytes byte array
686    * @return the int value
687    */
688   public static int toInt(byte[] bytes) {
689     return toInt(bytes, 0, SIZEOF_INT);
690   }
691 
692   /**
693    * Converts a byte array to an int value
694    * @param bytes byte array
695    * @param offset offset into array
696    * @return the int value
697    */
698   public static int toInt(byte[] bytes, int offset) {
699     return toInt(bytes, offset, SIZEOF_INT);
700   }
701 
702   /**
703    * Converts a byte array to an int value
704    * @param bytes byte array
705    * @param offset offset into array
706    * @param length length of int (has to be {@link #SIZEOF_INT})
707    * @return the int value
708    * @throws IllegalArgumentException if length is not {@link #SIZEOF_INT} or
709    * if there's not enough room in the array at the offset indicated.
710    */
711   public static int toInt(byte[] bytes, int offset, final int length) {
712     if (length != SIZEOF_INT || offset + length > bytes.length) {
713       throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_INT);
714     }
715     int n = 0;
716     for(int i = offset; i < (offset + length); i++) {
717       n <<= 8;
718       n ^= bytes[i] & 0xFF;
719     }
720     return n;
721   }
722 
723   /**
724    * Put an int value out to the specified byte array position.
725    * @param bytes the byte array
726    * @param offset position in the array
727    * @param val int to write out
728    * @return incremented offset
729    * @throws IllegalArgumentException if the byte array given doesn't have
730    * enough room at the offset specified.
731    */
732   public static int putInt(byte[] bytes, int offset, int val) {
733     if (bytes.length - offset < SIZEOF_INT) {
734       throw new IllegalArgumentException("Not enough room to put an int at"
735           + " offset " + offset + " in a " + bytes.length + " byte array");
736     }
737     for(int i= offset + 3; i > offset; i--) {
738       bytes[i] = (byte) val;
739       val >>>= 8;
740     }
741     bytes[offset] = (byte) val;
742     return offset + SIZEOF_INT;
743   }
744 
745   /**
746    * Convert a short value to a byte array of {@link #SIZEOF_SHORT} bytes long.
747    * @param val value
748    * @return the byte array
749    */
750   public static byte[] toBytes(short val) {
751     byte[] b = new byte[SIZEOF_SHORT];
752     b[1] = (byte) val;
753     val >>= 8;
754     b[0] = (byte) val;
755     return b;
756   }
757 
758   /**
759    * Converts a byte array to a short value
760    * @param bytes byte array
761    * @return the short value
762    */
763   public static short toShort(byte[] bytes) {
764     return toShort(bytes, 0, SIZEOF_SHORT);
765   }
766 
767   /**
768    * Converts a byte array to a short value
769    * @param bytes byte array
770    * @param offset offset into array
771    * @return the short value
772    */
773   public static short toShort(byte[] bytes, int offset) {
774     return toShort(bytes, offset, SIZEOF_SHORT);
775   }
776 
777   /**
778    * Converts a byte array to a short value
779    * @param bytes byte array
780    * @param offset offset into array
781    * @param length length, has to be {@link #SIZEOF_SHORT}
782    * @return the short value
783    * @throws IllegalArgumentException if length is not {@link #SIZEOF_SHORT}
784    * or if there's not enough room in the array at the offset indicated.
785    */
786   public static short toShort(byte[] bytes, int offset, final int length) {
787     if (length != SIZEOF_SHORT || offset + length > bytes.length) {
788       throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_SHORT);
789     }
790     short n = 0;
791     n ^= bytes[offset] & 0xFF;
792     n <<= 8;
793     n ^= bytes[offset+1] & 0xFF;
794     return n;
795   }
796 
797   /**
798    * Returns a new byte array, copied from the given {@code buf},
799    * from the position (inclusive) to the limit (exclusive).
800    * The position and the other index parameters are not changed.
801    *
802    * @param buf a byte buffer
803    * @return the byte array
804    * @see #toBytes(ByteBuffer)
805    */
806   public static byte[] getBytes(ByteBuffer buf) {
807     return readBytes(buf.duplicate());
808   }
809 
810   /**
811    * Put a short value out to the specified byte array position.
812    * @param bytes the byte array
813    * @param offset position in the array
814    * @param val short to write out
815    * @return incremented offset
816    * @throws IllegalArgumentException if the byte array given doesn't have
817    * enough room at the offset specified.
818    */
819   public static int putShort(byte[] bytes, int offset, short val) {
820     if (bytes.length - offset < SIZEOF_SHORT) {
821       throw new IllegalArgumentException("Not enough room to put a short at"
822           + " offset " + offset + " in a " + bytes.length + " byte array");
823     }
824     bytes[offset+1] = (byte) val;
825     val >>= 8;
826     bytes[offset] = (byte) val;
827     return offset + SIZEOF_SHORT;
828   }
829 
830   /**
831    * Convert a BigDecimal value to a byte array
832    *
833    * @param val
834    * @return the byte array
835    */
836   public static byte[] toBytes(BigDecimal val) {
837     byte[] valueBytes = val.unscaledValue().toByteArray();
838     byte[] result = new byte[valueBytes.length + SIZEOF_INT];
839     int offset = putInt(result, 0, val.scale());
840     putBytes(result, offset, valueBytes, 0, valueBytes.length);
841     return result;
842   }
843 
844 
845   /**
846    * Converts a byte array to a BigDecimal
847    *
848    * @param bytes
849    * @return the char value
850    */
851   public static BigDecimal toBigDecimal(byte[] bytes) {
852     return toBigDecimal(bytes, 0, bytes.length);
853   }
854 
855   /**
856    * Converts a byte array to a BigDecimal value
857    *
858    * @param bytes
859    * @param offset
860    * @param length
861    * @return the char value
862    */
863   public static BigDecimal toBigDecimal(byte[] bytes, int offset, final int length) {
864     if (bytes == null || length < SIZEOF_INT + 1 ||
865       (offset + length > bytes.length)) {
866       return null;
867     }
868 
869     int scale = toInt(bytes, offset);
870     byte[] tcBytes = new byte[length - SIZEOF_INT];
871     System.arraycopy(bytes, offset + SIZEOF_INT, tcBytes, 0, length - SIZEOF_INT);
872     return new BigDecimal(new BigInteger(tcBytes), scale);
873   }
874 
875   /**
876    * Put a BigDecimal value out to the specified byte array position.
877    *
878    * @param bytes  the byte array
879    * @param offset position in the array
880    * @param val    BigDecimal to write out
881    * @return incremented offset
882    */
883   public static int putBigDecimal(byte[] bytes, int offset, BigDecimal val) {
884     if (bytes == null) {
885       return offset;
886     }
887 
888     byte[] valueBytes = val.unscaledValue().toByteArray();
889     byte[] result = new byte[valueBytes.length + SIZEOF_INT];
890     offset = putInt(result, offset, val.scale());
891     return putBytes(result, offset, valueBytes, 0, valueBytes.length);
892   }
893 
894   /**
895    * @param vint Integer to make a vint of.
896    * @return Vint as bytes array.
897    */
898   public static byte [] vintToBytes(final long vint) {
899     long i = vint;
900     int size = WritableUtils.getVIntSize(i);
901     byte [] result = new byte[size];
902     int offset = 0;
903     if (i >= -112 && i <= 127) {
904       result[offset] = (byte) i;
905       return result;
906     }
907 
908     int len = -112;
909     if (i < 0) {
910       i ^= -1L; // take one's complement'
911       len = -120;
912     }
913 
914     long tmp = i;
915     while (tmp != 0) {
916       tmp = tmp >> 8;
917       len--;
918     }
919 
920     result[offset++] = (byte) len;
921 
922     len = (len < -120) ? -(len + 120) : -(len + 112);
923 
924     for (int idx = len; idx != 0; idx--) {
925       int shiftbits = (idx - 1) * 8;
926       long mask = 0xFFL << shiftbits;
927       result[offset++] = (byte)((i & mask) >> shiftbits);
928     }
929     return result;
930   }
931 
932   /**
933    * @param buffer buffer to convert
934    * @return vint bytes as an integer.
935    */
936   public static long bytesToVint(final byte [] buffer) {
937     int offset = 0;
938     byte firstByte = buffer[offset++];
939     int len = WritableUtils.decodeVIntSize(firstByte);
940     if (len == 1) {
941       return firstByte;
942     }
943     long i = 0;
944     for (int idx = 0; idx < len-1; idx++) {
945       byte b = buffer[offset++];
946       i = i << 8;
947       i = i | (b & 0xFF);
948     }
949     return (WritableUtils.isNegativeVInt(firstByte) ? ~i : i);
950   }
951 
952   /**
953    * Reads a zero-compressed encoded long from input stream and returns it.
954    * @param buffer Binary array
955    * @param offset Offset into array at which vint begins.
956    * @throws java.io.IOException e
957    * @return deserialized long from stream.
958    */
959   public static long readVLong(final byte [] buffer, final int offset)
960   throws IOException {
961     byte firstByte = buffer[offset];
962     int len = WritableUtils.decodeVIntSize(firstByte);
963     if (len == 1) {
964       return firstByte;
965     }
966     long i = 0;
967     for (int idx = 0; idx < len-1; idx++) {
968       byte b = buffer[offset + 1 + idx];
969       i = i << 8;
970       i = i | (b & 0xFF);
971     }
972     return (WritableUtils.isNegativeVInt(firstByte) ? ~i : i);
973   }
974 
975   /**
976    * @param left left operand
977    * @param right right operand
978    * @return 0 if equal, < 0 if left is less than right, etc.
979    */
980   public static int compareTo(final byte [] left, final byte [] right) {
981     return LexicographicalComparerHolder.BEST_COMPARER.
982       compareTo(left, 0, left.length, right, 0, right.length);
983   }
984 
985   /**
986    * Lexicographically compare two arrays.
987    *
988    * @param buffer1 left operand
989    * @param buffer2 right operand
990    * @param offset1 Where to start comparing in the left buffer
991    * @param offset2 Where to start comparing in the right buffer
992    * @param length1 How much to compare from the left buffer
993    * @param length2 How much to compare from the right buffer
994    * @return 0 if equal, < 0 if left is less than right, etc.
995    */
996   public static int compareTo(byte[] buffer1, int offset1, int length1,
997       byte[] buffer2, int offset2, int length2) {
998     return LexicographicalComparerHolder.BEST_COMPARER.
999       compareTo(buffer1, offset1, length1, buffer2, offset2, length2);
1000   }
1001 
1002   interface Comparer<T> {
1003     abstract public int compareTo(T buffer1, int offset1, int length1,
1004         T buffer2, int offset2, int length2);
1005   }
1006 
1007   @VisibleForTesting
1008   static Comparer<byte[]> lexicographicalComparerJavaImpl() {
1009     return LexicographicalComparerHolder.PureJavaComparer.INSTANCE;
1010   }
1011 
1012   /**
1013    * Provides a lexicographical comparer implementation; either a Java
1014    * implementation or a faster implementation based on {@link Unsafe}.
1015    *
1016    * <p>Uses reflection to gracefully fall back to the Java implementation if
1017    * {@code Unsafe} isn't available.
1018    */
1019   @VisibleForTesting
1020   static class LexicographicalComparerHolder {
1021     static final String UNSAFE_COMPARER_NAME =
1022         LexicographicalComparerHolder.class.getName() + "$UnsafeComparer";
1023 
1024     static final Comparer<byte[]> BEST_COMPARER = getBestComparer();
1025     /**
1026      * Returns the Unsafe-using Comparer, or falls back to the pure-Java
1027      * implementation if unable to do so.
1028      */
1029     static Comparer<byte[]> getBestComparer() {
1030       try {
1031         Class<?> theClass = Class.forName(UNSAFE_COMPARER_NAME);
1032 
1033         // yes, UnsafeComparer does implement Comparer<byte[]>
1034         @SuppressWarnings("unchecked")
1035         Comparer<byte[]> comparer =
1036           (Comparer<byte[]>) theClass.getEnumConstants()[0];
1037         return comparer;
1038       } catch (Throwable t) { // ensure we really catch *everything*
1039         return lexicographicalComparerJavaImpl();
1040       }
1041     }
1042 
1043     enum PureJavaComparer implements Comparer<byte[]> {
1044       INSTANCE;
1045 
1046       @Override
1047       public int compareTo(byte[] buffer1, int offset1, int length1,
1048           byte[] buffer2, int offset2, int length2) {
1049         // Short circuit equal case
1050         if (buffer1 == buffer2 &&
1051             offset1 == offset2 &&
1052             length1 == length2) {
1053           return 0;
1054         }
1055         // Bring WritableComparator code local
1056         int end1 = offset1 + length1;
1057         int end2 = offset2 + length2;
1058         for (int i = offset1, j = offset2; i < end1 && j < end2; i++, j++) {
1059           int a = (buffer1[i] & 0xff);
1060           int b = (buffer2[j] & 0xff);
1061           if (a != b) {
1062             return a - b;
1063           }
1064         }
1065         return length1 - length2;
1066       }
1067     }
1068 
1069     @VisibleForTesting
1070     enum UnsafeComparer implements Comparer<byte[]> {
1071       INSTANCE;
1072 
1073       static final Unsafe theUnsafe;
1074 
1075       /** The offset to the first element in a byte array. */
1076       static final int BYTE_ARRAY_BASE_OFFSET;
1077 
1078       static {
1079         theUnsafe = (Unsafe) AccessController.doPrivileged(
1080             new PrivilegedAction<Object>() {
1081               @Override
1082               public Object run() {
1083                 try {
1084                   Field f = Unsafe.class.getDeclaredField("theUnsafe");
1085                   f.setAccessible(true);
1086                   return f.get(null);
1087                 } catch (NoSuchFieldException e) {
1088                   // It doesn't matter what we throw;
1089                   // it's swallowed in getBestComparer().
1090                   throw new Error();
1091                 } catch (IllegalAccessException e) {
1092                   throw new Error();
1093                 }
1094               }
1095             });
1096 
1097         BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);
1098 
1099         // sanity check - this should never fail
1100         if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
1101           throw new AssertionError();
1102         }
1103       }
1104 
1105       static final boolean littleEndian =
1106         ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN);
1107 
1108       /**
1109        * Returns true if x1 is less than x2, when both values are treated as
1110        * unsigned.
1111        */
1112       static boolean lessThanUnsigned(long x1, long x2) {
1113         return (x1 + Long.MIN_VALUE) < (x2 + Long.MIN_VALUE);
1114       }
1115 
1116       /**
1117        * Lexicographically compare two arrays.
1118        *
1119        * @param buffer1 left operand
1120        * @param buffer2 right operand
1121        * @param offset1 Where to start comparing in the left buffer
1122        * @param offset2 Where to start comparing in the right buffer
1123        * @param length1 How much to compare from the left buffer
1124        * @param length2 How much to compare from the right buffer
1125        * @return 0 if equal, < 0 if left is less than right, etc.
1126        */
1127       @Override
1128       public int compareTo(byte[] buffer1, int offset1, int length1,
1129           byte[] buffer2, int offset2, int length2) {
1130         // Short circuit equal case
1131         if (buffer1 == buffer2 &&
1132             offset1 == offset2 &&
1133             length1 == length2) {
1134           return 0;
1135         }
1136         int minLength = Math.min(length1, length2);
1137         int minWords = minLength / SIZEOF_LONG;
1138         int offset1Adj = offset1 + BYTE_ARRAY_BASE_OFFSET;
1139         int offset2Adj = offset2 + BYTE_ARRAY_BASE_OFFSET;
1140 
1141         /*
1142          * Compare 8 bytes at a time. Benchmarking shows comparing 8 bytes at a
1143          * time is no slower than comparing 4 bytes at a time even on 32-bit.
1144          * On the other hand, it is substantially faster on 64-bit.
1145          */
1146         for (int i = 0; i < minWords * SIZEOF_LONG; i += SIZEOF_LONG) {
1147           long lw = theUnsafe.getLong(buffer1, offset1Adj + (long) i);
1148           long rw = theUnsafe.getLong(buffer2, offset2Adj + (long) i);
1149           long diff = lw ^ rw;
1150 
1151           if (diff != 0) {
1152             if (!littleEndian) {
1153               return lessThanUnsigned(lw, rw) ? -1 : 1;
1154             }
1155 
1156             // Use binary search
1157             int n = 0;
1158             int y;
1159             int x = (int) diff;
1160             if (x == 0) {
1161               x = (int) (diff >>> 32);
1162               n = 32;
1163             }
1164 
1165             y = x << 16;
1166             if (y == 0) {
1167               n += 16;
1168             } else {
1169               x = y;
1170             }
1171 
1172             y = x << 8;
1173             if (y == 0) {
1174               n += 8;
1175             }
1176             return (int) (((lw >>> n) & 0xFFL) - ((rw >>> n) & 0xFFL));
1177           }
1178         }
1179 
1180         // The epilogue to cover the last (minLength % 8) elements.
1181         for (int i = minWords * SIZEOF_LONG; i < minLength; i++) {
1182           int a = (buffer1[offset1 + i] & 0xff);
1183           int b = (buffer2[offset2 + i] & 0xff);
1184           if (a != b) {
1185             return a - b;
1186           }
1187         }
1188         return length1 - length2;
1189       }
1190     }
1191   }
1192 
1193   /**
1194    * @param left left operand
1195    * @param right right operand
1196    * @return True if equal
1197    */
1198   public static boolean equals(final byte [] left, final byte [] right) {
1199     // Could use Arrays.equals?
1200     //noinspection SimplifiableConditionalExpression
1201     if (left == right) return true;
1202     if (left == null || right == null) return false;
1203     if (left.length != right.length) return false;
1204     if (left.length == 0) return true;
1205 
1206     // Since we're often comparing adjacent sorted data,
1207     // it's usual to have equal arrays except for the very last byte
1208     // so check that first
1209     if (left[left.length - 1] != right[right.length - 1]) return false;
1210 
1211     return compareTo(left, right) == 0;
1212   }
1213 
1214   public static boolean equals(final byte[] left, int leftOffset, int leftLen,
1215                                final byte[] right, int rightOffset, int rightLen) {
1216     // short circuit case
1217     if (left == right &&
1218         leftOffset == rightOffset &&
1219         leftLen == rightLen) {
1220       return true;
1221     }
1222     // different lengths fast check
1223     if (leftLen != rightLen) {
1224       return false;
1225     }
1226     if (leftLen == 0) {
1227       return true;
1228     }
1229 
1230     // Since we're often comparing adjacent sorted data,
1231     // it's usual to have equal arrays except for the very last byte
1232     // so check that first
1233     if (left[leftOffset + leftLen - 1] != right[rightOffset + rightLen - 1]) return false;
1234 
1235     return LexicographicalComparerHolder.BEST_COMPARER.
1236       compareTo(left, leftOffset, leftLen, right, rightOffset, rightLen) == 0;
1237   }
1238 
1239 
1240   /**
1241    * Return true if the byte array on the right is a prefix of the byte
1242    * array on the left.
1243    */
1244   public static boolean startsWith(byte[] bytes, byte[] prefix) {
1245     return bytes != null && prefix != null &&
1246       bytes.length >= prefix.length &&
1247       LexicographicalComparerHolder.BEST_COMPARER.
1248         compareTo(bytes, 0, prefix.length, prefix, 0, prefix.length) == 0;
1249   }
1250 
1251   /**
1252    * @param b bytes to hash
1253    * @return Runs {@link WritableComparator#hashBytes(byte[], int)} on the
1254    * passed in array.  This method is what {@link org.apache.hadoop.io.Text} and
1255    * {@link ImmutableBytesWritable} use calculating hash code.
1256    */
1257   public static int hashCode(final byte [] b) {
1258     return hashCode(b, b.length);
1259   }
1260 
1261   /**
1262    * @param b value
1263    * @param length length of the value
1264    * @return Runs {@link WritableComparator#hashBytes(byte[], int)} on the
1265    * passed in array.  This method is what {@link org.apache.hadoop.io.Text} and
1266    * {@link ImmutableBytesWritable} use calculating hash code.
1267    */
1268   public static int hashCode(final byte [] b, final int length) {
1269     return WritableComparator.hashBytes(b, length);
1270   }
1271 
1272   /**
1273    * @param b bytes to hash
1274    * @return A hash of <code>b</code> as an Integer that can be used as key in
1275    * Maps.
1276    */
1277   public static Integer mapKey(final byte [] b) {
1278     return hashCode(b);
1279   }
1280 
1281   /**
1282    * @param b bytes to hash
1283    * @param length length to hash
1284    * @return A hash of <code>b</code> as an Integer that can be used as key in
1285    * Maps.
1286    */
1287   public static Integer mapKey(final byte [] b, final int length) {
1288     return hashCode(b, length);
1289   }
1290 
1291   /**
1292    * @param a lower half
1293    * @param b upper half
1294    * @return New array that has a in lower half and b in upper half.
1295    */
1296   public static byte [] add(final byte [] a, final byte [] b) {
1297     return add(a, b, HConstants.EMPTY_BYTE_ARRAY);
1298   }
1299 
1300   /**
1301    * @param a first third
1302    * @param b second third
1303    * @param c third third
1304    * @return New array made from a, b and c
1305    */
1306   public static byte [] add(final byte [] a, final byte [] b, final byte [] c) {
1307     byte [] result = new byte[a.length + b.length + c.length];
1308     System.arraycopy(a, 0, result, 0, a.length);
1309     System.arraycopy(b, 0, result, a.length, b.length);
1310     System.arraycopy(c, 0, result, a.length + b.length, c.length);
1311     return result;
1312   }
1313 
1314   /**
1315    * @param a array
1316    * @param length amount of bytes to grab
1317    * @return First <code>length</code> bytes from <code>a</code>
1318    */
1319   public static byte [] head(final byte [] a, final int length) {
1320     if (a.length < length) {
1321       return null;
1322     }
1323     byte [] result = new byte[length];
1324     System.arraycopy(a, 0, result, 0, length);
1325     return result;
1326   }
1327 
1328   /**
1329    * @param a array
1330    * @param length amount of bytes to snarf
1331    * @return Last <code>length</code> bytes from <code>a</code>
1332    */
1333   public static byte [] tail(final byte [] a, final int length) {
1334     if (a.length < length) {
1335       return null;
1336     }
1337     byte [] result = new byte[length];
1338     System.arraycopy(a, a.length - length, result, 0, length);
1339     return result;
1340   }
1341 
1342   /**
1343    * @param a array
1344    * @param length new array size
1345    * @return Value in <code>a</code> plus <code>length</code> prepended 0 bytes
1346    */
1347   public static byte [] padHead(final byte [] a, final int length) {
1348     byte [] padding = new byte[length];
1349     for (int i = 0; i < length; i++) {
1350       padding[i] = 0;
1351     }
1352     return add(padding,a);
1353   }
1354 
1355   /**
1356    * @param a array
1357    * @param length new array size
1358    * @return Value in <code>a</code> plus <code>length</code> appended 0 bytes
1359    */
1360   public static byte [] padTail(final byte [] a, final int length) {
1361     byte [] padding = new byte[length];
1362     for (int i = 0; i < length; i++) {
1363       padding[i] = 0;
1364     }
1365     return add(a,padding);
1366   }
1367 
1368   /**
1369    * Split passed range.  Expensive operation relatively.  Uses BigInteger math.
1370    * Useful splitting ranges for MapReduce jobs.
1371    * @param a Beginning of range
1372    * @param b End of range
1373    * @param num Number of times to split range.  Pass 1 if you want to split
1374    * the range in two; i.e. one split.
1375    * @return Array of dividing values
1376    */
1377   public static byte [][] split(final byte [] a, final byte [] b, final int num) {
1378     return split(a, b, false, num);
1379   }
1380 
1381   /**
1382    * Split passed range.  Expensive operation relatively.  Uses BigInteger math.
1383    * Useful splitting ranges for MapReduce jobs.
1384    * @param a Beginning of range
1385    * @param b End of range
1386    * @param inclusive Whether the end of range is prefix-inclusive or is
1387    * considered an exclusive boundary.  Automatic splits are generally exclusive
1388    * and manual splits with an explicit range utilize an inclusive end of range.
1389    * @param num Number of times to split range.  Pass 1 if you want to split
1390    * the range in two; i.e. one split.
1391    * @return Array of dividing values
1392    */
1393   public static byte[][] split(final byte[] a, final byte[] b,
1394       boolean inclusive, final int num) {
1395     byte[][] ret = new byte[num + 2][];
1396     int i = 0;
1397     Iterable<byte[]> iter = iterateOnSplits(a, b, inclusive, num);
1398     if (iter == null)
1399       return null;
1400     for (byte[] elem : iter) {
1401       ret[i++] = elem;
1402     }
1403     return ret;
1404   }
1405 
1406   /**
1407    * Iterate over keys within the passed range, splitting at an [a,b) boundary.
1408    */
1409   public static Iterable<byte[]> iterateOnSplits(final byte[] a,
1410       final byte[] b, final int num)
1411   {
1412     return iterateOnSplits(a, b, false, num);
1413   }
1414 
1415   /**
1416    * Iterate over keys within the passed range.
1417    */
1418   public static Iterable<byte[]> iterateOnSplits(
1419       final byte[] a, final byte[]b, boolean inclusive, final int num)
1420   {
1421     byte [] aPadded;
1422     byte [] bPadded;
1423     if (a.length < b.length) {
1424       aPadded = padTail(a, b.length - a.length);
1425       bPadded = b;
1426     } else if (b.length < a.length) {
1427       aPadded = a;
1428       bPadded = padTail(b, a.length - b.length);
1429     } else {
1430       aPadded = a;
1431       bPadded = b;
1432     }
1433     if (compareTo(aPadded,bPadded) >= 0) {
1434       throw new IllegalArgumentException("b <= a");
1435     }
1436     if (num <= 0) {
1437       throw new IllegalArgumentException("num cannot be <= 0");
1438     }
1439     byte [] prependHeader = {1, 0};
1440     final BigInteger startBI = new BigInteger(add(prependHeader, aPadded));
1441     final BigInteger stopBI = new BigInteger(add(prependHeader, bPadded));
1442     BigInteger diffBI = stopBI.subtract(startBI);
1443     if (inclusive) {
1444       diffBI = diffBI.add(BigInteger.ONE);
1445     }
1446     final BigInteger splitsBI = BigInteger.valueOf(num + 1);
1447     if(diffBI.compareTo(splitsBI) < 0) {
1448       return null;
1449     }
1450     final BigInteger intervalBI;
1451     try {
1452       intervalBI = diffBI.divide(splitsBI);
1453     } catch(Exception e) {
1454       LOG.error("Exception caught during division", e);
1455       return null;
1456     }
1457 
1458     final Iterator<byte[]> iterator = new Iterator<byte[]>() {
1459       private int i = -1;
1460 
1461       @Override
1462       public boolean hasNext() {
1463         return i < num+1;
1464       }
1465 
1466       @Override
1467       public byte[] next() {
1468         i++;
1469         if (i == 0) return a;
1470         if (i == num + 1) return b;
1471 
1472         BigInteger curBI = startBI.add(intervalBI.multiply(BigInteger.valueOf(i)));
1473         byte [] padded = curBI.toByteArray();
1474         if (padded[1] == 0)
1475           padded = tail(padded, padded.length - 2);
1476         else
1477           padded = tail(padded, padded.length - 1);
1478         return padded;
1479       }
1480 
1481       @Override
1482       public void remove() {
1483         throw new UnsupportedOperationException();
1484       }
1485 
1486     };
1487 
1488     return new Iterable<byte[]>() {
1489       @Override
1490       public Iterator<byte[]> iterator() {
1491         return iterator;
1492       }
1493     };
1494   }
1495 
1496   /**
1497    * @param bytes array to hash
1498    * @param offset offset to start from
1499    * @param length length to hash
1500    * */
1501   public static int hashCode(byte[] bytes, int offset, int length) {
1502     int hash = 1;
1503     for (int i = offset; i < offset + length; i++)
1504       hash = (31 * hash) + (int) bytes[i];
1505     return hash;
1506   }
1507 
1508   /**
1509    * @param t operands
1510    * @return Array of byte arrays made from passed array of Text
1511    */
1512   public static byte [][] toByteArrays(final String [] t) {
1513     byte [][] result = new byte[t.length][];
1514     for (int i = 0; i < t.length; i++) {
1515       result[i] = Bytes.toBytes(t[i]);
1516     }
1517     return result;
1518   }
1519 
1520   /**
1521    * @param column operand
1522    * @return A byte array of a byte array where first and only entry is
1523    * <code>column</code>
1524    */
1525   public static byte [][] toByteArrays(final String column) {
1526     return toByteArrays(toBytes(column));
1527   }
1528 
1529   /**
1530    * @param column operand
1531    * @return A byte array of a byte array where first and only entry is
1532    * <code>column</code>
1533    */
1534   public static byte [][] toByteArrays(final byte [] column) {
1535     byte [][] result = new byte[1][];
1536     result[0] = column;
1537     return result;
1538   }
1539 
1540   /**
1541    * Binary search for keys in indexes.
1542    *
1543    * @param arr array of byte arrays to search for
1544    * @param key the key you want to find
1545    * @param offset the offset in the key you want to find
1546    * @param length the length of the key
1547    * @param comparator a comparator to compare.
1548    * @return zero-based index of the key, if the key is present in the array.
1549    *         Otherwise, a value -(i + 1) such that the key is between arr[i -
1550    *         1] and arr[i] non-inclusively, where i is in [0, i], if we define
1551    *         arr[-1] = -Inf and arr[N] = Inf for an N-element array. The above
1552    *         means that this function can return 2N + 1 different values
1553    *         ranging from -(N + 1) to N - 1.
1554    */
1555   public static int binarySearch(byte [][]arr, byte []key, int offset,
1556       int length, RawComparator<byte []> comparator) {
1557     int low = 0;
1558     int high = arr.length - 1;
1559 
1560     while (low <= high) {
1561       int mid = (low+high) >>> 1;
1562       // we have to compare in this order, because the comparator order
1563       // has special logic when the 'left side' is a special key.
1564       int cmp = comparator.compare(key, offset, length,
1565           arr[mid], 0, arr[mid].length);
1566       // key lives above the midpoint
1567       if (cmp > 0)
1568         low = mid + 1;
1569       // key lives below the midpoint
1570       else if (cmp < 0)
1571         high = mid - 1;
1572       // BAM. how often does this really happen?
1573       else
1574         return mid;
1575     }
1576     return - (low+1);
1577   }
1578 
1579   /**
1580    * Bytewise binary increment/deincrement of long contained in byte array
1581    * on given amount.
1582    *
1583    * @param value - array of bytes containing long (length <= SIZEOF_LONG)
1584    * @param amount value will be incremented on (deincremented if negative)
1585    * @return array of bytes containing incremented long (length == SIZEOF_LONG)
1586    */
1587   public static byte [] incrementBytes(byte[] value, long amount)
1588   {
1589     byte[] val = value;
1590     if (val.length < SIZEOF_LONG) {
1591       // Hopefully this doesn't happen too often.
1592       byte [] newvalue;
1593       if (val[0] < 0) {
1594         newvalue = new byte[]{-1, -1, -1, -1, -1, -1, -1, -1};
1595       } else {
1596         newvalue = new byte[SIZEOF_LONG];
1597       }
1598       System.arraycopy(val, 0, newvalue, newvalue.length - val.length,
1599         val.length);
1600       val = newvalue;
1601     } else if (val.length > SIZEOF_LONG) {
1602       throw new IllegalArgumentException("Increment Bytes - value too big: " +
1603         val.length);
1604     }
1605     if(amount == 0) return val;
1606     if(val[0] < 0){
1607       return binaryIncrementNeg(val, amount);
1608     }
1609     return binaryIncrementPos(val, amount);
1610   }
1611 
1612   /* increment/deincrement for positive value */
1613   private static byte [] binaryIncrementPos(byte [] value, long amount) {
1614     long amo = amount;
1615     int sign = 1;
1616     if (amount < 0) {
1617       amo = -amount;
1618       sign = -1;
1619     }
1620     for(int i=0;i<value.length;i++) {
1621       int cur = ((int)amo % 256) * sign;
1622       amo = (amo >> 8);
1623       int val = value[value.length-i-1] & 0x0ff;
1624       int total = val + cur;
1625       if(total > 255) {
1626         amo += sign;
1627         total %= 256;
1628       } else if (total < 0) {
1629         amo -= sign;
1630       }
1631       value[value.length-i-1] = (byte)total;
1632       if (amo == 0) return value;
1633     }
1634     return value;
1635   }
1636 
1637   /* increment/deincrement for negative value */
1638   private static byte [] binaryIncrementNeg(byte [] value, long amount) {
1639     long amo = amount;
1640     int sign = 1;
1641     if (amount < 0) {
1642       amo = -amount;
1643       sign = -1;
1644     }
1645     for(int i=0;i<value.length;i++) {
1646       int cur = ((int)amo % 256) * sign;
1647       amo = (amo >> 8);
1648       int val = ((~value[value.length-i-1]) & 0x0ff) + 1;
1649       int total = cur - val;
1650       if(total >= 0) {
1651         amo += sign;
1652       } else if (total < -256) {
1653         amo -= sign;
1654         total %= 256;
1655       }
1656       value[value.length-i-1] = (byte)total;
1657       if (amo == 0) return value;
1658     }
1659     return value;
1660   }
1661 
1662   /**
1663    * Writes a string as a fixed-size field, padded with zeros.
1664    */
1665   public static void writeStringFixedSize(final DataOutput out, String s,
1666       int size) throws IOException {
1667     byte[] b = toBytes(s);
1668     if (b.length > size) {
1669       throw new IOException("Trying to write " + b.length + " bytes (" +
1670           toStringBinary(b) + ") into a field of length " + size);
1671     }
1672 
1673     out.writeBytes(s);
1674     for (int i = 0; i < size - s.length(); ++i)
1675       out.writeByte(0);
1676   }
1677 
1678   /**
1679    * Reads a fixed-size field and interprets it as a string padded with zeros.
1680    */
1681   public static String readStringFixedSize(final DataInput in, int size)
1682       throws IOException {
1683     byte[] b = new byte[size];
1684     in.readFully(b);
1685     int n = b.length;
1686     while (n > 0 && b[n - 1] == 0)
1687       --n;
1688 
1689     return toString(b, 0, n);
1690   }
1691 
1692   /**
1693    * Copy the byte array given in parameter and return an instance
1694    * of a new byte array with the same length and the same content.
1695    * @param bytes the byte array to duplicate
1696    * @return a copy of the given byte array
1697    */
1698   public static byte [] copy(byte [] bytes) {
1699     if (bytes == null) return null;
1700     byte [] result = new byte[bytes.length];
1701     System.arraycopy(bytes, 0, result, 0, bytes.length);
1702     return result;
1703   }
1704 
1705   /**
1706    * Copy the byte array given in parameter and return an instance
1707    * of a new byte array with the same length and the same content.
1708    * @param bytes the byte array to copy from
1709    * @return a copy of the given designated byte array
1710    * @param offset
1711    * @param length
1712    */
1713   public static byte [] copy(byte [] bytes, final int offset, final int length) {
1714     if (bytes == null) return null;
1715     byte [] result = new byte[length];
1716     System.arraycopy(bytes, offset, result, 0, length);
1717     return result;
1718   }
1719 
1720   /**
1721    * Search sorted array "a" for byte "key". I can't remember if I wrote this or copied it from
1722    * somewhere. (mcorgan)
1723    * @param a Array to search. Entries must be sorted and unique.
1724    * @param fromIndex First index inclusive of "a" to include in the search.
1725    * @param toIndex Last index exclusive of "a" to include in the search.
1726    * @param key The byte to search for.
1727    * @return The index of key if found. If not found, return -(index + 1), where negative indicates
1728    *         "not found" and the "index + 1" handles the "-0" case.
1729    */
1730   public static int unsignedBinarySearch(byte[] a, int fromIndex, int toIndex, byte key) {
1731     int unsignedKey = key & 0xff;
1732     int low = fromIndex;
1733     int high = toIndex - 1;
1734 
1735     while (low <= high) {
1736       int mid = (low + high) >>> 1;
1737       int midVal = a[mid] & 0xff;
1738 
1739       if (midVal < unsignedKey) {
1740         low = mid + 1;
1741       } else if (midVal > unsignedKey) {
1742         high = mid - 1;
1743       } else {
1744         return mid; // key found
1745       }
1746     }
1747     return -(low + 1); // key not found.
1748   }
1749 
1750   /**
1751    * Treat the byte[] as an unsigned series of bytes, most significant bits first.  Start by adding
1752    * 1 to the rightmost bit/byte and carry over all overflows to the more significant bits/bytes.
1753    *
1754    * @param input The byte[] to increment.
1755    * @return The incremented copy of "in".  May be same length or 1 byte longer.
1756    */
1757   public static byte[] unsignedCopyAndIncrement(final byte[] input) {
1758     byte[] copy = copy(input);
1759     if (copy == null) {
1760       throw new IllegalArgumentException("cannot increment null array");
1761     }
1762     for (int i = copy.length - 1; i >= 0; --i) {
1763       if (copy[i] == -1) {// -1 is all 1-bits, which is the unsigned maximum
1764         copy[i] = 0;
1765       } else {
1766         ++copy[i];
1767         return copy;
1768       }
1769     }
1770     // we maxed out the array
1771     byte[] out = new byte[copy.length + 1];
1772     out[0] = 1;
1773     System.arraycopy(copy, 0, out, 1, copy.length);
1774     return out;
1775   }
1776 
1777   public static boolean equals(List<byte[]> a, List<byte[]> b) {
1778     if (a == null) {
1779       if (b == null) {
1780         return true;
1781       }
1782       return false;
1783     }
1784     if (b == null) {
1785       return false;
1786     }
1787     if (a.size() != b.size()) {
1788       return false;
1789     }
1790     for (int i = 0; i < a.size(); ++i) {
1791       if (!Bytes.equals(a.get(i), b.get(i))) {
1792         return false;
1793       }
1794     }
1795     return true;
1796   }
1797 
1798   public static boolean isSorted(Collection<byte[]> arrays) {
1799     byte[] previous = new byte[0];
1800     for (byte[] array : IterableUtils.nullSafe(arrays)) {
1801       if (Bytes.compareTo(previous, array) > 0) {
1802         return false;
1803       }
1804       previous = array;
1805     }
1806     return true;
1807   }
1808 
1809   public static List<byte[]> getUtf8ByteArrays(List<String> strings) {
1810     List<byte[]> byteArrays = Lists.newArrayListWithCapacity(CollectionUtils.nullSafeSize(strings));
1811     for (String s : IterableUtils.nullSafe(strings)) {
1812       byteArrays.add(Bytes.toBytes(s));
1813     }
1814     return byteArrays;
1815   }
1816 
1817   /**
1818    * Returns the index of the first appearance of the value {@code target} in
1819    * {@code array}.
1820    *
1821    * @param array an array of {@code byte} values, possibly empty
1822    * @param target a primitive {@code byte} value
1823    * @return the least index {@code i} for which {@code array[i] == target}, or
1824    *     {@code -1} if no such index exists.
1825    */
1826   public static int indexOf(byte[] array, byte target) {
1827     for (int i = 0; i < array.length; i++) {
1828       if (array[i] == target) {
1829         return i;
1830       }
1831     }
1832     return -1;
1833   }
1834 
1835   /**
1836    * Returns the start position of the first occurrence of the specified {@code
1837    * target} within {@code array}, or {@code -1} if there is no such occurrence.
1838    *
1839    * <p>More formally, returns the lowest index {@code i} such that {@code
1840    * java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
1841    * the same elements as {@code target}.
1842    *
1843    * @param array the array to search for the sequence {@code target}
1844    * @param target the array to search for as a sub-sequence of {@code array}
1845    */
1846   public static int indexOf(byte[] array, byte[] target) {
1847     checkNotNull(array, "array");
1848     checkNotNull(target, "target");
1849     if (target.length == 0) {
1850       return 0;
1851     }
1852 
1853     outer:
1854     for (int i = 0; i < array.length - target.length + 1; i++) {
1855       for (int j = 0; j < target.length; j++) {
1856         if (array[i + j] != target[j]) {
1857           continue outer;
1858         }
1859       }
1860       return i;
1861     }
1862     return -1;
1863   }
1864 
1865   /**
1866    * @param array an array of {@code byte} values, possibly empty
1867    * @param target a primitive {@code byte} value
1868    * @return {@code true} if {@code target} is present as an element anywhere in {@code array}.
1869    */
1870   public static boolean contains(byte[] array, byte target) {
1871     return indexOf(array, target) > -1;
1872   }
1873 
1874   /**
1875    * @param array an array of {@code byte} values, possibly empty
1876    * @param target an array of {@code byte}
1877    * @return {@code true} if {@code target} is present anywhere in {@code array}
1878    */
1879   public static boolean contains(byte[] array, byte[] target) {
1880     return indexOf(array, target) > -1;
1881   }
1882 
1883   /**
1884    * Fill given array with zeros.
1885    * @param b array which needs to be filled with zeros
1886    */
1887   public static void zero(byte[] b) {
1888     zero(b, 0, b.length);
1889   }
1890 
1891   /**
1892    * Fill given array with zeros at the specified position.
1893    * @param b
1894    * @param offset
1895    * @param length
1896    */
1897   public static void zero(byte[] b, int offset, int length) {
1898     checkPositionIndex(offset, b.length, "offset");
1899     checkArgument(length > 0, "length must be greater than 0");
1900     checkPositionIndex(offset + length, b.length, "offset + length");
1901     Arrays.fill(b, offset, offset + length, (byte) 0);
1902   }
1903 
1904   private static final SecureRandom RNG = new SecureRandom();
1905 
1906   /**
1907    * Fill given array with random bytes.
1908    * @param b array which needs to be filled with random bytes
1909    */
1910   public static void random(byte[] b) {
1911     RNG.nextBytes(b);
1912   }
1913 
1914   /**
1915    * Fill given array with random bytes at the specified position.
1916    * @param b
1917    * @param offset
1918    * @param length
1919    */
1920   public static void random(byte[] b, int offset, int length) {
1921     checkPositionIndex(offset, b.length, "offset");
1922     checkArgument(length > 0, "length must be greater than 0");
1923     checkPositionIndex(offset + length, b.length, "offset + length");
1924     byte[] buf = new byte[length];
1925     RNG.nextBytes(buf);
1926     System.arraycopy(buf, 0, b, offset, length);
1927   }
1928 }