Search in sources :

Example 1 with MutationResult

use of com.google.datastore.v1.MutationResult in project appengine-java-standard by GoogleCloudPlatform.

the class AsyncCloudDatastoreV1ServiceImpl method doBatchPut.

@Override
protected Future<List<Key>> doBatchPut(@Nullable final Transaction txn, final List<Entity> entities) {
    if (txn == null) {
        CommitRequest.Builder baseReq = CommitRequest.newBuilder();
        baseReq.setMode(CommitRequest.Mode.NON_TRANSACTIONAL);
        final Multimap<Integer, Integer> dedupedIndexMap = HashMultimap.create();
        final List<Entity> dedupedEntities = dedupeByKey(entities, dedupedIndexMap);
        final List<Integer> order = Lists.newArrayListWithCapacity(dedupedEntities.size());
        Iterator<CommitRequest.Builder> batches = putBatcher.getBatches(dedupedEntities, baseReq, baseReq.build().getSerializedSize(), /* group= */
        true, order);
        List<Future<CommitResponse>> futures = putBatcher.makeCalls(batches);
        return new ReorderingMultiFuture<CommitResponse, List<Key>>(futures, order) {

            @Override
            protected List<Key> aggregate(CommitResponse intermediateResult, Iterator<Integer> indexItr, List<Key> result) {
                for (MutationResult mutationResult : intermediateResult.getMutationResultsList()) {
                    int index = indexItr.next();
                    Key key = dedupedEntities.get(index).getKey();
                    if (mutationResult.hasKey()) {
                        // Update the Key object from the original Entity with the allocated id.
                        List<PathElement> pathElements = mutationResult.getKey().getPathList();
                        key.setId(pathElements.get(pathElements.size() - 1).getId());
                    }
                    for (Integer dedupedIndex : dedupedIndexMap.get(index)) {
                        result.set(dedupedIndex, key);
                    }
                }
                return result;
            }

            @Override
            protected List<Key> initResult() {
                // Pre-deduped size.
                int size = entities.size();
                // Elements are set into this list by the reordering batcher to recreate the
                // original key order. The list size must be remain mutable for compatibility
                // with previous SDK releases.
                List<Key> keyList = Lists.newArrayListWithCapacity(size);
                keyList.addAll(Collections.<Key>nCopies(size, null));
                return keyList;
            }
        };
    }
    // Handle transactional put.
    // v1 builds transactions locally: we defer the put until transaction commit. However,
    // the Java API requires us to the return keys corresponding to the entities. Insertions
    // might have incomplete keys, so we need to allocate these IDs.
    TransactionImpl.ensureTxnActive(txn);
    final InternalTransactionCloudDatastoreV1 txnV1 = InternalTransactionCloudDatastoreV1.get(txn);
    ImmutableList.Builder<Key> keyListBuilder = ImmutableList.builder();
    final List<Key> incompleteKeys = Lists.newArrayList();
    final List<com.google.datastore.v1.Entity.Builder> incompleteEntityBldrs = Lists.newArrayList();
    for (Entity entity : entities) {
        Key key = entity.getKey();
        keyListBuilder.add(key);
        if (key.isComplete()) {
            // Mutations on complete keys and incomplete keys can't conflict with each other,
            // so it's safe to add mutations with completed keys immediately (out of order)
            // even though we need to wait for the allocations for incomplete keys.
            txnV1.deferPut(entity);
        } else {
            // Freeze entity.  We will add it to the transaction in a callback from the
            // AllocateId call below.
            com.google.datastore.v1.Entity.Builder entityV1 = com.google.datastore.v1.Entity.newBuilder();
            DataTypeTranslator.addPropertiesToPb(entity.getPropertyMap(), entityV1);
            incompleteEntityBldrs.add(entityV1);
            incompleteKeys.add(key);
        }
    }
    final List<Key> allKeys = keyListBuilder.build();
    if (incompleteKeys.isEmpty()) {
        return new FutureHelper.FakeFuture<List<Key>>(allKeys);
    }
    return registerInTransaction(txn, new FutureWrapper<List<com.google.datastore.v1.Key>, List<Key>>(allocateIds(incompleteKeys)) {

        @Override
        protected List<Key> wrap(List<com.google.datastore.v1.Key> completedKeyPbs) {
            Iterator<com.google.datastore.v1.Entity.Builder> entityPbBldrIt = incompleteEntityBldrs.iterator();
            Iterator<Key> incompleteKeysIt = incompleteKeys.iterator();
            for (com.google.datastore.v1.Key keyV1 : completedKeyPbs) {
                // Set the id field of the original key object.
                updateKey(keyV1, incompleteKeysIt.next());
                // Build the entity proto and add it to the transaction.
                txnV1.deferPut(entityPbBldrIt.next().setKey(keyV1));
            }
            return allKeys;
        }

        @Override
        protected Throwable convertException(Throwable cause) {
            return cause;
        }
    });
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) PathElement(com.google.datastore.v1.Key.PathElement) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) MutationResult(com.google.datastore.v1.MutationResult) CommitRequest(com.google.datastore.v1.CommitRequest) ReorderingMultiFuture(com.google.appengine.api.datastore.Batcher.ReorderingMultiFuture) CommitResponse(com.google.datastore.v1.CommitResponse) Future(java.util.concurrent.Future) MultiFuture(com.google.appengine.api.datastore.FutureHelper.MultiFuture) ReorderingMultiFuture(com.google.appengine.api.datastore.Batcher.ReorderingMultiFuture)

