performance updates, mostly by caching computed values
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -94,4 +94,8 @@ public interface Neo4jPersistentProperty extends PersistentProperty<Neo4jPersist
|
||||
boolean isUnique();
|
||||
|
||||
MappingPolicy obtainMappingPolicy(MappingPolicy currentMappingPolicy);
|
||||
|
||||
boolean hasQuery();
|
||||
|
||||
String getQuery();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user