Search in sources :

Example 26 with Property

use of com.google.storage.onestore.v3.OnestoreEntity.Index.Property in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreService method validateAndProcessProperty.

private void validateAndProcessProperty(Property prop) {
    if (RESERVED_NAME.matcher(prop.getName()).matches()) {
        throw newError(ErrorCode.BAD_REQUEST, String.format("illegal property.name: %s", prop.getName()));
    }
    PropertyValue val = prop.getMutableValue();
    if (val.hasUserValue() && !val.getUserValue().hasObfuscatedGaiaid()) {
        // If not already set, populate obfuscated gaia id with hash of email address.
        PropertyValue.UserValue userVal = val.getMutableUserValue();
        userVal.setObfuscatedGaiaid(Integer.toString(userVal.getEmail().hashCode()));
    }
}
Also used : PropertyValue(com.google.storage.onestore.v3.OnestoreEntity.PropertyValue)

Example 27 with Property

use of com.google.storage.onestore.v3.OnestoreEntity.Index.Property in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreService method createIndexEntities.

/**
 * Splits a full entity into all index entities seen in a projection.
 *
 * @param entity the entity to split
 * @param postfixProps the properties included in the postfix
 * @return A list of the index entities.
 */
private ImmutableList<EntityProto> createIndexEntities(EntityProto entity, Set<String> postfixProps, EntityProtoComparator entityComparator) {
    SetMultimap<String, PropertyValue> toSplit = MultimapBuilder.hashKeys(postfixProps.size()).hashSetValues(1).build();
    Set<String> seen = Sets.newHashSet();
    boolean splitRequired = false;
    for (Property prop : entity.propertys()) {
        if (postfixProps.contains(prop.getName())) {
            // If we have multiple values for any postfix property, we need to split.
            splitRequired |= !seen.add(prop.getName());
            // Only add the value if it matches the query filters
            if (entityComparator.matches(prop)) {
                toSplit.put(prop.getName(), prop.getValue());
            }
        }
    }
    if (!splitRequired) {
        // No need for splitting!
        return ImmutableList.of(entity);
    }
    EntityProto clone = new EntityProto();
    clone.getMutableKey().copyFrom(entity.getKey());
    clone.getMutableEntityGroup();
    List<EntityProto> results = Lists.newArrayList(clone);
    for (Map.Entry<String, Collection<PropertyValue>> entry : toSplit.asMap().entrySet()) {
        if (entry.getValue().size() == 1) {
            // No need for cloning!
            for (EntityProto result : results) {
                result.addProperty().setName(entry.getKey()).setMeaning(Property.Meaning.INDEX_VALUE).getMutableValue().copyFrom(Iterables.getOnlyElement(entry.getValue()));
            }
            continue;
        }
        List<EntityProto> splitResults = Lists.newArrayListWithCapacity(results.size() * entry.getValue().size());
        for (PropertyValue value : entry.getValue()) {
            for (EntityProto result : results) {
                EntityProto split = result.clone();
                split.addProperty().setName(entry.getKey()).setMeaning(Property.Meaning.INDEX_VALUE).getMutableValue().copyFrom(value);
                splitResults.add(split);
            }
        }
        results = splitResults;
    }
    return ImmutableList.copyOf(results);
}
Also used : PropertyValue(com.google.storage.onestore.v3.OnestoreEntity.PropertyValue) Collection(java.util.Collection) ByteString(com.google.protobuf.ByteString) Property(com.google.storage.onestore.v3.OnestoreEntity.Property) 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 28 with Property

use of com.google.storage.onestore.v3.OnestoreEntity.Index.Property in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreCostAnalysis method getEntityByPropertyIndexes.

/**
 * Given a set of property names, generates a {@code List} of {@link Index} objects that can be
 * used to generate index rows that would be appear in EntitiesByProperty and
 * EntitiesByPropertyDesc
 *
 * @param propertyNames The property names.
 * @return The indexes.
 */
static List<Index> getEntityByPropertyIndexes(Set<String> propertyNames) {
    List<String> sortedPropertyNames = Ordering.natural().sortedCopy(propertyNames);
    List<Index> indexes = Lists.newArrayList();
    for (String propName : sortedPropertyNames) {
        // EnititiesByProperty
        Index index = new Index();
        index.addProperty(new Index.Property().setName(propName).setDirection(Direction.ASCENDING));
        indexes.add(index);
        // EnititiesByPropertyDesc
        index = new Index();
        index.addProperty(new Index.Property().setName(propName).setDirection(Direction.DESCENDING));
        indexes.add(index);
    }
    return indexes;
}
Also used : Index(com.google.storage.onestore.v3.OnestoreEntity.Index)

Example 29 with Property

use of com.google.storage.onestore.v3.OnestoreEntity.Index.Property in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreCostAnalysis method changedIndexRows.

/**
 * Determine the number of index rows that need to change when writing {@code newEntity}, assuming
 * {@code oldEntity} represents the current state of the Datastore.
 *
 * @param oldEntity Entity representing the current state in the datastore.
 * @param newEntity Entity representing the desired state in the datastore.
 * @return The number of index rows that need to change.
 */
