Skip to content

Commit

Permalink
Make attribute definition lookup faster
Browse files Browse the repository at this point in the history
Instead of using the default (iterative) implementation, we provide
a map that can be used for common cases - immutable definition,
case-insensitive searches.

Preliminary. Does not include e.g. composite definitions (when aux OCs
are used).
  • Loading branch information
mederly committed May 2, 2023
1 parent 52965ae commit e930f67
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import com.evolveum.midpoint.prism.annotation.ItemDiagramSpecification;
import com.evolveum.midpoint.util.QNameUtil;

import static com.evolveum.midpoint.util.MiscUtil.stateCheck;

/**
* Common implementation for both {@link ResourceObjectClassDefinition} and {@link ResourceObjectTypeDefinition}.
*
Expand Down Expand Up @@ -67,6 +69,14 @@ public abstract class AbstractResourceObjectDefinitionImpl
@NotNull final DeeplyFreezableList<ResourceAttributeDefinition<?>> attributeDefinitions =
new DeeplyFreezableList<>();

/**
* Indexed attribute definitions for faster access.
* Created (as immutable map) on freezing.
*
* Temporary/experimental.
*/
private Map<QName, ResourceAttributeDefinition<?>> attributeDefinitionMap;

/**
* Names of primary identifiers. They are the same for both raw and refined definitions.
* (Currently we do not support tweaking of this information.)
Expand Down Expand Up @@ -169,6 +179,15 @@ public List<? extends ResourceAttributeDefinition<?>> getAttributeDefinitions()
return associationDefinitions;
}

@Override
public @Nullable ResourceAttributeDefinition<?> findAttributeDefinition(QName name, boolean caseInsensitive) {
if (caseInsensitive || isMutable()) {
return ResourceObjectDefinition.super.findAttributeDefinition(name, caseInsensitive);
} else {
return attributeDefinitionMap.get(name);
}
}

@NotNull
@Override
public Collection<ResourceAttributeDefinition<?>> getPrimaryIdentifiers() {
Expand Down Expand Up @@ -439,12 +458,22 @@ public boolean canRepresent(QName typeName) {
@Override
protected void performFreeze() {
attributeDefinitions.freeze();
createAttributeDefinitionMap();
associationDefinitions.freeze();
primaryIdentifiersNames.freeze();
secondaryIdentifiersNames.freeze();
auxiliaryObjectClassDefinitions.freeze();
}

private void createAttributeDefinitionMap() {
var map = new HashMap<QName, ResourceAttributeDefinition<?>>();
attributeDefinitions.forEach(def -> {
var previous = map.put(def.getItemName(), def);
stateCheck(previous == null, "Multiple definitions for attribute %s in %s", def, this);
});
attributeDefinitionMap = Collections.unmodifiableMap(map);
}

@Override
public void accept(Visitor<Definition> visitor) {
visitor.visit(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ protected void copyDefinitionDataFrom(ResourceAttributeContainerDefinition sourc

@Override
public <T> ResourceAttributeDefinition<T> findAttributeDefinition(QName elementQName, boolean caseInsensitive) {
var ctd = complexTypeDefinition;
if (ctd instanceof ResourceObjectDefinition) {
// Shortcut to more efficient lookup implementation - FIXME this is a hack
//noinspection unchecked
return (ResourceAttributeDefinition<T>)
((ResourceObjectDefinition) ctd).findAttributeDefinition(elementQName, caseInsensitive);
}
//noinspection unchecked
return findLocalItemDefinition(ItemName.fromQName(elementQName), ResourceAttributeDefinition.class, caseInsensitive);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,6 @@ public ResourceObjectTypeDefinition deepClone(@NotNull DeepCloneOperation operat
}
//endregion

//region ==== Parsing =================================================================================
void add(ResourceAttributeDefinition<?> refinedAttributeDefinition) {
attributeDefinitions.add(refinedAttributeDefinition);
}
//endregion

//region Diagnostic output, hashCode/equals =========================================================

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ public Collection<ResourceObjectPattern> getProtectedAccountPatterns(
public @NotNull ResourceObjectDefinition computeCompositeObjectDefinition(
@NotNull Collection<QName> auxObjectClassQNames)
throws SchemaException, ConfigurationException {
if (auxObjectClassQNames.isEmpty()) {
return getObjectDefinitionRequired();
}
Collection<ResourceObjectDefinition> auxiliaryObjectClassDefinitions = new ArrayList<>(auxObjectClassQNames.size());
for (QName auxObjectClassQName : auxObjectClassQNames) {
ResourceObjectDefinition auxObjectClassDef = getResourceSchema().findObjectClassDefinition(auxObjectClassQName);
Expand All @@ -267,6 +270,7 @@ public Collection<ResourceObjectPattern> getProtectedAccountPatterns(
}
auxiliaryObjectClassDefinitions.add(auxObjectClassDef);
}
// FIXME the attribute lookup in this definition will be slow (iterating through all the definitions)
return new CompositeObjectDefinitionImpl(
getObjectDefinitionRequired(),
auxiliaryObjectClassDefinitions);
Expand Down

0 comments on commit e930f67

Please sign in to comment.