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