|
|
|
@ -191,8 +191,85 @@ possibility.)
|
|
|
|
|
|
|
|
|
|
\section{Annotations}
|
|
|
|
|
|
|
|
|
|
\XXX{scoping, annotator creation, advantages of storing data in annotations and
|
|
|
|
|
not vertices. Annotator protocol and posibility of export. Various uses of annotators: enhancing, analysis, visualisation. heapq}
|
|
|
|
|
Once a TopologyV3 is obtained, it may be annotated. An Annotator may create an
|
|
|
|
|
Annotation, which is then stored as a part of an AnnotatedTopology. We now
|
|
|
|
|
explore design of these objects in detail.
|
|
|
|
|
|
|
|
|
|
An Annotation is essentially only a holder for any \uv{tags} that are to be
|
|
|
|
|
attached to the topology. These are represented by a dictionary holding
|
|
|
|
|
annotations for Vertices, another dictionary for annotating Edges, and a single
|
|
|
|
|
field allowing the attachment of a tag to the entire Topology. The keys of the
|
|
|
|
|
dictionaries are VertexIDs and Edges, respectively.
|
|
|
|
|
|
|
|
|
|
The Annotation can only attach one tag to each vertex and edge, but there are
|
|
|
|
|
little restrictions of what the tag is allowed to be. The intention is to allow
|
|
|
|
|
Annotators to provide any useful data they can collect. However, we think that
|
|
|
|
|
our AnnotatedTopologies could be utilised in other projects, so the Annotation
|
|
|
|
|
objects ought to be easy to serialise into JSON or other formats.
|
|
|
|
|
|
|
|
|
|
Annotations do not need to take other Annotations into account, because
|
|
|
|
|
AnnotatedTopology stores Annotations from different Annotators separately.
|
|
|
|
|
|
|
|
|
|
The Annotators are a tiny bit more interesting. While these objects are
|
|
|
|
|
basically a wrapper around the \verb|annotate()| method, which takes an
|
|
|
|
|
AnnotatedTopology and returns an Annotation, there are few twists to it.
|
|
|
|
|
|
|
|
|
|
First, an Annotator object is intended to be created by the respective
|
|
|
|
|
AnnotatedTopology in order for it to keep track of all the Annotators. To
|
|
|
|
|
describe an Annotator, an AnnotatorID is used, which is a re-creatable and
|
|
|
|
|
hashable recipe for creating that Annotator. It is also used as a handle to
|
|
|
|
|
reference and scope the resulting Annotation. The AnnotatorID is a pair of the
|
|
|
|
|
type object of the particular Annotator, and an optional hashable parameter,
|
|
|
|
|
which is passed to the Annotator's initialiser.
|
|
|
|
|
|
|
|
|
|
Second, an Annotator might require another Annotator to have already run. We
|
|
|
|
|
make this possible by allowing Annotators to request another Annotator to be
|
|
|
|
|
run by the AnnotatedTopology (provided the AnnotatorID), as long as there is
|
|
|
|
|
not a dependency cycle. This is the recommended method of implementing
|
|
|
|
|
dependencies of Annotators.
|
|
|
|
|
|
|
|
|
|
Furthermore, an Annotator can be declared to be idempotent. This affects what
|
|
|
|
|
happens when the same Annotator is invoked on the same Topology in the same way
|
|
|
|
|
(that is, using the same AnnotatorID) multiple times. For idempotent
|
|
|
|
|
Annotators, we know that their output will not change, so the Annotator is not
|
|
|
|
|
really run. For non-idempotent Annotators, the previous Annotation is removed
|
|
|
|
|
and the Annotator is run again.
|
|
|
|
|
|
|
|
|
|
Annotators may not alter the AnnotatedTopology in any way. They are only
|
|
|
|
|
allowed to return an Annotation, which will be added to the AnnotatedTopology.
|
|
|
|
|
As with frozen Topologies, this is not enforced by the code.
|
|
|
|
|
|
|
|
|
|
Annotators may be used for various tasks, including but not limited to
|
|
|
|
|
performing analysis of the Topology, enhancing it with additional data (e.g.
|
|
|
|
|
ping response times from other system), or specifying parameters for
|
|
|
|
|
visualisation. As a part of Birdvisu itself, we ship several anotators:
|
|
|
|
|
TopologyDifference outputs the differences between the reference and current
|
|
|
|
|
Topology, and ShortestPathTree marks the edges of the shortest path DAG.
|
|
|
|
|
|
|
|
|
|
The last important object related to annotation is the AnnotatedTopology. It
|
|
|
|
|
serves as a coordinator for running Annotators. It does two main things:
|
|
|
|
|
detects dependency cycles between Annotators, and keeps the Annotations.
|
|
|
|
|
|
|
|
|
|
The Annotations in the AnnotatedTopology are stored in a dictionary indexed by
|
|
|
|
|
the respective AnnotatorID. For vertices and edges, only sets of AnnotatorIDs
|
|
|
|
|
are stored. This way, both iterating Annotations for a Vertex or Edge and
|
|
|
|
|
examining individual Annotations is fast. Also, our approach isolates unrelated
|
|
|
|
|
Annotations by putting them into different scopes by AnnotatorID.
|
|
|
|
|
|
|
|
|
|
However, by using the Annotator's type in AnnotatorID, this design enforces a
|
|
|
|
|
rather tight coupling between Annotators and users of Annotations, because the
|
|
|
|
|
consumers of Annotations need to understand the precise format of the
|
|
|
|
|
particular Annotation. This could be solved by implementing support for
|
|
|
|
|
\uv{interface-annotators}, so that various Annotators may provide Annotations
|
|
|
|
|
in a commonly understood format.\footnote{Preliminary work on implementing this
|
|
|
|
|
approach is present in the \texttt{ann\_interfaces} branch, but the interaction of
|
|
|
|
|
implementers of the same interface is not decided yet.}
|
|
|
|
|
|
|
|
|
|
AnnotatedTopology does not expose a way to delete old Annotations. While we do
|
|
|
|
|
not expect this to cause big memory leaks, in case it does, an LRU-like
|
|
|
|
|
strategy might be employed to tame the memory usage. Also, the Annotators could
|
|
|
|
|
be run dynamically when the Annotation is requested, but our current approach
|
|
|
|
|
does not need this functionality, so it is not implemented at the moment.
|
|
|
|
|
|
|
|
|
|
\section{Visualisation}
|
|
|
|
|
|
|
|
|
|