* @param keys The {@link Key keys} of the entities to delete.
*
* @return A {@link Future} that provides the results of the operation.
*/
private Future<Void> doBatchDeleteBySize( Transaction txn, Iterable<Key> keys) {
DeleteRequest baseReq = new DeleteRequest();
if (txn != null) {
TransactionImpl.ensureTxnActive(txn);
baseReq.setTransaction(localTxnToRemoteTxn(txn));
}
final int baseEncodedReqSize = baseReq.encodingSize();
final List<Future<DeleteResponse>> futures = new ArrayList<Future<DeleteResponse>>();
int encodedReqSize = baseEncodedReqSize;
DeleteRequest req = baseReq.clone();
for (Key key : keys) {
if (!key.isComplete()) {
throw new IllegalArgumentException(key + " is incomplete.");
}
Reference ref = KeyTranslator.convertToPb(key);
int encodedKeySize = Protocol.stringSize(ref.encodingSize()) + 1;
if (getDatastoreServiceConfig().exceedsWriteLimits(
req.keySize() + 1, encodedReqSize + encodedKeySize)) {
futures.add(makeAsyncCall(apiConfig, "Delete", req, new DeleteResponse()));
encodedReqSize = baseEncodedReqSize;
req = baseReq.clone();
}
encodedReqSize += encodedKeySize;
req.addKey(ref);
}
if (req.keySize() > 0) {
futures.add(makeAsyncCall(apiConfig, "Delete", req, new DeleteResponse()));
}
return registerInTransaction(txn,
new CumulativeAggregateFuture<DeleteResponse, Void, Void>(futures) {