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