Review Board 1.7.22


HBASE-5625 Avoid byte buffer allocations when reading a value from a Result object

Review Request #4607 - Created April 2, 2012 and updated

Tudor Scurtu
trunk
HBASE-5625
Reviewers
hbase
hbase-git
When calling Result.getValue(), an extra dummy KeyValue and its associated underlying byte array are allocated, as well as a persistent buffer that will contain the returned value.

These can be avoided by reusing a static array for the dummy object and by passing a ByteBuffer object as a value destination buffer to the read method.
Added value check to TestResult#testBasic and TestResult.testMultiVersion.
src/main/java/org/apache/hadoop/hbase/KeyValue.java
Revision 243d76f New Change
[20] 19 lines
[+20]
20
package org.apache.hadoop.hbase;
20
package org.apache.hadoop.hbase;
21

    
   
21

   
22
import java.io.DataInput;
22
import java.io.DataInput;
23
import java.io.DataOutput;
23
import java.io.DataOutput;
24
import java.io.IOException;
24
import java.io.IOException;

    
   
25
import java.nio.BufferOverflowException;
25
import java.nio.ByteBuffer;
26
import java.nio.ByteBuffer;
26
import java.util.Comparator;
27
import java.util.Comparator;
27
import java.util.HashMap;
28
import java.util.HashMap;
28
import java.util.Map;
29
import java.util.Map;
29

    
   
30

   
[+20] [20] 473 lines
[+20] [+] static byte[] createEmptyByteArray(final int rlength, int flength,
503
    pos = Bytes.putByte(bytes, pos, type.getCode());
504
    pos = Bytes.putByte(bytes, pos, type.getCode());
504
    return bytes;
505
    return bytes;
505
  }
506
  }
506

    
   
507

   
507
  /**
508
  /**
508
   * Write KeyValue format into a byte array.
509
   * Constructs KeyValue structure filled with specified values. Uses the provided buffer as the

    
   
510
   * data buffer.

    
   
511
   * <p>

    
   
512
   * Column is split into two fields, family and qualifier.
509
   *
513
   *

    
   
514
   * @param buffer the bytes buffer to use
510
   * @param row row key
515
   * @param row row key
511
   * @param roffset row offset
516
   * @param roffset row offset
512
   * @param rlength row length
517
   * @param rlength row length
513
   * @param family family name
518
   * @param family family name
514
   * @param foffset family offset
519
   * @param foffset family offset
[+20] [20] 4 lines
[+20] static byte[] createEmptyByteArray(final int rlength, int flength,
519
   * @param timestamp version timestamp
524
   * @param timestamp version timestamp
520
   * @param type key type
525
   * @param type key type
521
   * @param value column value
526
   * @param value column value
522
   * @param voffset value offset
527
   * @param voffset value offset
523
   * @param vlength value length
528
   * @param vlength value length
524
   * @return The newly created byte array.
529
   * @throws IllegalArgumentException an illegal value was passed or there is insufficient space

    
   
530
   * remaining in the buffer
525
   */
531
   */
