Search in sources :

Example 1 with Cost

use of com.google.apphosting.datastore.DatastoreV3Pb.Cost in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreService method putImpl.

// status
@SuppressWarnings("unused")
public PutResponse putImpl(Status status, PutRequest request) {
    PutResponse response = new PutResponse();
    if (request.entitySize() == 0) {
        return response;
    }
    Cost totalCost = response.getMutableCost();
    String app = request.entitys().get(0).getKey().getApp();
    List<EntityProto> clones = new ArrayList<>();
    for (EntityProto entity : request.entitys()) {
        validateAndProcessEntityProto(entity);
        EntityProto clone = entity.clone();
        clones.add(clone);
        checkArgument(clone.hasKey());
        Reference key = clone.getKey();
        checkArgument(key.getPath().elementSize() > 0);
        clone.getMutableKey().setApp(app);
        Element lastPath = getLastElement(key);
        if (lastPath.getId() == 0 && !lastPath.hasName()) {
            if (autoIdAllocationPolicy == AutoIdAllocationPolicy.SEQUENTIAL) {
                lastPath.setId(entityIdSequential.getAndIncrement());
            } else {
                lastPath.setId(toScatteredId(entityIdScattered.getAndIncrement()));
            }
        }
        preprocessEntity(clone);
        if (clone.getEntityGroup().elementSize() == 0) {
            // The entity needs its entity group set.
            Path group = clone.getMutableEntityGroup();
            Element root = key.getPath().elements().get(0);
            Element pathElement = group.addElement();
            pathElement.setType(root.getType());
            if (root.hasName()) {
                pathElement.setName(root.getName());
            } else {
                pathElement.setId(root.getId());
            }
        } else {
            // update an existing entity
            checkState(clone.hasEntityGroup() && clone.getEntityGroup().elementSize() > 0);
        }
    }
    Map<Path, List<EntityProto>> entitiesByEntityGroup = new LinkedHashMap<>();
    Map<Reference, Long> writtenVersions = new HashMap<>();
    final Profile profile = getOrCreateProfile(app);
    synchronized (profile) {
        LiveTxn liveTxn = null;
        for (EntityProto clone : clones) {
            Profile.EntityGroup eg = profile.getGroup(clone.getEntityGroup());
            if (request.hasTransaction()) {
                // the transaction is committed.
                if (liveTxn == null) {
                    liveTxn = profile.getTxn(request.getTransaction().getHandle());
                }
                checkRequest(!liveTxn.isReadOnly(), "Cannot modify entities in a read-only transaction.");
                // this will throw an exception if we attempt to
                // modify the wrong entity group
                eg.addTransaction(liveTxn).addWrittenEntity(clone);
            } else {
                List<EntityProto> entities = entitiesByEntityGroup.get(clone.getEntityGroup());
                if (entities == null) {
                    entities = new ArrayList<>();
                    entitiesByEntityGroup.put(clone.getEntityGroup(), entities);
                }
                entities.add(clone);
            }
            response.mutableKeys().add(clone.getKey());
        }
        for (final Map.Entry<Path, List<EntityProto>> entry : entitiesByEntityGroup.entrySet()) {
            Profile.EntityGroup eg = profile.getGroup(entry.getKey());
            eg.incrementVersion();
            LocalDatastoreJob job = new WriteJob(highRepJobPolicy, eg, profile, entry.getValue(), Collections.<Reference>emptyList());
            addTo(totalCost, job.calculateJobCost());
            eg.addJob(job);
            for (EntityProto entity : entry.getValue()) {
                writtenVersions.put(entity.getKey(), job.getMutationTimestamp(entity.getKey()));
            }
        }
    }
    if (!request.hasTransaction()) {
        logger.fine("put: " + request.entitySize() + " entities");
        // Fill the version numbers, in the same order
        for (Reference key : response.keys()) {
            response.addVersion(writtenVersions.get(key));
        }
    }
    response.setCost(totalCost);
    return response;
}
Also used : Path(com.google.storage.onestore.v3.OnestoreEntity.Path) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) Reference(com.google.storage.onestore.v3.OnestoreEntity.Reference) Element(com.google.storage.onestore.v3.OnestoreEntity.Path.Element) Utils.getLastElement(com.google.appengine.api.datastore.dev.Utils.getLastElement) ArrayList(java.util.ArrayList) ByteString(com.google.protobuf.ByteString) PutResponse(com.google.apphosting.datastore.DatastoreV3Pb.PutResponse) Cost(com.google.apphosting.datastore.DatastoreV3Pb.Cost) LinkedHashMap(java.util.LinkedHashMap) AtomicLong(java.util.concurrent.atomic.AtomicLong) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) EntityProto(com.google.storage.onestore.v3.OnestoreEntity.EntityProto)

