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.

Changes between revision 3 and 4

1 2 3 4
1 2 3 4

  1. src/main/java/org/apache/hadoop/hbase/KeyValue.java: Loading...
  2. src/main/java/org/apache/hadoop/hbase/client/Result.java: Loading...
src/main/java/org/apache/hadoop/hbase/KeyValue.java
Diff Revision 3 Diff Revision 4
[20] 507 lines
[+20] [+] static byte[] createEmptyByteArray(final int rlength, int flength,
508
    // Qualifier length
508
    // Qualifier length
509
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
509
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
510
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
510
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
511
    }
511
    }
512
    // Key length
512
    // Key length
513
    long longkeylength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
513
    long longkeylength = getKeyDataStructureSize(rlength, flength, qlength);
514
    if (longkeylength > Integer.MAX_VALUE) {
514
    if (longkeylength > Integer.MAX_VALUE) {
515
      throw new IllegalArgumentException("keylength " + longkeylength + " > " +
515
      throw new IllegalArgumentException("keylength " + longkeylength + " > " +
516
        Integer.MAX_VALUE);
516
        Integer.MAX_VALUE);
517
    }
517
    }
518
    int keylength = (int)longkeylength;
518
    int keylength = (int)longkeylength;
519
    // Value length
519
    // Value length
520
    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
520
    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
521
      throw new IllegalArgumentException("Valuer > " +
521
      throw new IllegalArgumentException("Valuer > " +
522
          HConstants.MAXIMUM_VALUE_LENGTH);
522
          HConstants.MAXIMUM_VALUE_LENGTH);
523
    }
523
    }
524

    
   
524

   
525
    // Allocate right-sized byte array.
525
    // Allocate right-sized byte array.
526
    byte [] bytes = new byte[KEYVALUE_INFRASTRUCTURE_SIZE + keylength + vlength];
526
    byte [] bytes =

    
   
527
        new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength)];
527
    // Write the correct size markers
528
    // Write the correct size markers
528
    int pos = 0;
529
    int pos = 0;
529
    pos = Bytes.putInt(bytes, pos, keylength);
530
    pos = Bytes.putInt(bytes, pos, keylength);
530
    pos = Bytes.putInt(bytes, pos, vlength);
531
    pos = Bytes.putInt(bytes, pos, vlength);
531
    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
532
    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
[+20] [20] 4 lines
[+20] static byte[] createEmptyByteArray(final int rlength, int flength,
536
    pos = Bytes.putByte(bytes, pos, type.getCode());
537
    pos = Bytes.putByte(bytes, pos, type.getCode());
537
    return bytes;
538
    return bytes;
538
  }
539
  }
539

    
   
540

   
540
  /**
541
  /**
541
   * Constructs KeyValue structure filled with specified values. Uses the provided buffer as the
542
   * Constructs KeyValue structure filled with specified values. Uses the provided buffer as its
542
   * data buffer.
543
   * backing data buffer.
543
   * <p>
544
   * <p>
544
   * Column is split into two fields, family and qualifier.
545
   * Column is split into two fields, family and qualifier.
545
   *
546
   *
546
   * @param buffer the bytes buffer to use
547
   * @param buffer the bytes buffer to use
547
   * @param row row key
548
   * @param row row key
[+20] [20] 103 lines
[+20] [+] private static void checkParameters(final byte [] row, final int rlength,
651
    qlength = qualifier == null ? 0 : qlength;
652
    qlength = qualifier == null ? 0 : qlength;
652
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
653
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
653
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
654
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
654
    }
655
    }
655
    // Key length
656
    // Key length
656
    long longKeyLength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
657
    long longKeyLength = getKeyDataStructureSize(rlength, flength, qlength);
657
    if (longKeyLength > Integer.MAX_VALUE) {
658
    if (longKeyLength > Integer.MAX_VALUE) {
658
      throw new IllegalArgumentException("keylength " + longKeyLength + " > " +
659
      throw new IllegalArgumentException("keylength " + longKeyLength + " > " +
659
          Integer.MAX_VALUE);
660
          Integer.MAX_VALUE);
660
    }
661
    }
661
    // Value length
662
    // Value length
[+20] [20] 36 lines
[+20] [+] static int writeByteArray(byte [] buffer, final int boffset,
698
      final long timestamp, final Type type,
699
      final long timestamp, final Type type,
699
      final byte [] value, final int voffset, int vlength) {
700
      final byte [] value, final int voffset, int vlength) {
700

    
   
701

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

    
   
703

   
703
    int keyLength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
704
    int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
704
    int keyValueLength = KEYVALUE_INFRASTRUCTURE_SIZE + keyLength + vlength;
705
    int keyValueLength = (int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength);
705
    if (keyValueLength > buffer.length - boffset) {
706
    if (keyValueLength > buffer.length - boffset) {
706
      throw new IllegalArgumentException("Buffer size " + (buffer.length - boffset) + " < " +
707
      throw new IllegalArgumentException("Buffer size " + (buffer.length - boffset) + " < " +
707
          keyValueLength);
708
          keyValueLength);
708
    }
709
    }
709

    
   
710

   
[+20] [20] 45 lines
[+20] static int writeByteArray(byte [] buffer, final int boffset,
755
      final byte [] value, final int voffset, int vlength) {
756
      final byte [] value, final int voffset, int vlength) {
756

    
   
757

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

    
   
759

   
759
    // Allocate right-sized byte array.
760
    // Allocate right-sized byte array.
760
    int keyLength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
761
    int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
761
    byte [] bytes = new byte[KEYVALUE_INFRASTRUCTURE_SIZE + keyLength + vlength];
762
    byte [] bytes =

    
   
763
        new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength)];
762
    // Write key, value and key row length.
764
    // Write key, value and key row length.
763
    int pos = 0;
765
    int pos = 0;
764
    pos = Bytes.putInt(bytes, pos, keyLength);
766
    pos = Bytes.putInt(bytes, pos, keyLength);
765
    pos = Bytes.putInt(bytes, pos, vlength);
767
    pos = Bytes.putInt(bytes, pos, vlength);
766
    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
768
    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
[+20] [20] 342 lines
[+20] [+] public int getQualifierLength() {
1109

    
   
1111

   
1110
  /**
1112
  /**
1111
   * @return Qualifier length
1113
   * @return Qualifier length
1112
   */
1114
   */
1113
  public int getQualifierLength(int rlength, int flength) {
1115
  public int getQualifierLength(int rlength, int flength) {
1114
    return getKeyLength() -
1116
    return getKeyLength() - (int) getKeyDataStructureSize(rlength, flength, 0);
1115
      (KEY_INFRASTRUCTURE_SIZE + rlength + flength);

   
1116
  }
1117
  }
1117

    
   
1118

   
1118
  /**
1119
  /**
1119
   * @return Column (family + qualifier) length
1120
   * @return Column (family + qualifier) length
1120
   */
1121
   */
[+20] [20] 1443 lines
src/main/java/org/apache/hadoop/hbase/client/Result.java
Diff Revision 3 Diff Revision 4
 
  1. src/main/java/org/apache/hadoop/hbase/KeyValue.java: Loading...
  2. src/main/java/org/apache/hadoop/hbase/client/Result.java: Loading...