526
  static byte [] createByteArray(final byte [] row, final int roffset,
532
  public KeyValue(byte [] buffer,
527
      final int rlength, final byte [] family, final int foffset, int flength,
533
      final byte [] row, final int roffset, final int rlength,
528
      final byte [] qualifier, final int qoffset, int qlength,
534
      final byte [] family, final int foffset, final int flength,

    
   
535
      final byte [] qualifier, final int qoffset, final int qlength,
529
      final long timestamp, final Type type,
536
      final long timestamp, final Type type,
530
      final byte [] value, final int voffset, int vlength) {
537
      final byte [] value, final int voffset, final int vlength) {

    
   
538

   

    
   
539
    this(buffer, 0,

    
   
540
        row, roffset, rlength,

    
   
541
        family, foffset, flength,

    
   
542
        qualifier, qoffset, qlength,

    
   
543
        timestamp, type,

    
   
544
        value, voffset, vlength);

    
   
545
  }

    
   
546

   

    
   
547
  /**

    
   
548
   * Constructs KeyValue structure filled with specified values. Uses the provided buffer as the

    
   
549
   * data buffer.

    
   
550
   * <p>

    
   
551
   * Column is split into two fields, family and qualifier.

    
   
552
   *

    
   
553
   * @param buffer the bytes buffer to use

    
   
554
   * @param boffset buffer offset

    
   
555
   * @param row row key

    
   
556
   * @param roffset row offset

    
   
557
   * @param rlength row length

    
   
558
   * @param family family name

    
   
559
   * @param foffset family offset

    
   
560
   * @param flength family length

    
   
561
   * @param qualifier column qualifier

    
   
562
   * @param qoffset qualifier offset

    
   
563
   * @param qlength qualifier length

    
   
564
   * @param timestamp version timestamp

    
   
565
   * @param type key type

    
   
566
   * @param value column value

    
   
567
   * @param voffset value offset

    
   
568
   * @param vlength value length

    
   
569
   * @throws IllegalArgumentException an illegal value was passed or there is insufficient space

    
   
570
   * remaining in the buffer

    
   
571
   */

    
   
572
  public KeyValue(byte [] buffer, final int boffset,

    
   
573
      final byte [] row, final int roffset, final int rlength,

    
   
574
      final byte [] family, final int foffset, final int flength,

    
   
575
      final byte [] qualifier, final int qoffset, final int qlength,

    
   
576
      final long timestamp, final Type type,

    
   
577
      final byte [] value, final int voffset, final int vlength) {

    
   
578

   

    
   
579
    this.bytes  = buffer;

    
   
580
    this.length = writeByteArray(buffer, boffset,

    
   
581
        row, roffset, rlength,

    
   
582
        family, foffset, flength, qualifier, qoffset, qlength,

    
   
583
        timestamp, type, value, voffset, vlength);

    
   
584
    this.offset = boffset;

    
   
585
  }

    
   
586

   

    
   
587
  /**

    
   
588
   * Checks the parameters passed to a constructor.

    
   
589
   *

    
   
590
   * @param row row key

    
   
591
   * @param rlength row length

    
   
592
   * @param family family name

    
   
593
   * @param flength family length

    
   
594
   * @param qualifier column qualifier

    
   
595
   * @param qlength qualifier length

    
   
596
   * @param value column value

    
   
597
   * @param vlength value length

    
   
598
   *

    
   
599
   * @throws IllegalArgumentException an illegal value was passed

    
   
600
   */

    
   
601
  private static void checkParameters(final byte [] row, final int rlength,

    
   
602
      final byte [] family, int flength,

    
   
603
      final byte [] qualifier, int qlength,

    
   
604
      final byte [] value, int vlength)

    
   
605
          throws IllegalArgumentException {

    
   
606

   
531
    if (rlength > Short.MAX_VALUE) {
607
    if (rlength > Short.MAX_VALUE) {
532
      throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
608
      throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
533
    }
609
    }
534
    if (row == null) {
610
    if (row == null) {
535
      throw new IllegalArgumentException("Row is null");
611
      throw new IllegalArgumentException("Row is null");
[+20] [20] 7 lines
[+20] static byte[] createEmptyByteArray(final int rlength, int flength, [+] private static void checkParameters(final byte [] row, final int rlength,
543
    qlength = qualifier == null ? 0 : qlength;
619
    qlength = qualifier == null ? 0 : qlength;
544
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
620
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
545
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
621
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
546
    }
622
    }
547
    // Key length
623
    // Key length
548
    long longkeylength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
624
    long longKeyLength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
549
    if (longkeylength > Integer.MAX_VALUE) {
625
    if (longKeyLength > Integer.MAX_VALUE) {
550
      throw new IllegalArgumentException("keylength " + longkeylength + " > " +
626
      throw new IllegalArgumentException("keylength " + longKeyLength + " > " +
551
        Integer.MAX_VALUE);
627
          Integer.MAX_VALUE);
552
    }
628
    }
553
    int keylength = (int)longkeylength;

   
554
    // Value length
629
    // Value length
555
    vlength = value == null? 0 : vlength;
630
    vlength = value == null? 0 : vlength;
556
    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
631
    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
557
      throw new IllegalArgumentException("Valuer > " +
632
      throw new IllegalArgumentException("Value length " + vlength + " > " +
558
          HConstants.MAXIMUM_VALUE_LENGTH);
633
          HConstants.MAXIMUM_VALUE_LENGTH);
559
    }
634
    }

    
   
635
  }

    
   
636

   

    
   
637
  /**

    
   
638
   * Write KeyValue format into the provided byte array.

    
   
639
   *

    
   
640
   * @param buffer the bytes buffer to use

    
   
641
   * @param boffset buffer offset

    
   
642
   * @param row row key

    
   
643
   * @param roffset row offset

    
   
644
   * @param rlength row length

    
   
645
   * @param family family name

    
   
646
   * @param foffset family offset

    
   
647
   * @param flength family length

    
   
648
   * @param qualifier column qualifier

    
   
649
   * @param qoffset qualifier offset

    
   
650
   * @param qlength qualifier length

    
   
651
   * @param timestamp version timestamp

    
   
652
   * @param type key type

    
   
653
   * @param value column value

    
   
654
   * @param voffset value offset

    
   
655
   * @param vlength value length

    
   
656
   *

    
   
657
   * @return The number of useful bytes in the buffer.

    
   
658
   *

    
   
659
   * @throws IllegalArgumentException an illegal value was passed or there is insufficient space

    
   
660
   * remaining in the buffer

    
   
661
   */

    
   
662
  static int writeByteArray(byte [] buffer, final int boffset,

    
   
663
      final byte [] row, final int roffset, final int rlength,

    
   
664
      final byte [] family, final int foffset, int flength,

    
   
665
      final byte [] qualifier, final int qoffset, int qlength,

    
   
666
      final long timestamp, final Type type,

    
   
667
      final byte [] value, final int voffset, int vlength) {

    
   
668

   

    
   
669
    checkParameters(row, rlength, family, flength, qualifier, qlength, value, vlength);

    
   
670

   

    
   
671
    int keyLength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;

    
   
672
    int keyValueLength = KEYVALUE_INFRASTRUCTURE_SIZE + keyLength + vlength;

    
   
673
    if (keyValueLength > buffer.length - boffset) {

    
   
674
      throw new IllegalArgumentException("Buffer size " + (buffer.length - boffset) + " < " +

    
   
675
          keyValueLength);

    
   
676
    }

    
   
677

   

    
   
678
    // Write key, value and key row length.

    
   
679
    int pos = boffset;

    
   
680
    pos = Bytes.putInt(buffer, pos, keyLength);

    
   
681
    pos = Bytes.putInt(buffer, pos, vlength);

    
   
682
    pos = Bytes.putShort(buffer, pos, (short)(rlength & 0x0000ffff));

    
   
683
    pos = Bytes.putBytes(buffer, pos, row, roffset, rlength);

    
   
684
    pos = Bytes.putByte(buffer, pos, (byte) (flength & 0x0000ff));

    
   
685
    if (flength != 0) {

    
   
686
      pos = Bytes.putBytes(buffer, pos, family, foffset, flength);

    
   
687
    }

    
   
688
    if (qlength != 0) {

    
   
689
      pos = Bytes.putBytes(buffer, pos, qualifier, qoffset, qlength);

    
   
690
    }

    
   
691
    pos = Bytes.putLong(buffer, pos, timestamp);

    
   
692
    pos = Bytes.putByte(buffer, pos, type.getCode());

    
   
693
    if (value != null && value.length > 0) {

    
   
694
      pos = Bytes.putBytes(buffer, pos, value, voffset, vlength);

    
   
695
    }

    
   
696

   

    
   
697
    return keyValueLength;

    
   
698
  }

    
   
699

   

    
   
700
  /**

    
   
701
   * Write KeyValue format into a byte array.

    
   
702
   *

    
   
703
   * @param row row key

    
   
704
   * @param roffset row offset

    
   
705
   * @param rlength row length

    
   
706
   * @param family family name

    
   
707
   * @param foffset family offset

    
   
708
   * @param flength family length

    
   
709
   * @param qualifier column qualifier

    
   
710
   * @param qoffset qualifier offset

    
   
711
   * @param qlength qualifier length

    
   
712
   * @param timestamp version timestamp

    
   
713
   * @param type key type

    
   
714
   * @param value column value

    
   
715
   * @param voffset value offset

    
   
716
   * @param vlength value length

    
   
717
   * @return The newly created byte array.

    
   
718
   */

    
   
719
  static byte [] createByteArray(final byte [] row, final int roffset,

    
   
720
      final int rlength, final byte [] family, final int foffset, int flength,

    
   
721
      final byte [] qualifier, final int qoffset, int qlength,

    
   
722
      final long timestamp, final Type type,

    
   
723
      final byte [] value, final int voffset, int vlength) {

    
   
724

   

    
   
725
    checkParameters(row, rlength, family, flength, qualifier, qlength, value, vlength);
560

    
   
726

   
561
    // Allocate right-sized byte array.
727
    // Allocate right-sized byte array.
562
    byte [] bytes = new byte[KEYVALUE_INFRASTRUCTURE_SIZE + keylength + vlength];
728
    int keyLength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;

    
   
729
    byte [] bytes = new byte[KEYVALUE_INFRASTRUCTURE_SIZE + keyLength + vlength];
563
    // Write key, value and key row length.
730
    // Write key, value and key row length.
564
    int pos = 0;
731
    int pos = 0;
565
    pos = Bytes.putInt(bytes, pos, keylength);
732
    pos = Bytes.putInt(bytes, pos, keyLength);
566
    pos = Bytes.putInt(bytes, pos, vlength);
733
    pos = Bytes.putInt(bytes, pos, vlength);
567
    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
734
    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
568
    pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
735
    pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
569
    pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
736
    pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
570
    if(flength != 0) {
737
    if(flength != 0) {
[+20] [20] 434 lines
[+20] [+] public boolean updateLatestStamp(final byte [] now) {
1005
    System.arraycopy(getBuffer(), o, result, 0, l);
1172
    System.arraycopy(getBuffer(), o, result, 0, l);
1006
    return result;
1173
    return result;
1007
  }
1174
  }
1008

    
   
1175

   
1009
  /**
1176
  /**

    
   
1177
   * Returns the value wrapped in a new <code>ByteBuffer</code>.

    
   
1178
   *

    
   
1179
   * @return the value

    
   
1180
   */

    
   
1181
  public ByteBuffer getValueAsByteBuffer() {

    
   
1182
    return ByteBuffer.wrap(getBuffer(), getValueOffset(), getValueLength());

    
   
1183
  }

    
   
1184

   

    
   
1185
  /**

    
   
1186
   * Loads this object's value into the provided <code>ByteBuffer</code>.

    
   
1187
   * <p>

    
   
1188
   * Does not clear or flip the buffer.

    
   
1189
   *

    
   
1190
   * @param dst the buffer where to write the value

    
   
1191
   *

    
   
1192
   * @throws BufferOverflowException if there is insufficient space remaining in the buffer

    
   
1193
   */

    
   
1194
  public void loadValue(ByteBuffer dst) throws BufferOverflowException {

    
   
1195
    dst.put(getBuffer(), getValueOffset(), getValueLength());

    
   
1196
  }

    
   
1197

   

    
   
1198
  /**
1010
   * Primarily for use client-side.  Returns the row of this KeyValue in a new
1199
   * Primarily for use client-side.  Returns the row of this KeyValue in a new
1011
   * byte array.<p>
1200
   * byte array.<p>
1012
   *
1201
   *
1013
   * If server-side, use {@link #getBuffer()} with appropriate offsets and
1202
   * If server-side, use {@link #getBuffer()} with appropriate offsets and
1014
   * lengths instead.
1203
   * lengths instead.
[+20] [20] 260 lines
[+20] [+] public boolean matchingColumnNoDelimiter(final byte [] column) {
1275
   * @param family column family
1464
   * @param family column family
1276
   * @param qualifier column qualifier
1465
   * @param qualifier column qualifier
1277
   * @return True if column matches
1466
   * @return True if column matches
1278
   */
1467
   */
1279
  public boolean matchingColumn(final byte[] family, final byte[] qualifier) {
1468
  public boolean matchingColumn(final byte[] family, final byte[] qualifier) {

    
   
1469
    return matchingColumn(family, 0, family == null ? 0 : family.length,

    
   
1470
        qualifier, 0, qualifier == null ? 0 : qualifier.length);

    
   
1471
  }

    
   
1472

   

    
   
1473
  /**

    
   
1474
   * Checks if column matches.

    
   
1475
   *

    
   
1476
   * @param family family name

    
   
1477
   * @param foffset family offset

    
   
1478
   * @param flength family length

    
   
1479
   * @param qualifier column qualifier

    
   
1480
   * @param qoffset qualifier offset

    
   
1481
   * @param qlength qualifier length

    
   
1482
   *

    
   
1483
   * @return True if column matches

    
   
1484
   */

    
   
1485
  public boolean matchingColumn(final byte [] family, final int foffset, final int flength,

    
   
1486
      final byte [] qualifier, final int qoffset, final int qlength) {
1280
    int rl = getRowLength();
1487
    int rl = getRowLength();
1281
    int o = getFamilyOffset(rl);
1488
    int o = getFamilyOffset(rl);
1282
    int fl = getFamilyLength(o);
1489
    int fl = getFamilyLength(o);
1283
    int ql = getQualifierLength(rl,fl);
1490
    if (!Bytes.equals(family, foffset, flength, this.bytes, o, fl)) {
1284
    if (!Bytes.equals(family, 0, family.length, this.bytes, o, fl)) {

   
1285
      return false;
1491
      return false;
1286
    }
1492
    }
1287
    if (qualifier == null || qualifier.length == 0) {
1493

   
1288
      if (ql == 0) {
1494
    int ql = getQualifierLength(rl, fl);
1289
        return true;
1495
    if (qualifier == null || qlength == 0) {
1290
      }
1496
      return (ql == 0);
1291
      return false;

   
1292
    }
1497
    }
1293
    return Bytes.equals(qualifier, 0, qualifier.length,
1498
    return Bytes.equals(qualifier, qoffset, qlength, this.bytes, o + fl, ql);
1294
        this.bytes, o + fl, ql);

   
1295
  }
1499
  }
1296

    
   
1500

   
1297
  /**
1501
  /**
1298
   * @param left
1502
   * @param left
1299
   * @param loffset
1503
   * @param loffset
[+20] [20] 519 lines
[+20] [+] public static KeyValue createFirstOnRow(final byte [] row,
1819
        HConstants.LATEST_TIMESTAMP, Type.Maximum, null, 0, 0);
2023
        HConstants.LATEST_TIMESTAMP, Type.Maximum, null, 0, 0);
1820
  }
2024
  }
1821

    
   
2025

   
1822
  /**
2026
  /**
1823
   * Create a KeyValue for the specified row, family and qualifier that would be
2027
   * Create a KeyValue for the specified row, family and qualifier that would be

    
   
2028
   * smaller than all other possible KeyValues that have the same row,

    
   
2029
   * family, qualifier.

    
   
2030
   * Used for seeking.

    
   
2031
   *

    
   
2032
   * @param buffer the buffer to use for the new <code>KeyValue</code> object

    
   
2033
   * @param row the value key

    
   
2034
   * @param family family name

    
   
2035
   * @param qualifier column qualifier

    
   
2036
   *

    
   
2037
   * @return First possible key on passed Row, Family, Qualifier.

    
   
2038
   *

    
   
2039
   * @throws IllegalArgumentException The resulting <code>KeyValue</code> object would be larger

    
   
2040
   * than the provided buffer or than <code>Integer.MAX_VALUE</code>

    
   
2041
   */

    
   
2042
  public static KeyValue createFirstOnRow(byte [] buffer, final byte [] row,

    
   
2043
      final byte [] family, final byte [] qualifier)

    
   
2044
          throws IllegalArgumentException {

    
   
2045

   

    
   
2046
    return createFirstOnRow(buffer, 0, row, 0, row.length,

    
   
2047
        family, 0, family.length,

    
   
2048
        qualifier, 0, qualifier.length);

    
   
2049
  }

    
   
2050

   

    
   
2051
  /**

    
   
2052
   * Create a KeyValue for the specified row, family and qualifier that would be

    
   
2053
   * smaller than all other possible KeyValues that have the same row,

    
   
2054
   * family, qualifier.

    
   
2055
   * Used for seeking.

    
   
2056
   *

    
   
2057
   * @param buffer the buffer to use for the new <code>KeyValue</code> object

    
   
2058
   * @param boffset buffer offset

    
   
2059
   * @param row the value key

    
   
2060
   * @param roffset row offset

    
   
2061
   * @param rlength row length

    
   
2062
   * @param family family name

    
   
2063
   * @param foffset family offset

    
   
2064
   * @param flength family length

    
   
2065
   * @param qualifier column qualifier

    
   
2066
   * @param qoffset qualifier offset

    
   
2067
   * @param qlength qualifier length

    
   
2068
   *

    
   
2069
   * @return First possible key on passed Row, Family, Qualifier.

    
   
2070
   *

    
   
2071
   * @throws IllegalArgumentException The resulting <code>KeyValue</code> object would be larger

    
   
2072
   * than the provided buffer or than <code>Integer.MAX_VALUE</code>

    
   
2073
   */

    
   
2074
  public static KeyValue createFirstOnRow(byte [] buffer, final int boffset,

    
   
2075
      final byte [] row, final int roffset, final int rlength,

    
   
2076
      final byte [] family, final int foffset, final int flength,

    
   
2077
      final byte [] qualifier, final int qoffset, final int qlength)

    
   
2078
          throws IllegalArgumentException {

    
   
2079

   

    
   
2080
    long lLength = KeyValue.KEY_INFRASTRUCTURE_SIZE + row.length + flength + qlength +

    
   
2081
        KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE;

    
   
2082

   

    
   
2083
    if (lLength > Integer.MAX_VALUE) {

    
   
2084
      throw new IllegalArgumentException("KeyValue length " + lLength + " > " + Integer.MAX_VALUE);

    
   
2085
    }

    
   
2086
    int iLength = (int) lLength;

    
   
2087
    if (buffer.length - boffset < iLength) {

    
   
2088
      throw new IllegalArgumentException("Buffer size " + (buffer.length - boffset) + " < " +

    
   
2089
          iLength);

    
   
2090
    }

    
   
2091
    return new KeyValue(buffer, boffset,

    
   
2092
        row, roffset, rlength,

    
   
2093
        family, foffset, flength,

    
   
2094
        qualifier, qoffset, qlength,

    
   
2095
        HConstants.LATEST_TIMESTAMP, KeyValue.Type.Maximum,

    
   
2096
        null, 0, 0);

    
   
2097
  }

    
   
2098

   

    
   
2099
  /**

    
   
2100
   * Create a KeyValue for the specified row, family and qualifier that would be
1824
   * larger than or equal to all other possible KeyValues that have the same
2101
   * larger than or equal to all other possible KeyValues that have the same
1825
   * row, family, qualifier.
2102
   * row, family, qualifier.
1826
   * Used for reseeking.
2103
   * Used for reseeking.
1827
   * @param row row key
2104
   * @param row row key
1828
   * @param roffset row offset
2105
   * @param roffset row offset
[+20] [20] 426 lines
src/main/java/org/apache/hadoop/hbase/client/Result.java
Revision df0b3ef New Change
 
src/test/java/org/apache/hadoop/hbase/TestKeyValue.java
Revision fae6902 New Change
 
src/test/java/org/apache/hadoop/hbase/client/TestResult.java
Revision f9e29c2 New Change
 
  1. src/main/java/org/apache/hadoop/hbase/KeyValue.java: Loading...
  2. src/main/java/org/apache/hadoop/hbase/client/Result.java: Loading...
  3. src/test/java/org/apache/hadoop/hbase/TestKeyValue.java: Loading...
  4. src/test/java/org/apache/hadoop/hbase/client/TestResult.java: Loading...