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 9ae9e02 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] 135 lines
[+20] [+] public static KeyComparator getRowComparator(byte [] tableName) {
165

    
   
166

   
166
  // Size of the length ints in a KeyValue datastructure.
167
  // Size of the length ints in a KeyValue datastructure.
167
  public static final int KEYVALUE_INFRASTRUCTURE_SIZE = ROW_OFFSET;
168
  public static final int KEYVALUE_INFRASTRUCTURE_SIZE = ROW_OFFSET;
168

    
   
169

   
169
  /**
170
  /**

    
   
171
   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided

    
   
172
   * characteristics would take up for its underlying data structure.

    
   
173
   *

    
   
174
   * @param rlength row length

    
   
175
   * @param flength family length

    
   
176
   * @param qlength qualifier length

    
   
177
   * @param vlength value length

    
   
178
   *

    
   
179
   * @return the <code>KeyValue</code> data structure length

    
   
180
   */

    
   
181
  public static long getKeyValueDataStructureSize(int rlength,

    
   
182
      int flength, int qlength, int vlength) {

    
   
183
    return KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE +

    
   
184
            getKeyDataStructureSize(rlength, flength, qlength) + vlength;

    
   
185
  }

    
   
186

   

    
   
187
  /**

    
   
188
   * Computes the number of bytes that a <code>KeyValue</code> instance with the provided

    
   
189
   * characteristics would take up in its underlying data structure for the key.

    
   
190
   *

    
   
191
   * @param rlength row length

    
   
192
   * @param flength family length

    
   
193
   * @param qlength qualifier length

    
   
194
   *

    
   
195
   * @return the key data structure length

    
   
196
   */

    
   
197
  public static long getKeyDataStructureSize(int rlength, int flength, int qlength) {

    
   
198
    return KeyValue.KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;

    
   
199
  }

    
   
200

   

    
   
201
  /**
170
   * Key type.
202
   * Key type.
171
   * Has space for other key types to be added later.  Cannot rely on
203
   * Has space for other key types to be added later.  Cannot rely on
172
   * enum ordinals . They change if item is removed or moved.  Do our own codes.
204
   * enum ordinals . They change if item is removed or moved.  Do our own codes.
173
   */
205
   */
174
  public static enum Type {
206
  public static enum Type {
[+20] [20] 301 lines
[+20] [+] static byte[] createEmptyByteArray(final int rlength, int flength,
476
    // Qualifier length
508
    // Qualifier length
477
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
509
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
478
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
510
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
479
    }
511
    }
480
    // Key length
512
    // Key length
481
    long longkeylength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
513
    long longkeylength = getKeyDataStructureSize(rlength, flength, qlength);
482
    if (longkeylength > Integer.MAX_VALUE) {
514
    if (longkeylength > Integer.MAX_VALUE) {
483
      throw new IllegalArgumentException("keylength " + longkeylength + " > " +
515
      throw new IllegalArgumentException("keylength " + longkeylength + " > " +
484
        Integer.MAX_VALUE);
516
        Integer.MAX_VALUE);
485
    }
517
    }
486
    int keylength = (int)longkeylength;
518
    int keylength = (int)longkeylength;
487
    // Value length
519
    // Value length
488
    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
520
    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
489
      throw new IllegalArgumentException("Valuer > " +
521
      throw new IllegalArgumentException("Valuer > " +
490
          HConstants.MAXIMUM_VALUE_LENGTH);
522
          HConstants.MAXIMUM_VALUE_LENGTH);
491
    }
523
    }
492

    
   
524

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

    
   
527
        new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength)];
495
    // Write the correct size markers
528
    // Write the correct size markers
496
    int pos = 0;
529
    int pos = 0;
497
    pos = Bytes.putInt(bytes, pos, keylength);
530
    pos = Bytes.putInt(bytes, pos, keylength);
498
    pos = Bytes.putInt(bytes, pos, vlength);
531
    pos = Bytes.putInt(bytes, pos, vlength);
499
    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,
504
    pos = Bytes.putByte(bytes, pos, type.getCode());
537
    pos = Bytes.putByte(bytes, pos, type.getCode());
505
    return bytes;
538
    return bytes;
506
  }
539
  }
507

    
   
540

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

    
   
543
   * backing data buffer.

    
   
