Topic maps, trait to provide lazy and eager indices
my $tm = new TM... # get any map use Class::Trait; Class::Trait->apply ($tm, "TM::IndexAble"); # apply the trait # add a lazy cache for subclassing and instanceOf $tm->index ({ axis => 'taxo' }); $tm->index ({ axis => 'taxo', closed => 0}); # the same, lazy is NOT closed # add eager cache (= index) for taxonometrics $tm->index ({ axis => 'taxo', closed => 1}); # eager is closed, will take some time # add index for characteristics $tm->index ({ axis => 'char'}); $tm->index ({ axis => 'char', closed => 1}); # can be closed as well # ditto for reification $tm->index ({ axis => 'reify'}); $tm->index ({ axis => 'reify', closed => 1}); # create index/caches, but separate from map itself $tm->index ({ axis => 'reify', closed => 0, detached => {} }); my %stats = $tm->index; # get current indices + statistics
Like TM::Index, this package also adds index/caching capabilities to any topic map stored via \s-1TM\s0 (or any of its subclasses). The difference, though, is that the index/caching functionality is added as a trait, and not via an explicit attachment. The indices are - by default - part of the map, and not standalone objects as with TM::Index.
When you add an index/cache then you simply use precomputed navigation results for the \s-1TM\s0 methods \*(C`match_forall\*(C' and \*(C`is_reified\*(C' (but not used for \*(C`reifies\*(C').
As with TM::Index you can create caching (lazy indexing) and full indices (eager precaching).
To enrich a map with an index/cache, you call the method \*(C`index\*(C' provided here. The index/cache will by default be stored inside the map. That may be convenient in most cases.
If not - as with some storage techniques - you can detach the index to live within your scope. For that purpose you simply pass in an empty hash reference. It is then your responsibility to get rid of it afterwards.
Having the index detached also opens the way for you to make the index persistent.
Following methods are mixed into the class/object:
$tm->index ({ %spec }, ...) This method establishes one or more indices/caches to the topic map. Each cache/index is described with its own hash reference. Which navigation axes should be covered by a single cache/index is specified with the \*(C`axis\*(C' field. It can have as value one of the axes in TM::Axes, or one of the following values:
Shortcut for the axes: \*(C`subclass.type\*(C' \*(C`superclass.type\*(C' \*(C`class.type\*(C' \*(C`instance.type\*(C' Shortcut for the axes: \*(C`char.topic\*(C' \*(C`char.value\*(C' \*(C`char.type\*(C' \*(C`char.type.value\*(C' \*(C`char.topic.type\*(C'
To control whether a cache (lazy indexing) or a full index (eager caching) should be used, the field \*(C`closed\*(C' can have two values (default is 0): The default is to keep the index lazy. In this mode the index is empty at the start and it will learn more and more on its own. In this sense, the index lives under an open world assumption (hence the name), as the absence of information does not mean that there is no result. A closed world index has to be populated to be useful. If a query is launched and the result is stored in the index, then it will be used, like for an open index. If no result in the index is found for a query, the empty result will be assumed.
Additionally, a field \*(C`detached\*(C' can be passed in for one cache/index. It \s-1MUST\s0 contain a hash reference. Example: $tm->index ( { axis => 'reify', closed => 0, detached => {} }, { axis => 'char', closed => 1 } ); The method returns a hash with some statistical information for every axis: Number of requests since inception of the index. Number of cache hits since inception. For an eager cache (i.e. index) this number should be the same as \*(C`requests\*(C'
$tm->deindex ($axis, ....) $tm->deindex ($index, ....) This method gets rid of certain indices/caches, as specified by their axes. Since v1.55: You can also pass in the hash reference of the index (in the detached case). Since v1.55: Also the expansion of axes (like for \*(C`index\*(C') works now.
\s-1TM\s0, TM::Index
Copyright 20(10) by Robert Barta, <[email protected]>
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.