The only place Counters are used is in rendering, for the number of
nodes under a topology, so the overhead of holding a unique data
structure in every Node is unwarranted.
Counters are not set in the probe, so we don't need any
backwards-compatibility in report decoding. Similarly they are not set
until after all nodes are merged, so we don't need that logic.
We consistently
- pre-allocate in Copy()
- merge the smaller into a copy of the larger in Merge()
This doesn't make much of a difference overall, since there are
comparatively few instances of these structures. But it costs little
in the code, and the consistency alone is worth it.
Pre-allocating slices really pays dividends when we create loads of
them and they don't grow very large.
We take special care to return nil rather than 0-length slices. This
a) saves further on allocation, and b) is required for some crude
tests to pass that match on nil rather than length.
Also, a bunch of code in templates/tables used slices as Maybe's,
i.e. returning nil or a single-element slice, which is horrendously
inefficient. Eliminating these saves a lot of allocations.
Squash of:
* Include plugins in the report
* show plugin list in the UI
* moving metric and metadata templates into the probe reports
* update js for prime -> priority
* added retry to plugin handshake
* added iowait plugin
* review feedback
* plugin documentation