In VIATRA Query, all pattern matching (query evaluation) is carried out in ViatraQueryEngine instances that are accessed through the user-friendly generated classes of the public API. The ViatraQueryEngine associated to your patterns can be accessed and managed through the EngineManager singleton class, to track and manipulate their lifecycles.
A ViatraQueryEngine is instantiated with a Scope implementation that describes the model the query should work with. By default, in case of EMF it is recommended to initialize an EMFScope instance with the ResourceSet containing the EMF model. For more details about scopes see Query Scopes.
By default, for each scope a single, managed ViatraQueryEngine is created, which is shared by all objects that access VIATRA Query’s features through the generated API. The ViatraQueryEngine is attached to the scope and it is retained on the heap as long as the model itself is there. It will listen on update notifications stemming from the given model in order to maintain live results. If you release all references to the model (e.g. unload the resource), the ViatraQueryEngine can also be garbage collected (as long as there are no other inbound references on it).
In all, for most (basic) scenarios, the following workflow should be followed:
initialize/load the model
initialize your ViatraQueryEngine instance
initialize pattern matchers, or groups of pattern matchers and use them
if you release the model and your ViatraQueryEngine instance, all resources will be freed by the garbage collector.
For advanced scenarios (if you wish to manage lifecycles at a more finegrained level), you have the option of creating unmanaged ViatraQueryEngines and dispose of them independently of your instance model. For most use-cases though, we recommend the use of managed engines, this is the default and optimized behavior, as these engines can share common indices and caches to save memory and CPU time. The EngineManager ensures that there will be no duplicated engine for the same model root (Notifier) object. Creating an unmanaged engine will give you certain additional benefits, however additional considerations should be applied.
If you want to remove the matchers from the engine you can call the
wipe() method on it. It discards any pattern matcher caches and forgets the known patterns. The base index built directly on the underlying EMF model, however, is kept in memory to allow reuse when new pattern matchers are built. If you don’t want to use it anymore call the
dispose() instead, to completely disconnect and dismantle the engine.
Never call wipe or dispose on any engine that were not explicitly created by you; any created matcher over the engine becomes unusable.