Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Efficiently Traversing an Entire EMF Model
Efficiently Traversing an Entire EMF Model [message #894899] Wed, 11 July 2012 01:18 Go to next message
Vinny Vallarine is currently offline Vinny VallarineFriend
Messages: 9
Registered: June 2012
Junior Member
I have a recursive method that looks like:

void buildAllFiles(final EObject eObject) throws InterruptedException {

if (!this.objectsAlreadyVisited.add(eObject)) {
return;
}

//this.saveFile(eObject);

for (EObject containedObject : eObject.eContents()) {
this.buildAllFiles(containedObject, monitor);
}

for (EObject referencedObject : eObject.eCrossReferences()) {
this.buildAllFiles(referencedObject, monitor);
}
}


The goal of the method is to find ALL XMI files that back the resources on disk. This method works 100% of the time. The issue I have is with regard to performance. For very large models (5GB+), lots of time is spent in this recursive method. But this is only an issue on the first time through the method. If I call this method a second time while keeping my application up and running, it flies through. I've narrowed it down to the fact that resources are getting 'resolved' the first time but don't have to the successive times through.

Just as a test, I verified this by putting a EcoreUtil.resolveAll(<my root EOBject>) in a side thread that constantly keeps all references 'resolved' in my model. When I do this, EVERY time I run through my recursive method above results in the same speedy execution, even the first time.

My question. Can I traverse through an entire model like above but without 'resolving' any references, just traversing them to lookup their backing files? I have a feeling I'm not fully understanding the 'resolving' concept here.

[Updated on: Wed, 11 July 2012 01:18]

Report message to a moderator

Re: Traverse and Entire EMF Model [message #894924 is a reply to message #894899] Wed, 11 July 2012 06:12 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 30463
Registered: July 2009
Senior Member
Vinny,

Comments below.

On 11/07/2012 3:18 AM, Vinny Vallarine wrote:
> I have a recursive method that looks like:
>
> void buildAllFiles(final EObject eObject) throws InterruptedException {
>
> if (!this.objectsAlreadyVisited.add(eObject)) {
> return;
> }
>
> //this.saveFile(eObject);
>
> for (EObject containedObject : eObject.eContents()) {
> this.buildAllFiles(containedObject, monitor);
> }
>
> for (EObject referencedObject : eObject.eCrossReferences()) {
> this.buildAllFiles(referencedObject, monitor);
> }
> }
>
>
> The goal of the method is to find ALL XMI files that back the
> resources on disk. This method works 100% of the time. The issue I
> have is with regard to performance. For very large models (5GB+),
> lots of time is spent in this recursive method.
Of course the time spent will be proportional to the size of the model.
I imagine it grows linearly, or nearly so, with the number of
containment and cross references.
> But this is only an issue on the first time through the method. If I
> call this method a second time while keeping my application up and
> running, it flies through.
That's a good thing...
> I've narrowed it down to the fact that resources are getting
> 'resolved' the first time but don't have to the successive times through.
Yes, proxies are resolved the first time they're visited and are
replaced with their resolved result.
> Just as a test, I verified this by putting a EcoreUtil.resolveAll(<my
> root EOBject>) in a side thread that constantly keeps all references
> 'resolved' in my model. When I do this, EVERY time I run through my
> recursive method above results in the same speedy execution, even the
> first time.
> My question. Can I traverse through an entire model like above but
> without 'resolving' any references, just traversing them to lookup
> their backing files?
Yes, you can cast the result of eContents() and eCrossReferences() to
InternalEList and use basicList or basicIterator to get at the
unresolved objects. You can use EObject.eIsProxy to determine if an
object is a proxy and you can cast EObjects to InternalEObject and use
eProxyURI to determine the proxy URI. If you trim the fragment from
that URI, you have the URI of a resource you need to save. Likely you
need to visit all the contents of that resource (rather than visiting
the contents or references of the proxy, which generally won't have either).
> I have a feeling I'm not fully understanding the 'resolving' concept
> here.
Re: Traverse and Entire EMF Model [message #895007 is a reply to message #894924] Wed, 11 July 2012 11:43 Go to previous messageGo to next message
Vinny Vallarine is currently offline Vinny VallarineFriend
Messages: 9
Registered: June 2012
Junior Member
So, will implementing something like you mentioned allow me to rip through the model WITHOUT incurring the initial resolving latency? That is, will it traverse quickly EVERYTIME, not just after the first traversal, as it does currently.

If so, what calls in my original method cause the resolving? Must be the call to eContents() and eCrossReferences(), correct? If so, I'm not sure how simply casting those calls as you say would prevent the resolving.
Re: Traverse and Entire EMF Model [message #895024 is a reply to message #895007] Wed, 11 July 2012 12:44 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 30463
Registered: July 2009
Senior Member
Vinny,

Comments below.

On 11/07/2012 1:43 PM, Vinny Vallarine wrote:
> So, will implementing something like you mentioned allow me to rip
> through the model WITHOUT incurring the initial resolving latency?
Yes, no proxies will be resolve with this approach, but, presumably
you'll need to load the referenced resource and traverse its contents.
> That is, will it traverse quickly EVERYTIME, not just after the first
> traversal, as it does currently.
Yes.
>
> If so, what calls in my original method cause the resolving?
Iterating over the contents resolves each proxy before returning it from
the iterator.
> Must be the call to eContents() and eCrossReferences(), correct?
No, those lists are just "views". The process of traverse it it will
resolve the proxies..
> If so, I'm not sure how simply casting those calls as you say would
> prevent the resolving.

I didn't say just cast it, I said to call basicEList or basicIterator on
the result of the cast and iterating over that instead.
Re: Traverse and Entire EMF Model [message #895029 is a reply to message #895024] Wed, 11 July 2012 12:59 Go to previous messageGo to next message
Vinny Vallarine is currently offline Vinny VallarineFriend
Messages: 9
Registered: June 2012
Junior Member
Ah, so I replaced my original traversal with:

InternalEList<EObject> containedInternalList = (InternalEList<EObject>) eObject.eContents();
for (EObject containedObject : containedInternalList.basicList()) {
this.addAllContentFilesInner(containedObject, monitor);
}

InternalEList<EObject> referencedInternalList = (InternalEList<EObject>) eObject.eCrossReferences();
for (EObject referencedObject : referencedInternalList.basicList()) {
this.addAllContentFilesInner(referencedObject, monitor);
}


This did in fact fly through, but unfortunately, only grabbed a fraction of the files. I'm assuming I need to 'resolve' at some point for me to get to every possible object, transitively. Would you agree?

[Updated on: Wed, 11 July 2012 13:02]

Report message to a moderator

Re: Traverse and Entire EMF Model [message #895032 is a reply to message #895029] Wed, 11 July 2012 13:05 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 30463
Registered: July 2009
Senior Member
Vinny,

Yes, you need to work directly with the proxy URIs as I suggested. Most
likely you need to load the resource and walk the contents exactly this
same way.

On 11/07/2012 2:59 PM, Vinny Vallarine wrote:
> Ah, so I replaced my original traversal with:
>
> InternalEList<EObject> containedInternalList =
> (InternalEList<EObject>) eObject.eContents();
> for (EObject containedObject : containedInternalList.basicList()) {
> this.addAllContentFilesInner(containedObject, monitor);
> }
>
> InternalEList<EObject> referencedInternalList =
> (InternalEList<EObject>) eObject.eCrossReferences();
> for (EObject containedObject : referencedInternalList.basicList()) {
> this.addAllContentFilesInner(containedObject, monitor);
> }
>
>
> This did in fact fly through, but unfortunately, only grabbed a
> fraction of the files. I'm assuming I need to 'resolve' at some point
> for me to get to every possible object, transitively. Would you agree?
>
Previous Topic:[EMF Validation] EMF Validation Framework
Next Topic:Generating Setters and Getters API for EMF.Edit commands
Goto Forum:
  


Current Time: Mon Sep 23 03:31:58 GMT 2019

Powered by FUDForum. Page generated in 0.02160 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top