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