544
   * <p>

    
   
545
   * Column is split into two fields, family and qualifier.
510
   *
546
   *

    
   
547
   * @param buffer the bytes buffer to use
511
   * @param row row key
548
   * @param row row key
512
   * @param roffset row offset
549
   * @param roffset row offset
513
   * @param rlength row length
550
   * @param rlength row length
514
   * @param family family name
551
   * @param family family name
515
   * @param foffset family offset
552
   * @param foffset family offset
[+20] [20] 4 lines
[+20] static byte[] createEmptyByteArray(final int rlength, int flength,
520
   * @param timestamp version timestamp
557
   * @param timestamp version timestamp
521
   * @param type key type
558
   * @param type key type
522
   * @param value column value
559
   * @param value column value
523
   * @param voffset value offset
560
   * @param voffset value offset
524
   * @param vlength value length
561
   * @param vlength value length
525
   * @return The newly created byte array.
562
   * @throws IllegalArgumentException an illegal value was passed or there is insufficient space

    
   
563
   * remaining in the buffer
526
   */
564
   */
527
  static byte [] createByteArray(final byte [] row, final int roffset,
565
  public KeyValue(byte [] buffer,
528
      final int rlength, final byte [] family, final int foffset, int flength,
566
      final byte [] row, final int roffset, final int rlength,
529
      final byte [] qualifier, final int qoffset, int qlength,
567
      final byte [] family, final int foffset, final int flength,

    
   
568
      final byte [] qualifier, final int qoffset, final int qlength,
530
      final long timestamp, final Type type,
569
      final long timestamp, final Type type,
531
      final byte [] value, final int voffset, int vlength) {
570
      final byte [] value, final int voffset, final int vlength) {

    
   
571

   

    
   
572
    this(buffer, 0,

    
   
573
        row, roffset, rlength,

    
   
574
        family, foffset, flength,

    
   
575
        qualifier, qoffset, qlength,

    
   
576
        timestamp, type,

    
   
577
        value, voffset, vlength);

    
   
578
  }

    
   
579

   

    
   
580
  /**

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

    
   
582
   * data buffer.

    
   
583
   * <p>

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

    
   
585
   *

    
   
586
   * @param buffer the bytes buffer to use

    
   
587
   * @param boffset buffer offset

    
   
588
   * @param row row key

    
   
589
   * @param roffset row offset

    
   
590
   * @param rlength row length

    
   
591
   * @param family family name

    
   
592
   * @param foffset family offset

    
   
593
   * @param flength family length

    
   
594
   * @param qualifier column qualifier

    
   
595
   * @param qoffset qualifier offset

    
   
596
   * @param qlength qualifier length

    
   
597
   * @param timestamp version timestamp

    
   
598
   * @param type key type

    
   
599
   * @param value column value

    
   
600
   * @param voffset value offset

    
   
601
   * @param vlength value length

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

    
   
603
   * remaining in the buffer

    
   
604
   */

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

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

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

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

    
   
609
      final long timestamp, final Type type,

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

    
   
611

   

    
   
612
    this.bytes  = buffer;

    
   
613
    this.length = writeByteArray(buffer, boffset,

    
   
614
        row, roffset, rlength,

    
   
615
        family, foffset, flength, qualifier, qoffset, qlength,

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

    
   
617
    this.offset = boffset;

    
   
618
  }

    
   
619

   

    
   
620
  /**

    
   
621
   * Checks the parameters passed to a constructor.

    
   
622
   *

    
   
623
   * @param row row key

    
   
624
   * @param rlength row length

    
   
625
   * @param family family name

    
   
626
   * @param flength family length

    
   
627
   * @param qualifier column qualifier

    
   
628
   * @param qlength qualifier length

    
   
629
   * @param value column value

    
   
630
   * @param vlength value length

    
   
631
   *

    
   
632
   * @throws IllegalArgumentException an illegal value was passed

    
   
633
   */

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

    
   
635
      final byte [] family, int flength,

    
   
636
      final byte [] qualifier, int qlength,

    
   
637
      final byte [] value, int vlength)

    
   
638
          throws IllegalArgumentException {

    
   
639

   
532
    if (rlength > Short.MAX_VALUE) {
640
    if (rlength > Short.MAX_VALUE) {
533
      throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
641
      throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
534
    }
642
    }
535
    if (row == null) {
643
    if (row == null) {
536
      throw new IllegalArgumentException("Row is null");
644
      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,
544
    qlength = qualifier == null ? 0 : qlength;
652
    qlength = qualifier == null ? 0 : qlength;
545
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
653
    if (qlength > Integer.MAX_VALUE - rlength - flength) {
546
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
654
      throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
547
    }
655
    }
548
    // Key length
656
    // Key length
549
    long longkeylength = KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
657
    long longKeyLength = getKeyDataStructureSize(rlength, flength, qlength);
550
    if (longkeylength > Integer.MAX_VALUE) {
658
    if (longKeyLength > Integer.MAX_VALUE) {
551
      throw new IllegalArgumentException("keylength " + longkeylength + " > " +
659
      throw new IllegalArgumentException("keylength " + longKeyLength + " > " +
552
        Integer.MAX_VALUE);
660
          Integer.MAX_VALUE);
553
    }
661
    }
554
    int keylength = (int)longkeylength;

   
555
    // Value length
662
    // Value length
556
    vlength = value == null? 0 : vlength;
663
    vlength = value == null? 0 : vlength;
557
    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
664
    if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) { // FindBugs INT_VACUOUS_COMPARISON
558
      throw new IllegalArgumentException("Valuer > " +
665
      throw new IllegalArgumentException("Value length " + vlength + " > " +
559
          HConstants.MAXIMUM_VALUE_LENGTH);
666
          HConstants.MAXIMUM_VALUE_LENGTH);
560
    }
667
    }

    
   
668
  }

    
   