Example 2 with MutationResult

use of com.google.datastore.v1.MutationResult in project appengine-java-standard by GoogleCloudPlatform.

the class BaseCloudDatastoreV1ServiceImplTest method createCommitResponse.

CommitResponse createCommitResponse(CommitRequest request, Long... allocatedIds) {
    CommitResponse.Builder req = CommitResponse.newBuilder();
    Iterator<Long> idIterator = Iterators.forArray(allocatedIds);
    for (Mutation mutation : request.getMutationsList()) {
        MutationResult.Builder mutationResult = MutationResult.newBuilder();
        com.google.datastore.v1.Entity.Builder entity;
        switch(mutation.getOperationCase()) {
            case INSERT:
                entity = mutation.getInsert().toBuilder();
                break;
            case UPSERT:
                entity = mutation.getUpsert().toBuilder();
                break;
            default:
                entity = null;
        }
        if (entity != null) {
            com.google.datastore.v1.Key key = entity.getKey();
            PathElement lastPathElem = key.getPath(key.getPathCount() - 1);
            if (lastPathElem.getIdTypeCase() == IdTypeCase.IDTYPE_NOT_SET) {
                mutationResult.setKey(completeKey(key, idIterator.next()));
            }
        }
        req.addMutationResults(mutationResult);
    }
    assertThat(idIterator.hasNext()).isFalse();
    return req.build();
}
Also used : CommitResponse(com.google.datastore.v1.CommitResponse) PathElement(com.google.datastore.v1.Key.PathElement) AtomicLong(java.util.concurrent.atomic.AtomicLong) Mutation(com.google.datastore.v1.Mutation) MutationResult(com.google.datastore.v1.MutationResult)

Aggregations

CommitResponse (com.google.datastore.v1.CommitResponse)2 PathElement (com.google.datastore.v1.Key.PathElement)2 MutationResult (com.google.datastore.v1.MutationResult)2 ReorderingMultiFuture (com.google.appengine.api.datastore.Batcher.ReorderingMultiFuture)1 MultiFuture (com.google.appengine.api.datastore.FutureHelper.MultiFuture)1 ImmutableList (com.google.common.collect.ImmutableList)1 CommitRequest (com.google.datastore.v1.CommitRequest)1 Mutation (com.google.datastore.v1.Mutation)1 ArrayList (java.util.ArrayList)1 Iterator (java.util.Iterator)1 List (java.util.List)1 Future (java.util.concurrent.Future)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1