Example 2 with Cost

use of com.google.apphosting.datastore.DatastoreV3Pb.Cost in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreCostAnalysis method getWriteOps.

/**
 * Determines the cost of writing {@code newEntity}, assuming its current state in the datastore
 * matches {@code oldEntity}.
 *
 * @param oldEntity Entity representing the current state in the datastore. Can be {@code null}.
 * @param newEntity Entity representing the desired state in the datastore.
 * @return The cost of writing {@code newEntity}.
 */
public Cost getWriteOps(@Nullable EntityProto oldEntity, EntityProto newEntity) {
    Cost cost = new Cost().setEntityWrites(0).setIndexWrites(0);
    // check for a no-op write, only possible if an entity already existed
    if (equalProperties(oldEntity, newEntity)) {
        return cost;
    }
    // Not a no-op write, so one write for the entity.
    cost.setEntityWrites(1);
    int indexWrites = changedIndexRows(oldEntity, newEntity);
    if (oldEntity == null) {
        // 1 additional index write for the EntitiesByKind index, which is only written to when we're
        // writing an entity for the first time (kind is immutable).
        indexWrites++;
    }
    return cost.setIndexWrites(indexWrites);
}
Also used : Cost(com.google.apphosting.datastore.DatastoreV3Pb.Cost)

Example 3 with Cost

use of com.google.apphosting.datastore.DatastoreV3Pb.Cost in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreService method commitImpl.

/**
 * Requires a lock on the provided profile.
 */
private CommitResponse commitImpl(LiveTxn liveTxn, final Profile profile) {
    // assumes we already have a lock on the profile
    CommitResponse response = new CommitResponse();
    for (EntityGroupTracker tracker : liveTxn.getAllTrackers()) {
        // This will throw an exception if the entity group
        // has been modified since this transaction started.
        tracker.checkEntityGroupVersion();
    }
    int deleted = 0;
    int written = 0;
    Cost totalCost = new Cost();
    long commitTimestamp = profile.incrementAndGetCommitTimestamp();
    for (EntityGroupTracker tracker : liveTxn.getAllTrackers()) {
        Profile.EntityGroup eg = tracker.getEntityGroup();
        eg.incrementVersion();
        final Collection<EntityProto> writtenEntities = tracker.getWrittenEntities();
        final Collection<Reference> deletedKeys = tracker.getDeletedKeys();
        LocalDatastoreJob job = new WriteJob(highRepJobPolicy, eg, profile, commitTimestamp, writtenEntities, deletedKeys);
        addTo(totalCost, job.calculateJobCost());
        eg.addJob(job);
        deleted += deletedKeys.size();
        written += writtenEntities.size();
        for (EntityProto writtenEntity : writtenEntities) {
            response.addVersion().setRootEntityKey(writtenEntity.getKey()).setVersion(job.getMutationTimestamp(writtenEntity.getKey()));
        }
        for (Reference deletedKey : deletedKeys) {
            response.addVersion().setRootEntityKey(deletedKey).setVersion(job.getMutationTimestamp(deletedKey));
        }
    }
    logger.fine("committed: " + written + " puts, " + deleted + " deletes in " + liveTxn.getAllTrackers().size() + " entity groups");
    response.setCost(totalCost);
    return response;
}
Also used : Reference(com.google.storage.onestore.v3.OnestoreEntity.Reference) CommitResponse(com.google.apphosting.datastore.DatastoreV3Pb.CommitResponse) Cost(com.google.apphosting.datastore.DatastoreV3Pb.Cost) EntityProto(com.google.storage.onestore.v3.OnestoreEntity.EntityProto)

Example 4 with Cost

use of com.google.apphosting.datastore.DatastoreV3Pb.Cost in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreService method deleteImpl.

