Bug 146411 - CrossReferenceAdapter is consuming too time iterating over derived features and never uses the values of these features
Summary: CrossReferenceAdapter is consuming too time iterating over derived features a...
Status: RESOLVED FIXED
Alias: None
Product: GMF-Runtime
Classification: Modeling
Component: General (show other bugs)
Version: 1.0   Edit
Hardware: PC Windows XP
: P3 normal
Target Milestone: 1.0.1   Edit
Assignee: Anthony Hunter CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed, performance
Depends on:
Blocks:
 
Reported: 2006-06-11 10:26 EDT by Maneesh CLA
Modified: 2010-07-19 12:24 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Maneesh CLA 2006-06-11 10:26:55 EDT
In two methods of CrossReferenceAdapter, #setTarget and #updateImportsAndExports there is an iterator to iterate over crossreference values of given EObject. This iterator also computes derived features.

Later on in these methods, there is a check to ignore unchangeable feature. The performance is improved a lot by creating an iterator that ignores unchangeable features.

Please use getOptimizedCrossReferenceIterator instead of eCrossReferences().iterator in #setTarget and #updateImportsAndExports


Please see the code below...

    private static Map eClassToChangeableFeatures = new HashMap();
    private static List nullList = new ArrayList(1);
    private static List getCrossReferencesChangeableFeatures(EClass eCls) {
        List features = (List)eClassToChangeableFeatures.get(eCls);
        if(features == null) {
            features = nullList;
            EStructuralFeature [] crossReferenceFeatures = 
                ((EClassImpl.FeatureSubsetSupplier)eCls.getEAllStructuralFeatures()).crossReferences();
            if(crossReferenceFeatures != null) {
                features = new ArrayList(crossReferenceFeatures.length);
                for(int i=0; i<crossReferenceFeatures.length; i++) {
                    EStructuralFeature feature = crossReferenceFeatures[i];
                    if(feature.isChangeable())
                        features.add(feature);
                }
            }
            eClassToChangeableFeatures.put(eCls, features);
        }
        return features != nullList ? features : null;
    }

    private EContentsEList.FeatureIterator getOptimizedCrossReferenceIterator(EObject eObj) {
        List features = getCrossReferencesChangeableFeatures(eObj.eClass());
        if(features != null) {
            EContentsEList list = null;
            if(features.size() > 0) {
                list = new ECrossReferenceEList(eObj, (EStructuralFeature[])features.toArray(new EStructuralFeature[features.size()])) {
                    // to get to the protected constructor
                };
            } else {
                list = ECrossReferenceEList.EMPTY_CROSS_REFERENCE_ELIST;
            }
    
            return (EContentsEList.FeatureIterator) (resolve() ? list.iterator()
                : ((InternalEList) list)
                        .basicIterator());
        }
        return (EContentsEList.FeatureIterator)ECrossReferenceEList.EMPTY_CROSS_REFERENCE_ELIST.iterator();
    }
Comment 1 Anthony Hunter CLA 2006-07-11 11:20:31 EDT
Can you put this code in a patch?
Comment 2 Anthony Hunter CLA 2006-07-11 12:09:28 EDT
OK, worked with Maneesh and committed the code fixes to R1_0_maintenance
Comment 3 Anthony Hunter CLA 2006-07-11 16:43:13 EDT
Hi Christian,

You say we need worry about derived features.

What is the use case that is invalidated by the patch?
Comment 4 Maneesh CLA 2006-07-11 18:07:51 EDT
I think the defect description needs to be modified, because the suggested fix is only to ignore non-changeable features. Ignoring these features when iterating is what the iterating loop was doing, and hence there was no need to create an iterator for these features.

For a typical metamodel, it is observed that the improvement was 10%.
Comment 5 Christian Damus CLA 2006-07-11 18:20:00 EDT
Hi, Anthony,

The problem is, that some features marked as "derived" cannot be interpreted as being unchangeable (read-only) features that don't matter to the computation of imports and exports.  A particular case of this occurs in feature maps, which are relatively common in EMF metamodels imported from XSD.

In a feature map representing an XSD group, where the group members are EReferences, these EReferences are marked as "derived" because their values are actually derived from the feature map EAttribute (a list of EFeatureMapEntry).  Despite being derived, they are entirely changeable.  If the cross-referencer ignores these features, then it will not discover the cross-references that they contain, which may result in resource-level imports and exports being missed.

However, it may be that the listening for proxy resolution brings these derived cross-references to the adapter's attention and gets imports and exports registered, later.  I'm working on a JUnit test with a metamodel defining a feature map to see ...
Comment 6 Linda Damus CLA 2006-07-12 13:59:47 EDT
The discussion about the potential problem with feature maps has moved to bug 147312.

I have re-applied the original fix.
Comment 7 Eclipse Webmaster CLA 2010-07-19 12:24:46 EDT
[GMF Restructure] Bug 319140 : product GMF and component
Runtime EMF was the original product and component for this bug