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