use of com.google.storage.onestore.v3.OnestoreEntity.EntityProto in project appengine-java-standard by GoogleCloudPlatform.
the class KindPseudoKind method runQuery.
// Based on LocalDatastoreService.getSchema (now removed)
@Override
List<EntityProto> runQuery(Query query, Key startKey, boolean startInclusive, Key endKey, boolean endInclusive) {
/* Ancestor has no meaning in schema queries. This also has the desirable side effect that
* schema queries cannot live in transactions. */
checkRequest(!query.hasAncestor(), "ancestor queries on " + KIND_METADATA_KIND + " not allowed");
String app = query.getApp();
String namespace = query.getNameSpace();
String startKind = kindKeyToString(startKey);
String endKind = kindKeyToString(endKey);
Profile profile = getDatastore().getOrCreateProfile(app);
Map<String, Extent> extents = profile.getExtents();
List<EntityProto> kinds = Lists.newArrayList();
synchronized (extents) {
// We create one EntityProto per kind with a key containing the kind name
for (Map.Entry<String, Extent> entry : extents.entrySet()) {
String kind = entry.getKey();
// Apply filters.
if (startKind != null) {
int kindsCompared = kind.compareTo(startKind);
if ((startInclusive && kindsCompared < 0) || (!startInclusive && kindsCompared <= 0)) {
continue;
}
}
if (endKind != null) {
int kindsCompared = kind.compareTo(endKind);
if ((endInclusive && kindsCompared > 0) || (!endInclusive && kindsCompared >= 0)) {
continue;
}
}
if (entry.getValue().getAllEntityProtos().isEmpty()) {
// no entities of this kind
continue;
}
// Add an entry only if entities exist in the requested namespace.
if (isKindPresentInNamespace(entry.getValue(), namespace)) {
kinds.add(makeKindEntity(kind, app, namespace));
}
}
}
return kinds;
}
use of com.google.storage.onestore.v3.OnestoreEntity.EntityProto 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;
}
use of com.google.storage.onestore.v3.OnestoreEntity.EntityProto in project appengine-java-standard by GoogleCloudPlatform.
the class EntityTest method testUnindexableValueInIndexedList.
@Test
public void testUnindexableValueInIndexedList() {
Entity entity = new Entity("foo");
entity.setProperty("prop", ImmutableList.of("string", new EmbeddedEntity(), new Text("text"), new Blob(new byte[] { 1, 2, 3 })));
assertThat(entity.isUnindexedProperty("prop")).isFalse();
EntityProto proto = EntityTranslator.convertToPb(entity);
assertThat(proto.propertySize()).isEqualTo(1);
assertThat(proto.rawPropertySize()).isEqualTo(3);
Entity restoredEntity = EntityTranslator.createFromPb(proto);
assertThat(restoredEntity.getPropertyMap()).isEqualTo(entity.getPropertyMap());
assertThat(restoredEntity.isUnindexedProperty("prop")).isFalse();
}
use of com.google.storage.onestore.v3.OnestoreEntity.EntityProto 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);
}
}
}
use of com.google.storage.onestore.v3.OnestoreEntity.EntityProto in project appengine-java-standard by GoogleCloudPlatform.
the class EntityStorageConversions method restoreStashedProperties.
/**
* Moves stashed properties back from raw properties to properties.
*
* <p>Note: this piece of code assumes that stashed properties appear in the raw property list in
* stashed index order.
*
* @param storageEntity The EntityProto to modify.
*/
static void restoreStashedProperties(EntityProto storageEntity) {
ImmutableList<Property> properties = ImmutableList.copyOf(storageEntity.propertys());
ImmutableList<Property> rawProperties = ImmutableList.copyOf(storageEntity.rawPropertys());
ImmutableList.Builder<Property> badlyStashedProperties = ImmutableList.builder();
int propertyListIndex = 0;
storageEntity.clearProperty();
storageEntity.clearRawProperty();
for (Property rawProperty : rawProperties) {
if (rawProperty.hasStashed()) {
int stashed = rawProperty.getStashed();
int advance = stashed - storageEntity.propertySize();
if (// Not at the end (out-of-order, duplicate)
stashed < storageEntity.propertySize() || propertyListIndex + advance > properties.size()) {
// Past the end
// The value of stashed is bad.
badlyStashedProperties.add(rawProperty.clearStashed());
} else {
// Copy until before the position where the stashed property needs to be restored.
if (advance > 0) {
storageEntity.mutablePropertys().addAll(properties.subList(propertyListIndex, propertyListIndex + advance));
propertyListIndex = propertyListIndex + advance;
}
storageEntity.addProperty(rawProperty.clearStashed());
}
} else {
storageEntity.addRawProperty(rawProperty);
}
}
storageEntity.mutablePropertys().addAll(properties.subList(propertyListIndex, properties.size()));
storageEntity.mutablePropertys().addAll(badlyStashedProperties.build());
}
Aggregations