performance updates, mostly by caching computed values

This commit is contained in:
Michael Hunger
2012-06-21 04:56:20 +02:00
parent aaa72aaf8c
commit 0d04a76de1
7 changed files with 101 additions and 31 deletions

View File

@@ -50,9 +50,10 @@ public class FieldAccessorFactoryProviders<T> {
public List<FieldAccessListener> listeners() {
if (fieldAccessorListenerFactories == null) return null;
final List<FieldAccessListener> listeners = new ArrayList<FieldAccessListener>(fieldAccessorListenerFactories.size());
for (final FieldAccessorListenerFactory fieldAccessorListenerFactory : fieldAccessorListenerFactories) {
listeners.add(fieldAccessorListenerFactory.forField(property));
int count = fieldAccessorListenerFactories.size();
final List<FieldAccessListener> listeners = new ArrayList<FieldAccessListener>(count);
for (int i=0;i<count;i++) {
listeners.add(fieldAccessorListenerFactories.get(i).forField(property));
}
return listeners;
}
@@ -73,8 +74,10 @@ public class FieldAccessorFactoryProviders<T> {
}
public Map<Neo4jPersistentProperty, FieldAccessor> getFieldAccessors() {
final Map<Neo4jPersistentProperty, FieldAccessor> result = new HashMap<Neo4jPersistentProperty, FieldAccessor>(fieldAccessorFactoryProviders.size(),1);
for (final FieldAccessorFactoryProvider<T> fieldAccessorFactoryProvider : fieldAccessorFactoryProviders) {
int count = fieldAccessorFactoryProviders.size();
final Map<Neo4jPersistentProperty, FieldAccessor> result = new HashMap<Neo4jPersistentProperty, FieldAccessor>(count,1);
for (int i = 0; i < count; i++) {
FieldAccessorFactoryProvider<T> fieldAccessorFactoryProvider = fieldAccessorFactoryProviders.get(i);
final FieldAccessor accessor = fieldAccessorFactoryProvider.accessor();
result.put(fieldAccessorFactoryProvider.getProperty(), accessor);
}
@@ -82,8 +85,10 @@ public class FieldAccessorFactoryProviders<T> {
}
public Map<Neo4jPersistentProperty, List<FieldAccessListener>> getFieldAccessListeners() {
final Map<Neo4jPersistentProperty, List<FieldAccessListener>> result = new HashMap<Neo4jPersistentProperty, List<FieldAccessListener>>(fieldAccessorFactoryProviders.size(),1);
for (final FieldAccessorFactoryProvider<T> fieldAccessorFactoryProvider : fieldAccessorFactoryProviders) {
int count = fieldAccessorFactoryProviders.size();
final Map<Neo4jPersistentProperty, List<FieldAccessListener>> result = new HashMap<Neo4jPersistentProperty, List<FieldAccessListener>>(count,1);
for (int i = 0; i < count; i++) {
FieldAccessorFactoryProvider<T> fieldAccessorFactoryProvider = fieldAccessorFactoryProviders.get(i);
final List<FieldAccessListener> listeners = (List<FieldAccessListener>) fieldAccessorFactoryProvider.listeners();
result.put(fieldAccessorFactoryProvider.getProperty(), listeners);
}

View File

@@ -41,9 +41,8 @@ public class QueryFieldAccessorFactory implements FieldAccessorFactory {
}
@Override
public boolean accept(final Neo4jPersistentProperty f) {
final Query query = f.getAnnotation(Query.class);
return query != null && !query.value().isEmpty();
public boolean accept(final Neo4jPersistentProperty property) {
return property.hasQuery();
}
@@ -73,7 +72,7 @@ public class QueryFieldAccessorFactory implements FieldAccessorFactory {
if ((this.annotationParams.length % 2) != 0) {
throw new IllegalArgumentException("Number of parameters has to be even to construct a parameter map");
}
this.query = query.value();
this.query = property.getQuery();
this.iterableResult = Iterable.class.isAssignableFrom(property.getType());
this.target = resolveTarget(query,property);
queryEngine = this.template.queryEngineFor(QueryType.Cypher);

View File

@@ -94,4 +94,8 @@ public interface Neo4jPersistentProperty extends PersistentProperty<Neo4jPersist
boolean isUnique();
MappingPolicy obtainMappingPolicy(MappingPolicy currentMappingPolicy);
boolean hasQuery();
String getQuery();
}

View File

@@ -25,14 +25,7 @@ import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.model.AbstractPersistentProperty;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.GraphProperty;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.annotation.RelatedToVia;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.mapping.IndexInfo;
import org.springframework.data.neo4j.mapping.ManagedEntity;
import org.springframework.data.neo4j.mapping.MappingPolicy;
@@ -68,17 +61,33 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
private Association<Neo4jPersistentProperty> myAssociation;
private String defaultValue;
private Class<?> propertyType;
private String query;
private final boolean isNeo4jEntityType;
private final String neo4jPropertyName;
private final int hash;
public Neo4jPersistentPropertyImpl(Field field, PropertyDescriptor propertyDescriptor,
PersistentEntity<?, Neo4jPersistentProperty> owner, SimpleTypeHolder simpleTypeHolder, Neo4jMappingContext ctx) {
super(field, propertyDescriptor, owner, simpleTypeHolder);
this.hash = getField().hashCode();
this.annotations = extractAnnotations(field);
this.relationshipInfo = extractRelationshipInfo(field, ctx);
this.propertyType = extractPropertyType();
this.isNeo4jEntityType = isNeo4jPropertyType(getType());
this.neo4jPropertyName = createNeo4jPropertyName();
this.indexInfo = extractIndexInfo();
this.isIdProperty = annotations.containsKey(GraphId.class);
this.defaultValue = extractDefaultValue();
this.myAssociation = isAssociation() ? super.getAssociation() == null ? createAssociation() : super.getAssociation() : null;
this.propertyType = extractPropertyType();
this.query = extractQuery();
}
private String extractQuery() {
final Query query = getAnnotation(Query.class);
if (query == null) return null;
String value = query.value();
return value.trim().isEmpty() ? null : value;
}
private Class<?> extractPropertyType() {
@@ -186,6 +195,10 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
}
public String getNeo4jPropertyName() {
return neo4jPropertyName;
}
private String createNeo4jPropertyName() {
final Neo4jPersistentEntity entityClass = (Neo4jPersistentEntity) getOwner();
if (entityClass.useShortNames()) return getName();
return String.format("%s.%s", entityClass.getType().getSimpleName(), getName());
@@ -208,7 +221,7 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
@Override
public boolean isNeo4jPropertyType() {
return isNeo4jPropertyType(getType());
return isNeo4jEntityType;
}
private static boolean isNeo4jPropertyType(final Class<?> fieldType) {
@@ -359,6 +372,14 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
return getField().equals(((AbstractPersistentProperty)other).getField());
}
public int hashCode() {
return getField().hashCode();
return hash;
}
public boolean hasQuery() {
return this.query!=null;
}
public String getQuery() {
return query;
}
}

View File

@@ -44,6 +44,7 @@ public class Neo4jPersistentEntityImpl<T> extends BasicPersistentEntity<T, Neo4j
private Neo4jPersistentProperty relationshipType;
private StoredEntityType storedType;
private Neo4jPersistentProperty uniqueProperty;
private final boolean shouldUseShortNames;
/**
* Creates a new {@link Neo4jPersistentEntityImpl} instance.
@@ -56,6 +57,7 @@ public class Neo4jPersistentEntityImpl<T> extends BasicPersistentEntity<T, Neo4j
annotations.put(annotation.annotationType(),annotation);
}
managed = ManagedEntity.class.isAssignableFrom(information.getType());
shouldUseShortNames = shouldUseShortNames();
}
void updateStoredType(StoredEntityType storedType) {
@@ -74,6 +76,10 @@ public class Neo4jPersistentEntityImpl<T> extends BasicPersistentEntity<T, Neo4j
}
public boolean useShortNames() {
return shouldUseShortNames;
}
private boolean shouldUseShortNames() {
final NodeEntity graphEntity = getAnnotation(NodeEntity.class);
if (graphEntity != null) return graphEntity.useShortNames();
final RelationshipEntity graphRelationship = getAnnotation(RelationshipEntity.class);

View File

@@ -44,12 +44,18 @@ public class StoredEntityType {
private final Neo4jPersistentEntity<?> entity;
private final Collection<StoredEntityType> superTypes;
private final EntityAlias entityAlias;
private final Class<?> type;
private final boolean isNodeEntity;
private final boolean isRelationshipEntity;
StoredEntityType(Neo4jPersistentEntity<?> entity, Collection<Neo4jPersistentEntity<?>> superTypeEntities, final EntityAlias entityAlias) {
this.entity = entity;
this.entityAlias = entityAlias;
this.superTypes = collectSuperTypes(superTypeEntities);
this.alias = createAlias();
type = this.entity.getType();
isNodeEntity = this.entity.isNodeEntity();
isRelationshipEntity = this.entity.isRelationshipEntity();
}
private Collection<StoredEntityType> collectSuperTypes(Collection<Neo4jPersistentEntity<?>> superTypeEntities) {
@@ -92,15 +98,15 @@ public class StoredEntityType {
}
public Class<?> getType() {
return entity.getType();
return type;
}
public boolean isNodeEntity() {
return entity.isNodeEntity();
return isNodeEntity;
}
public boolean isRelationshipEntity() {
return entity.isRelationshipEntity();
return isRelationshipEntity;
}
@Override

View File

@@ -37,6 +37,7 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
protected final GraphDatabase graphDb;
protected final IndexProvider indexProvider;
private final Class<? extends PropertyContainer> clazz;
private Index<S> typesIndex;
public AbstractIndexingTypeRepresentationStrategy(GraphDatabase graphDb, IndexProvider indexProvider,
final String indexName, final Class<? extends PropertyContainer> clazz) {
@@ -44,11 +45,11 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
this.indexProvider = indexProvider;
INDEX_NAME = indexName;
this.clazz = clazz;
getTypesIndex();
typesIndex = createTypesIndex();
}
@SuppressWarnings("unchecked")
public Index<S> getTypesIndex() {
private Index<S> createTypesIndex() {
return (Index<S>) graphDb.createIndex(clazz, INDEX_NAME, IndexType.SIMPLE);
}
@@ -61,7 +62,8 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
@Override
public long count(StoredEntityType type) {
long count = 0;
final IndexHits<S> hits = getTypesIndex().get(INDEX_KEY, type.getAlias());
Object value = type.getAlias();
final IndexHits<S> hits = get(value);
while (hits.hasNext()) {
hits.next();
count++;
@@ -69,9 +71,27 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
return count;
}
private IndexHits<S> get(Object value) {
try {
return typesIndex.get(INDEX_KEY, value);
} catch(IllegalStateException ise) {
typesIndex=createTypesIndex();
return typesIndex.get(INDEX_KEY, value);
}
}
@Override
public void preEntityRemoval(S state) {
getTypesIndex().remove(state);
remove(state);
}
private void remove(S state) {
try {
typesIndex.remove(state);
} catch(IllegalStateException ise) {
typesIndex=createTypesIndex();
typesIndex.remove(state);
}
}
@Override
@@ -92,19 +112,28 @@ public abstract class AbstractIndexingTypeRepresentationStrategy<S extends Prope
if (indexProvider != null) {
value = indexProvider.createIndexValueForType(type.getAlias());
}
getTypesIndex().add(element, INDEX_KEY, value);
add(element, value);
for (StoredEntityType superType : type.getSuperTypes()) {
addToTypesIndex(element,superType);
}
}
private void add(S element, Object value) {
try {
typesIndex.add(element, INDEX_KEY, value);
} catch(IllegalStateException ise) {
typesIndex = createTypesIndex();
typesIndex.add(element, INDEX_KEY, value);
}
}
@SuppressWarnings("hiding")
private ClosableIterable<S> findAllRelBacked(StoredEntityType type) {
Object value = type.getAlias();
if (indexProvider != null)
value = indexProvider.createIndexValueForType(type.getAlias());
final IndexHits<S> allEntitiesOfType = getTypesIndex().get(INDEX_KEY, value);
final IndexHits<S> allEntitiesOfType = get(value);
return new ClosableIndexHits<S>(allEntitiesOfType);
}