669

   

    
   
670
  /**

    
   
671
   * Write KeyValue format into the provided byte array.

    
   
672
   *

    
   
673
   * @param buffer the bytes buffer to use

    
   
674
   * @param boffset buffer offset

    
   
675
   * @param row row key

    
   
676
   * @param roffset row offset

    
   
677
   * @param rlength row length

    
   
678
   * @param family family name

    
   
679
   * @param foffset family offset

    
   
680
   * @param flength family length

    
   
681
   * @param qualifier column qualifier

    
   
682
   * @param qoffset qualifier offset

    
   
683
   * @param qlength qualifier length

    
   
684
   * @param timestamp version timestamp

    
   
685
   * @param type key type

    
   
686
   * @param value column value

    
   
687
   * @param voffset value offset

    
   
688
   * @param vlength value length

    
   
689
   *

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

    
   
691
   *

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

    
   
693
   * remaining in the buffer

    
   
694
   */

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

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

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

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

    
   
699
      final long timestamp, final Type type,

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

    
   
701

   

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

    
   
703

   

    
   
704
    int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);

    
   
705
    int keyValueLength = (int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength);

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

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

    
   
708
          keyValueLength);

    
   
709
    }

    
   
710

   

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

    
   
712
    int pos = boffset;

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

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

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

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

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

    
   
718
    if (flength != 0) {

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

    
   
720
    }

    
   
721
    if (qlength != 0) {

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

    
   
723
    }

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

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

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

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

    
   
728
    }

    
   
729

   

    
   
730
    return keyValueLength;

    
   
731
  }

    
   
732

   

    
   
733
  /**

    
   
734
   * Write KeyValue format into a byte array.

    
   
735
   *

    
   
736
   * @param row row key

    
   
737
   * @param roffset row offset

    
   
738
   * @param rlength row length

    
   
739
   * @param family family name

    
   
740
   * @param foffset family offset

    
   
741
   * @param flength family length

    
   
742
   * @param qualifier column qualifier

    
   
743
   * @param qoffset qualifier offset

    
   
744
   * @param qlength qualifier length

    
   
745
   * @param timestamp version timestamp

    
   
746
   * @param type key type

    
   
747
   * @param value column value

    
   
748
   * @param voffset value offset

    
   
749
   * @param vlength value length

    
   
750
   * @return The newly created byte array.

    
   
751
   */

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

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

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

    
   
755
      final long timestamp, final Type type,

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

    
   
757

   

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

    
   
759

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

    
   
762
    byte [] bytes =

    
   
763
        new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength)];
564
    // Write key, value and key row length.
764
    // Write key, value and key row length.
