Bug 404536 - Coherence cache issue with CollectionAnnotator's WeakHashMap
Summary: Coherence cache issue with CollectionAnnotator's WeakHashMap
Status: CLOSED FIXED
Alias: None
Product: Epsilon
Classification: Modeling
Component: Core (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 blocker (vote)
Target Milestone: ---   Edit
Assignee: Dimitris Kolovos CLA
QA Contact:
URL:
Whiteboard:
Keywords: consistency
Depends on:
Blocks:
 
Reported: 2013-03-28 05:38 EDT by Sébastien Latre CLA
Modified: 2013-09-01 08:32 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sébastien Latre CLA 2013-03-28 05:38:16 EDT
There seems to be a board effect of https://bugs.eclipse.org/bugs/show_bug.cgi?id=338087 which in some cases fails to act correctly due to the garbage collection. Tested with 0.9.1 and 1.0.0.

This bug is quite hard to reproduce because it depends on memory consumption (high memory consumption will make the garbage collection pass more frequently which can ease to repoduce this bug).
However, the problem is quite simple to understand.

The problem relies in collection annotation with EMF.
Here is a scenario that explains the bug which causes a NullPointerException breaking therefore the validation phase (that's why I put the bug as blocker):

# org.eclipse.epsilon.eol.execute.PointExecutor#execute(AST ast, IEolContext context, boolean returnSetter) line 42
## org.eclipse.epsilon.emc.emf.EmfPropertyGetter#invoke(Object object, String property)
LOGIC_1 to compute collection's kind:
collection (eObject) of type EObjectContainmentWithInverseEList
EStructuralFeature sf = EmfUtil.getEStructuralFeature(eObject.eClass(), property)
sf != null && sf.isMany() && sf.isOrdered() && sf.isUnique() => annotation = OrderedSet
=> CollectionAnnotators's cache is set to OrderedSet for the collection.
# org.eclipse.epsilon.eol.execute.PointExecutor#execute(AST ast, IEolContext context, boolean returnSetter) line 43
## org.eclipse.epsilon.eol.execute.operations.declarative.ExistsOperation#execute(Object obj, AST ast, IEolContext context) line 28
Collection selected = (Collection) selectOperation.execute(obj, ast, context);
### org.eclipse.epsilon.eol.types.EolCollectionType#createSameType(Collection c)
Test if it's Bag
#### org.eclipse.epsilon.eol.types.EolCollectionType#isType(Object o)
##### org.eclipse.epsilon.eol.types.EolCollectionType#getTypeOf(Collection c)
Check if annotation exists for collection in CollectionAnnotator's cache.
Got it: OrderedSet
=> collection is not a Bag
### org.eclipse.epsilon.eol.types.EolCollectionType#createSameType(Collection c)
Test if it's Sequence
#### org.eclipse.epsilon.eol.types.EolCollectionType#isType(Object o)
##### org.eclipse.epsilon.eol.types.EolCollectionType#getTypeOf(Collection c)
Check if annotation exists for collection in CollectionAnnotator's cache.
Got it: OrderedSet
=> collection is not a Sequence
### GARBAGE COLLECTION PASS and empties the CollectionAnnotator's cache (or at least reduce the size by removing the line concerning of the collection)
### org.eclipse.epsilon.eol.types.EolCollectionType#createSameType(Collection c)
Test if it's OrderedSet
#### org.eclipse.epsilon.eol.types.EolCollectionType#isType(Object o)
##### org.eclipse.epsilon.eol.types.EolCollectionType#getTypeOf(Collection c)
Check if annotation exists for collection in CollectionAnnotator's cache.
Cannot get it !
Try to rebuild the value with LOGIC_2
collection !instanceof EolSequence && collection instanceof List && !collection instanceof Set => New annotation is Sequence
=> We have a different result: This sould be an OrderedSet!
=> collection is not an OrderedSet.
### org.eclipse.epsilon.eol.types.EolCollectionType#createSameType(Collection c)
Test if it's Set
#### org.eclipse.epsilon.eol.types.EolCollectionType#isType(Object o)
##### org.eclipse.epsilon.eol.types.EolCollectionType#getTypeOf(Collection c)
Check if annotation exists for collection in CollectionAnnotator's cache.
Cannot get it !
Try to rebuild the value with LOGIC_2 => New annotation is Sequence
=> collection is not a Set.
### org.eclipse.epsilon.eol.types.EolCollectionType#createSameType(Collection c)
=> collection is not either a Bag, a Sequence, an OrderedSet or a Set => return null
## org.eclipse.epsilon.eol.execute.operations.declarative.ExistsOperation#execute(Object obj, AST ast, IEolContext context) line 30
return selected.size() > 0; with selected == null => NullPointerException
Comment 1 Dimitris Kolovos CLA 2013-03-28 06:13:36 EDT
Many thanks for reporting this. I've investigated a bit and the only clean solution I can see is to get rid of CollectionAnnotator altogether. It is currently only used to annotate EMF ELists but it should be possible to figure out uniqueness/ordering by checking to see if the list in question is an EcoreEList and then using its getEStructuralFeature() method to get access to the underlying structural feature.

This will require an additional extension point for collection type resolvers (the core of Epsilon is decoupled from EMF) so this may take a couple of weeks to fix and test.
Comment 2 Dimitris Kolovos CLA 2013-03-28 11:56:25 EDT
I believe I've now fixed this in the SVN (r2167). Could you please check and let me know whether it works for you?
Comment 3 Sébastien Latre CLA 2013-04-05 10:41:08 EDT
I couldn't use the complete new version from the trunk as I have some other constraints but I merged your fix inside my version and so far I have not been able to reproduce the problem after several tries.
Your fix looks awesome and really simple. Fortunately you corrected it because I wouldn't have done this way (quite hard to understand at once the Epsilon split between engine and EMF...)

However, does the remove of the cache not harmful for the overall performances? With your fix it's quite easy to add a WeakHashMap agan inside EmfCollectionTypeResolver as we can build the the type again from the collection itself. That's just a question in fact.

Anyway, thanks very much for your reactivity!
Comment 4 Dimitris Kolovos CLA 2013-04-06 05:31:11 EDT
Many thanks for your feedback. Caching previously computed collection types sounds like a very good idea indeed. I've implemented this at the level of EolCollectionType in R2185.
Comment 5 Dimitris Kolovos CLA 2013-04-27 05:46:12 EDT
Fixed in the latest interim version (1.0.0.201304211529).
Comment 6 Dimitris Kolovos CLA 2013-09-01 08:32:21 EDT
Fixed in 1.1