*
* @return A {@link Future} that provides the results of the operation.
*/
private Future<List<Key>> doBatchPutBySize( Transaction txn,
final Iterable<Entity> entities) {
PutRequest baseReq = new PutRequest();
if (txn != null) {
TransactionImpl.ensureTxnActive(txn);
baseReq.setTransaction(localTxnToRemoteTxn(txn));
}
final int baseEncodedReqSize = baseReq.encodingSize();
final List<Future<PutResponse>> futures = new ArrayList<Future<PutResponse>>();
int encodedReqSize = baseEncodedReqSize;
PutRequest req = baseReq.clone();
for (Entity entity : entities) {
EntityProto proto = EntityTranslator.convertToPb(entity);
int encodedEntitySize = Protocol.stringSize(proto.encodingSize()) + 1;
if (getDatastoreServiceConfig().exceedsWriteLimits(
req.entitySize() + 1, encodedReqSize + encodedEntitySize)) {
futures.add(makeAsyncCall(apiConfig, "Put", req, new PutResponse()));
encodedReqSize = baseEncodedReqSize;
req = baseReq.clone();
}
encodedReqSize += encodedEntitySize;
req.addEntity(proto);
}
if (req.entitySize() > 0) {
futures.add(makeAsyncCall(apiConfig, "Put", req, new PutResponse()));
}
return registerInTransaction(txn,
new IteratingAggregateFuture<PutResponse, Entity, List<Key>>(futures) {