Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimizations for applying decorators on a model #856

Open
sanketshevkar opened this issue Jun 5, 2024 · 0 comments
Open

Optimizations for applying decorators on a model #856

sanketshevkar opened this issue Jun 5, 2024 · 0 comments

Comments

@sanketshevkar
Copy link
Member

sanketshevkar commented Jun 5, 2024

Discussion 馃棧

The current implementation of applyDecorators is not optimized, <"Add profiling and benchmarking data here.">.

Context

The process of applying decorators on a model today has a very brute force approach wherein we try apply each and every decorator on all the declarations, properties, map elements etc. [decorateModels]
This works fine for small models with small DCS. But for large models with large DCS this process creates a bottle neck.

Detailed Description

  • Ideally we would need a index of sort wherein we can store all the decorators that target to a specific declaration, property or map-element. For this we could traverse all all the commands and create an index first, then traverse the metamodel object to the find and apply the decorator on that particular element.

Challenge: Since a dcs is not tightly linked to a particular model, we need to define a target/targets for each an and every decorator.
Each decorator command's target can be defined in almost 5!=120 ways (we don't allow certain combinations eg: property and properties together), which makes it very difficult on the first pass to find out which model element/s is that decorator targeted at.

  • So I tried to write up a logic wherein we can map decorators based on the declarations, properties, map elements, namespace and types. Then try to apply them on metamodel element based on this logic. This is not as optimized as the first approach but still better than traversing over each and every model element against all the decorator commands. feat(dcs): optimize decorate models聽#857

Challenge: This works, but we face an issue with specificity, in cases of two or more commands in the same DCS which has the same decorator and target the same element but targeted in different way. The decorator which is a part of the last command will get applied. Unless and until we have a way to define specificity for such similar decorators, its very difficult to predict which one will get applied. Also, another question that comes up is that why would we allow a user to define a same decorator (name is same, but arguments could differ) within the same DCS (assuming they target to the same model) without any rule for specificity.

{
    "$class" : "org.accordproject.decoratorcommands@0.3.0.DecoratorCommandSet",
    "name" : "web",
    "version": "1.0.0",
    "commands" : [
        {
            "$class" : "org.accordproject.decoratorcommands@0.3.0.Command",
            "type" : "UPSERT",
            "target" : {
                "$class" : "org.accordproject.decoratorcommands@0.3.0.CommandTarget",
                "namespace" : "test@1.0.0",
                "declaration" : "Person",
                "property" : "bio"
            },
            "decorator" : {
                "$class" : "concerto.metamodel@1.0.0.Decorator",
                "name" : "Form",
                "arguments" : [
                    {
                        "$class" : "concerto.metamodel@1.0.0.DecoratorString",
                        "value" : "inputType"
                    },
                    {
                        "$class" : "concerto.metamodel@1.0.0.DecoratorString",
                        "value" : "textArea"
                    }
                ]
            }
        },
        {
            "$class" : "org.accordproject.decoratorcommands@0.3.0.Command",
            "type" : "UPSERT",
            "target" : {
                "$class" : "org.accordproject.decoratorcommands@0.3.0.CommandTarget",
                "type" : "concerto.metamodel@1.0.0.StringProperty"
            },
            "decorator" : {
                "$class" : "concerto.metamodel@1.0.0.Decorator",
                "name" : "Form",
                "arguments" : [
                    {
                        "$class" : "concerto.metamodel@1.0.0.DecoratorString",
                        "value" : "inputType"
                    },
                    {
                        "$class" : "concerto.metamodel@1.0.0.DecoratorString",
                        "value" : "text"
                    }
                ]
            }
        }
    ]
}

In this example both decorators have the same name, but the second decorator would get we'll be seen on the final model based on the current logic. With changes proposed in #857 it's difficult to predict which was the last one in the list. The decorators get segregated based on specificity of the command targets.
Specificity of targets defined as:
type > property > mapElements > declaration > namespace.

This is based on the heuristic that if a type is defined in target, it will take the highest precedence amongst all other target properties. Next highest precedence is for properties and map-elements, then declarations and then namespace.

target(namespace) = applyDecoratorTo all decl in namespace
target(namespace + declaration) = applyDecoratorTo to declaration
target(namespace + declaration + property) = applyDecoratorTo  property
target(namespace + declaration + mapElement) = applyDecoratorTo mapElement
target(namespace + declaration + property/mapElement + type) = applyDecoratorTo to type

Logic for executeCommand

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant