Creates a new fixed-length buffer on the heap. @param server_version What RPC protocol version the server is running. @param max_payload_size A good approximation of the size of the payload. The approximation must be an upper bound on the expected size of the payload as trying to store more than {@c
(final byte server_version,
final int max_payload_size)
| 883 | * the buffer returned will cause an {@link ArrayIndexOutOfBoundsException}. |
| 884 | */ |
| 885 | final ChannelBuffer newBuffer(final byte server_version, |
| 886 | final int max_payload_size) { |
| 887 | // Add extra bytes for the RPC header: |
| 888 | // 4 bytes: Payload size (always present, even in HBase 0.95+). |
| 889 | // 4 bytes: RPC ID. |
| 890 | // 2 bytes: Length of the method name. |
| 891 | // N bytes: The method name. |
| 892 | final int header = 4 + 4 + 2 + method(server_version).length |
| 893 | // Add extra bytes for the RPC header used in HBase 0.92 and above: |
| 894 | // 1 byte: RPC header version. |
| 895 | // 8 bytes: Client version. Yeah, 8 bytes, WTF seriously. |
| 896 | // 4 bytes: Method fingerprint. |
| 897 | + (server_version < RegionClient.SERVER_VERSION_092_OR_ABOVE ? 0 |
| 898 | : 1 + 8 + 4); |
| 899 | // Note: with HBase 0.95 and up, the size of the protobuf header varies. |
| 900 | // It is currently made of (see RequestHeader in RPC.proto): |
| 901 | // - uint32 callId: varint 1 to 5 bytes |
| 902 | // - RPCTInfo traceInfo: two uint64 varint so 4 to 20 bytes. |
| 903 | // - string methodName: varint length (1 byte) and method name. |
| 904 | // - bool requestParam: 1 byte |
| 905 | // - CellBlockMeta cellBlockMeta: one uint32 varint so 2 to 6 bytes. |
| 906 | // Additionally each field costs an extra 1 byte, and there is a varint |
| 907 | // prior to the header for the size of the header. We don't set traceInfo |
| 908 | // right now so that leaves us with 4 fields for a total maximum size of |
| 909 | // 1 varint + 4 fields + 5 + 1 + N + 1 + 6 = 18 bytes max + method name. |
| 910 | // Since for HBase 0.92 we reserve 19 bytes, we're good, we over-allocate |
| 911 | // at most 1 bytes. So the logic above doesn't need to change for 0.95+. |
| 912 | final ChannelBuffer buf = ChannelBuffers.buffer(header + max_payload_size); |
| 913 | buf.setIndex(0, header); // Advance the writerIndex past the header. |
| 914 | return buf; |
| 915 | } |
| 916 | |
| 917 | /** |
| 918 | * Serializes the given protobuf object into a Netty {@link ChannelBuffer}. |
no test coverage detected