565
    int pos = 0;
765
    int pos = 0;
566
    pos = Bytes.putInt(bytes, pos, keylength);
766
    pos = Bytes.putInt(bytes, pos, keyLength);
567
    pos = Bytes.putInt(bytes, pos, vlength);
767
    pos = Bytes.putInt(bytes, pos, vlength);
568
    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
768
    pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
569
    pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
769
    pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
570
    pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
770
    pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
571
    if(flength != 0) {
771
    if(flength != 0) {
[+20] [20] 339 lines
[+20] [+] public int getQualifierLength() {
911

    
   
1111

   
912
  /**
1112
  /**
913
   * @return Qualifier length
1113
   * @return Qualifier length
914
   */
1114
   */
915
  public int getQualifierLength(int rlength, int flength) {
1115
  public int getQualifierLength(int rlength, int flength) {
916
    return getKeyLength() -
1116
    return getKeyLength() - (int) getKeyDataStructureSize(rlength, flength, 0);
917
      (KEY_INFRASTRUCTURE_SIZE + rlength + flength);

   
918
  }
1117
  }
919

    
   
1118

   
920
  /**
1119
  /**
921
   * @return Column (family + qualifier) length
1120
   * @return Column (family + qualifier) length
922
   */
1121
   */
[+20] [20] 83 lines
[+20] [+] public boolean updateLatestStamp(final byte [] now) {
1006
    System.arraycopy(getBuffer(), o, result, 0, l);
1205
    System.arraycopy(getBuffer(), o, result, 0, l);
1007
    return result;
1206
    return result;
1008
  }
1207
  }
1009

    
   
1208

   
1010
  /**
1209
  /**

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

    
   
1211
   *

    
   
1212
   * @return the value

    
   
1213
   */

    
   
1214
  public ByteBuffer getValueAsByteBuffer() {

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

    
   
1216
  }

    
   
1217

   

    
   
1218
  /**

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

    
   
1220
   * <p>

    
   
1221
   * Does not clear or flip the buffer.

    
   
1222
   *

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

    
   
1224
   *

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

    
   
1226
   */

    
   
1227
  public void loadValue(ByteBuffer dst) throws BufferOverflowException {

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

    
   
1229
  }

    
   
1230

   

    
   
1231
  /**
1011
   * Primarily for use client-side.  Returns the row of this KeyValue in a new
1232
   * Primarily for use client-side.  Returns the row of this KeyValue in a new
1012
   * byte array.<p>
1233
   * byte array.<p>
1013
   *
1234
   *
1014
   * If server-side, use {@link #getBuffer()} with appropriate offsets and
1235
   * If server-side, use {@link #getBuffer()} with appropriate offsets and
1015
   * lengths instead.
1236
   * lengths instead.
[+20] [20] 260 lines
[+20] [+] public boolean matchingColumnNoDelimiter(final byte [] column) {
1276
   * @param family column family
1497
   * @param family column family
1277
   * @param qualifier column qualifier
1498
   * @param qualifier column qualifier
1278
   * @return True if column matches
1499
   * @return True if column matches
1279
   */
1500
   */
1280
  public boolean matchingColumn(final byte[] family, final byte[] qualifier) {
1501
  public boolean matchingColumn(final byte[] family, final byte[] qualifier) {

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

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

    
   
1504
  }

    
   
1505

   

    
   
1506
  /**

    
   
1507
   * Checks if column matches.

    
   
1508
   *

    
   
1509
   * @param family family name

    
   
1510
   * @param foffset family offset

    
   
1511
   * @param flength family length

    
   
1512
   * @param qualifier column qualifier

    
   
1513
   * @param qoffset qualifier offset

    
   
1514
   * @param qlength qualifier length

    
   
1515
   *

    
   
1516
   * @return True if column matches

    
   
1517
   */

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

    
   
1519
      final byte [] qualifier, final int qoffset, final int qlength) {
1281
    int rl = getRowLength();
1520
    int rl = getRowLength();
1282
    int o = getFamilyOffset(rl);
1521
    int o = getFamilyOffset(rl);
1283
    int fl = getFamilyLength(o);
1522
    int fl = getFamilyLength(o);
1284
    int ql = getQualifierLength(rl,fl);
1523
    if (!Bytes.equals(family, foffset, flength, this.bytes, o, fl)) {
1285
    if (!Bytes.equals(family, 0, family.length, this.bytes, o, fl)) {

   
1286
      return false;
1524
      return false;
1287
    }
1525
    }
1288
    if (qualifier == null || qualifier.length == 0) {
1526

   
1289
      if (ql == 0) {
1527
    int ql = getQualifierLength(rl, fl);
1290
        return true;
1528
    if (qualifier == null || qlength == 0) {
1291
      }
1529
      return (ql == 0);
1292
      return false;

   
1293
    }
1530
    }
1294
    return Bytes.equals(qualifier, 0, qualifier.length,
1531
    return Bytes.equals(qualifier, qoffset, qlength, this.bytes, o + fl, ql);
1295
        this.bytes, o + fl, ql);

   
1296
  }
1532
  }
1297

    
   
1533

   
1298
  /**
1534
  /**
1299
   * @param left
1535
   * @param left
1300
   * @param loffset
1536
   * @param loffset
[+20] [20] 519 lines
[+20] [+] public static KeyValue createFirstOnRow(final byte [] row,
1820
        HConstants.LATEST_TIMESTAMP, Type.Maximum, null, 0, 0);
2056
        HConstants.LATEST_TIMESTAMP, Type.Maximum, null, 0, 0);
1821
  }
2057
  }
1822

    
   
2058

   
1823
  /**
2059
  /**
1824
   * Create a KeyValue for the specified row, family and qualifier that would be
2060
   * Create a KeyValue for the specified row, family and qualifier that would be

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

    
   
2062
   * family, qualifier.

    
   
2063
   * Used for seeking.

    
   
2064
   *

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

    
   
2066
   * @param row the value key

    
   
2067
   * @param family family name

    
   
2068
   * @param qualifier column qualifier

    
   
2069
   *

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

    
   
2071
   *

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

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

    
   
2074
   */

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

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

    
   
2077
          throws IllegalArgumentException {

    
   
2078

   

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

    
   
2080
        family, 0, family.length,

    
   
2081
        qualifier, 0, qualifier.length);

    
   
2082
  }

    
   