private int changedIndexRows(EntityProto oldEntity, EntityProto newEntity) {
    // All properties that are unique within the old entity, not all properties that are unique
    // to the old entity. Declaring the specific subtype because we rely on the fact that
    // HashMultimap enforces uniqueness of key-value pairs.
    SetMultimap<String, Property> uniqueOldProperties = HashMultimap.create();
    if (oldEntity != null) {
        for (Property oldProp : oldEntity.propertys()) {
            // A given name may only have one property value on the old entity but multiple values on
            // the new entity. If that's the case, two Properties that are equal will be considered not
            // equal due to different values of the "multiple" attribute. We want these Properties to be
            // considered equal so we hard-code "multiple" to be false in the map.
            oldProp = oldProp.isMultiple() ? oldProp.clone().setMultiple(false) : oldProp;
            uniqueOldProperties.put(oldProp.getName(), oldProp);
        }
    }
    // All properties that are unique within the new entity, not all properties that are unique
    // to the new entity. Declaring the specific subtype because we rely on the fact that
    // HashMultimap enforces uniqueness of key-value pairs.
    SetMultimap<String, Property> uniqueNewProperties = HashMultimap.create();
    // Number of properties per name that have not changed between old and new.
    Multiset<String> unchanged = HashMultiset.create();
    for (Property newProp : newEntity.propertys()) {
        // See the comment in the loop where we populate uniqueOldProperties for an explanation of why
        // we do this.
        newProp = newProp.isMultiple() ? newProp.clone().setMultiple(false) : newProp;
        uniqueNewProperties.put(newProp.getName(), newProp);
        if (uniqueOldProperties.containsEntry(newProp.getName(), newProp)) {
            unchanged.add(newProp.getName());
        }
    }
    // We're going to build Index objects that correspond to the single-property, built-in indexes
    // that the Datastore maintains. In order to do this we need a unique list of all the property
    // names on both the old and new entities.
    Set<String> allPropertyNames = Sets.newHashSet(Iterables.concat(uniqueOldProperties.keySet(), uniqueNewProperties.keySet()));
    Iterable<Index> allIndexes = Iterables.concat(indexManager.getIndexesForKind(Utils.getKind(newEntity.getKey())), getEntityByPropertyIndexes(allPropertyNames));
    Multiset<String> uniqueOldPropertyNames = uniqueOldProperties.keys();
    Multiset<String> uniqueNewPropertyNames = uniqueNewProperties.keys();
    int pathSize = newEntity.getKey().getPath().elementSize();
    int writes = 0;
    for (Index index : allIndexes) {
        // Take ancestor indexes into account.
        // Ancestor doesn't matter for EntityByProperty indexes, and these are the only indexes that
        // have a single property.
        int ancestorMultiplier = index.isAncestor() && index.propertySize() > 1 ? pathSize : 1;
        writes += (calculateWritesForCompositeIndex(index, uniqueOldPropertyNames, uniqueNewPropertyNames, unchanged) * ancestorMultiplier);
    }
    return writes;
}
Also used : Index(com.google.storage.onestore.v3.OnestoreEntity.Index) Property(com.google.storage.onestore.v3.OnestoreEntity.Property)

Example 30 with Property

use of com.google.storage.onestore.v3.OnestoreEntity.Index.Property in project appengine-java-standard by GoogleCloudPlatform.

the class EntityStorageConversions method stashProperties.

/**
 * Finds all properties marked for stashing: if they are computed, removes them, moves them to raw
 * properties.
 *
 * @param diskEntity The EntityProto to modify.
 */
private static void stashProperties(EntityProto diskEntity) {
    ImmutableList<Property> properties = ImmutableList.copyOf(diskEntity.propertys());
    diskEntity.clearProperty();
    for (Property property : properties) {
        if (property.hasStashed()) {
            if (!property.isComputed()) {
                diskEntity.addRawProperty(property);
            }
        } else {
            diskEntity.addProperty(property);
        }
    }
}
Also used : Property(com.google.storage.onestore.v3.OnestoreEntity.Property)

Aggregations

Property (com.google.storage.onestore.v3.OnestoreEntity.Property)15 PropertyValue (com.google.storage.onestore.v3.OnestoreEntity.PropertyValue)9 EntityProto (com.google.storage.onestore.v3.OnestoreEntity.EntityProto)8 Property (com.google.storage.onestore.v3.OnestoreEntity.Index.Property)8 Filter (com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter)5 Order (com.google.apphosting.datastore.DatastoreV3Pb.Query.Order)4 ByteString (com.google.protobuf.ByteString)4 Index (com.google.storage.onestore.v3.OnestoreEntity.Index)4 OnestoreEntity (com.google.storage.onestore.v3.OnestoreEntity)3 Map (java.util.Map)3 Nullable (org.checkerframework.checker.nullness.qual.Nullable)3 Test (org.junit.Test)3 Entity (com.google.appengine.api.datastore.Entity)2 ImmutableList (com.google.common.collect.ImmutableList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 Test (org.junit.jupiter.api.Test)2 Property (com.google.appengine.api.datastore.Index.Property)1 Extent (com.google.appengine.api.datastore.dev.LocalDatastoreService.Extent)1 Profile (com.google.appengine.api.datastore.dev.LocalDatastoreService.Profile)1