Predicts a lower bound on the serialized size of this RPC. This is to avoid using a dynamic buffer, to avoid re-sizing the buffer. Since we use a static buffer, if the prediction is wrong and turns out to be less than what we need, there will be an exception which will prevent the RPC from being ser
(final byte server_version)
| 144 | * @param server_version What RPC protocol version the server is running. |
| 145 | */ |
| 146 | private int predictSerializedSize(final byte server_version) { |
| 147 | // See the comment in serialize() about the for loop that follows. |
| 148 | int size = 0; |
| 149 | size += 4; // int: Number of parameters. |
| 150 | size += 1; // byte: Type of the 1st parameter. |
| 151 | size += 1; // byte: Type again (see HBASE-2877). |
| 152 | size += 4; // int: How many regions do we want to affect? |
| 153 | |
| 154 | // Are we serializing a `multi' RPC, or `multiPut'? |
| 155 | final boolean use_multi = method(server_version) == MULTI; |
| 156 | |
| 157 | BatchableRpc prev = PutRequest.EMPTY_PUT; |
| 158 | for (final BatchableRpc rpc : batch) { |
| 159 | final byte[] region_name = rpc.getRegion().name(); |
| 160 | final boolean new_region = !Bytes.equals(prev.getRegion().name(), |
| 161 | region_name); |
| 162 | final byte[] family = rpc.family(); |
| 163 | final boolean new_key = (new_region |
| 164 | || prev.code() != rpc.code() |
| 165 | || !Bytes.equals(prev.key, rpc.key) |
| 166 | || family == DeleteRequest.WHOLE_ROW); |
| 167 | final boolean new_family = new_key || !Bytes.equals(prev.family(), |
| 168 | family); |
| 169 | |
| 170 | if (new_region) { |
| 171 | size += 3; // vint: region name length (3 bytes => max length = 32768). |
| 172 | size += region_name.length; // The region name. |
| 173 | size += 4; // int: How many RPCs for this region. |
| 174 | } |
| 175 | |
| 176 | final int key_length = rpc.key.length; |
| 177 | |
| 178 | if (new_key) { |
| 179 | if (use_multi) { |
| 180 | size += 4; // int: Number of "attributes" for the last key (none). |
| 181 | size += 4; // Index of this `action'. |
| 182 | size += 3; // 3 bytes to serialize `null'. |
| 183 | |
| 184 | size += 1; // byte: Type code for `Action'. |
| 185 | size += 1; // byte: Type code again (see HBASE-2877). |
| 186 | |
| 187 | size += 1; // byte: Code for a `Row' object. |
| 188 | size += 1; // byte: Code for a `Put' object. |
| 189 | } |
| 190 | |
| 191 | size += 1; // byte: Version of Put. |
| 192 | size += 3; // vint: row key length (3 bytes => max length = 32768). |
| 193 | size += key_length; // The row key. |
| 194 | size += 8; // long: Timestamp. |
| 195 | size += 8; // long: Lock ID. |
| 196 | size += 1; // bool: Whether or not to write to the WAL. |
| 197 | size += 4; // int: Number of families for which we have edits. |
| 198 | } |
| 199 | |
| 200 | if (new_family) { |
| 201 | size += 1; // vint: Family length (guaranteed on 1 byte). |
| 202 | size += family.length; // The family. |
| 203 | size += 4; // int: Number of KeyValues that follow. |
no test coverage detected