2083

   

    
   
2084
  /**

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

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

    
   
2087
   * family, qualifier.

    
   
2088
   * Used for seeking.

    
   
2089
   *

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

    
   
2091
   * @param boffset buffer offset

    
   
2092
   * @param row the value key

    
   
2093
   * @param roffset row offset

    
   
2094
   * @param rlength row length

    
   
2095
   * @param family family name

    
   
2096
   * @param foffset family offset

    
   
2097
   * @param flength family length

    
   
2098
   * @param qualifier column qualifier

    
   
2099
   * @param qoffset qualifier offset

    
   
2100
   * @param qlength qualifier length

    
   
2101
   *

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

    
   
2103
   *

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

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

    
   
2106
   */

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

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

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

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

    
   
2111
          throws IllegalArgumentException {

    
   
2112

   

    
   
2113
    long lLength = getKeyValueDataStructureSize(rlength, flength, qlength, 0);

    
   
2114

   

    
   
2115
    if (lLength > Integer.MAX_VALUE) {

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

    
   
2117
    }

    
   
2118
    int iLength = (int) lLength;

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

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

    
   
2121
          iLength);

    
   
2122
    }

    
   
2123
    return new KeyValue(buffer, boffset,

    
   
2124
        row, roffset, rlength,

    
   
2125
        family, foffset, flength,

    
   
2126
        qualifier, qoffset, qlength,

    
   
2127
        HConstants.LATEST_TIMESTAMP, KeyValue.Type.Maximum,

    
   
2128
        null, 0, 0);

    
   
2129
  }

    
   
2130

   

    
   
2131
  /**

    
   
2132
   * Create a KeyValue for the specified row, family and qualifier that would be
1825
   * larger than or equal to all other possible KeyValues that have the same
2133
   * larger than or equal to all other possible KeyValues that have the same
1826
   * row, family, qualifier.
2134
   * row, family, qualifier.
1827
   * Used for reseeking.
2135
   * Used for reseeking.
1828
   * @param row row key
2136
   * @param row row key
1829
   * @param roffset row offset
2137
   * @param roffset row offset
[+20] [20] 427 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 786d2df 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...