Finds the highest row that's less than or equal to the given row. @param region The region in which to search. @param tabl The table to which the key belongs. @param row The row to search. @param family The family to get. @return A Deferred ArrayList of KeyValue. The list is guarant
(final RegionInfo region,
final byte[] tabl,
final byte[] row,
final byte[] family)
| 729 | * guaranteed to be non-{@code null} but may be empty. |
| 730 | */ |
| 731 | public |
| 732 | Deferred<ArrayList<KeyValue>> getClosestRowBefore(final RegionInfo region, |
| 733 | final byte[] tabl, |
| 734 | final byte[] row, |
| 735 | final byte[] family) { |
| 736 | final class GetClosestRowBefore extends HBaseRpc { |
| 737 | GetClosestRowBefore() { |
| 738 | super(tabl, row); |
| 739 | } |
| 740 | |
| 741 | @Override |
| 742 | byte[] method(final byte server_version) { |
| 743 | return server_version >= SERVER_VERSION_095_OR_ABOVE |
| 744 | ? GetRequest.GGET : GET_CLOSEST_ROW_BEFORE; |
| 745 | } |
| 746 | |
| 747 | @Override |
| 748 | Object deserialize(final ChannelBuffer buf, final int cell_size) { |
| 749 | assert cell_size == 0 : "cell_size=" + cell_size; |
| 750 | final ClientPB.GetResponse resp = |
| 751 | readProtobuf(buf, ClientPB.GetResponse.PARSER); |
| 752 | return GetRequest.extractResponse(resp, buf, cell_size); |
| 753 | } |
| 754 | |
| 755 | @Override |
| 756 | ChannelBuffer serialize(final byte server_version) { |
| 757 | if (server_version < SERVER_VERSION_095_OR_ABOVE) { |
| 758 | return serializeOld(server_version); |
| 759 | } |
| 760 | final ClientPB.Get getpb = ClientPB.Get.newBuilder() |
| 761 | .setRow(Bytes.wrap(row)) |
| 762 | .addColumn(FAM_INFO) // Fetch from one family only. |
| 763 | .setClosestRowBefore(true) |
| 764 | .build(); |
| 765 | final ClientPB.GetRequest get = ClientPB.GetRequest.newBuilder() |
| 766 | .setRegion(region.toProtobuf()) |
| 767 | .setGet(getpb) |
| 768 | .build(); |
| 769 | return toChannelBuffer(GetRequest.GGET, get); |
| 770 | } |
| 771 | |
| 772 | private ChannelBuffer serializeOld(final byte server_version) { |
| 773 | // region.length and row.length will use at most a 3-byte VLong. |
| 774 | // This is because VLong wastes 1 byte of meta-data + 2 bytes of |
| 775 | // payload. HBase's own KeyValue code uses a short to store the row |
| 776 | // length. Finally, family.length cannot be on more than 1 byte, |
| 777 | // HBase's own KeyValue code uses a byte to store the family length. |
| 778 | final byte[] region_name = region.name(); |
| 779 | final ChannelBuffer buf = newBuffer(server_version, |
| 780 | + 4 // num param |
| 781 | + 1 + 2 + region_name.length // 3 times 1 byte for the |
| 782 | + 1 + 4 + row.length // parm type + VLong |
| 783 | + 1 + 1 + family.length); // + array |
| 784 | buf.writeInt(3); // Number of parameters. |
| 785 | writeHBaseByteArray(buf, region_name); // 1st param. |
| 786 | writeHBaseByteArray(buf, row); // 2nd param. |
| 787 | writeHBaseByteArray(buf, family); // 3rd param. |
| 788 | return buf; |