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