// status
@SuppressWarnings("unused")
public DeleteResponse deleteImpl(Status status, DeleteRequest request) {
    DeleteResponse response = new DeleteResponse();
    if (request.keySize() == 0) {
        return response;
    }
    Cost totalCost = response.getMutableCost();
    // We don't support requests that span apps, so the app for the first key
    // is the app for all keys.
    String app = request.keys().get(0).getApp();
    final Profile profile = getOrCreateProfile(app);
    LiveTxn liveTxn = null;
    // Maintain a mapping of keys by entity group so that we can apply one job
    // per entity group.
    Map<Path, List<Reference>> keysByEntityGroup = new LinkedHashMap<>();
    Map<Reference, Long> writtenVersions = new HashMap<>();
    synchronized (profile) {
        for (final Reference key : request.keys()) {
            validatePathComplete(key);
            Path group = getGroup(key);
            if (request.hasTransaction()) {
                if (liveTxn == null) {
                    liveTxn = profile.getTxn(request.getTransaction().getHandle());
                }
                checkRequest(!liveTxn.isReadOnly(), "Cannot modify entities in a read-only transaction.");
                Profile.EntityGroup eg = profile.getGroup(group);
                // this will throw an exception if we attempt to modify
                // the wrong entity group
                eg.addTransaction(liveTxn).addDeletedEntity(key);
            } else {
                List<Reference> keysToDelete = keysByEntityGroup.get(group);
                if (keysToDelete == null) {
                    keysToDelete = new ArrayList<>();
                    keysByEntityGroup.put(group, keysToDelete);
                }
                keysToDelete.add(key);
            }
        }
        // does all the work for each entity group.
        for (final Map.Entry<Path, List<Reference>> entry : keysByEntityGroup.entrySet()) {
            Profile.EntityGroup eg = profile.getGroup(entry.getKey());
            eg.incrementVersion();
            LocalDatastoreJob job = new WriteJob(highRepJobPolicy, eg, profile, Collections.<EntityProto>emptyList(), entry.getValue());
            addTo(totalCost, job.calculateJobCost());
            eg.addJob(job);
            for (Reference deletedKey : entry.getValue()) {
                writtenVersions.put(deletedKey, job.getMutationTimestamp(deletedKey));
            }
        }
    }
    if (!request.hasTransaction()) {
        for (Reference key : request.keys()) {
            response.addVersion(writtenVersions.get(key));
        }
    }
    return response;
}
Also used : Path(com.google.storage.onestore.v3.OnestoreEntity.Path) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) Reference(com.google.storage.onestore.v3.OnestoreEntity.Reference) ByteString(com.google.protobuf.ByteString) Cost(com.google.apphosting.datastore.DatastoreV3Pb.Cost) LinkedHashMap(java.util.LinkedHashMap) DeleteResponse(com.google.apphosting.datastore.DatastoreV3Pb.DeleteResponse) AtomicLong(java.util.concurrent.atomic.AtomicLong) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap)

Example 5 with Cost

use of com.google.apphosting.datastore.DatastoreV3Pb.Cost in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreService method commit.

// status
@SuppressWarnings("unused")
public CommitResponse commit(Status status, final Transaction req) {
    Profile profile = profiles.get(req.getApp());
    checkNotNull(profile);
    CommitResponse response = new CommitResponse();
    globalLock.readLock().lock();
    // Synchronized so we can't commit and rollback at the same time.
    synchronized (profile) {
        LiveTxn liveTxn;
        try {
            liveTxn = profile.removeTxn(req.getHandle());
            try {
                if (liveTxn.isDirty()) {
                    response = commitImpl(liveTxn, profile);
                } else {
                    // cost of a read-only txn is 0
                    response.setCost(new Cost().setEntityWrites(0).setIndexWrites(0));
                }
            } catch (ApplicationException e) {
                // commit failed, re-add transaction so that it can be rolled back or reset.
                profile.addTxn(req.getHandle(), new LiveTxn(clock, liveTxn.allowMultipleEg, liveTxn.originalTransactionMode, true));
                throw e;
            }
        } finally {
            globalLock.readLock().unlock();
        }
        // taskqueue tasks become durable.
        for (TaskQueueAddRequest action : liveTxn.getActions()) {
            try {
                addActionImpl(action);
            } catch (ApplicationException e) {
                logger.log(Level.WARNING, "Transactional task: " + action + " has been dropped.", e);
            }
        }
    }
    return response;
}
Also used : ApplicationException(com.google.apphosting.api.ApiProxy.ApplicationException) TaskQueueAddRequest(com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest) CommitResponse(com.google.apphosting.datastore.DatastoreV3Pb.CommitResponse) Cost(com.google.apphosting.datastore.DatastoreV3Pb.Cost)

Aggregations

Cost (com.google.apphosting.datastore.DatastoreV3Pb.Cost)5 Reference (com.google.storage.onestore.v3.OnestoreEntity.Reference)3 CommitResponse (com.google.apphosting.datastore.DatastoreV3Pb.CommitResponse)2 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 ByteString (com.google.protobuf.ByteString)2 EntityProto (com.google.storage.onestore.v3.OnestoreEntity.EntityProto)2 Path (com.google.storage.onestore.v3.OnestoreEntity.Path)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2 Map (java.util.Map)2 WeakHashMap (java.util.WeakHashMap)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 Utils.getLastElement (com.google.appengine.api.datastore.dev.Utils.getLastElement)1 TaskQueueAddRequest (com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest)1 ApplicationException (com.google.apphosting.api.ApiProxy.ApplicationException)1 DeleteResponse (com.google.apphosting.datastore.DatastoreV3Pb.DeleteResponse)1