Add Magnesium encoding tokens 28/84728/1
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 20 Sep 2019 08:07:10 +0000 (10:07 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 26 Sep 2019 07:23:20 +0000 (09:23 +0200)
commitd250ac02439472cc36b07f1d30510ef2ae467407
treeb37e393bd62324bb848635d7150afa1584ac5975
parent2d9e3b5a950d89716bc45f95469389937afa5058
Add Magnesium encoding tokens

Changes to how uint8/16/32/64 types are mapped results in the need
to transfer the new value types. These represent 4 brand new tokens,
which need to be handled.

One option would be to fork NeonSR2 and modify it, somehow dealing
with value lookups (i.e. Uint8 is not valid in SR2 stream, but tokens
are shared across Lithium/NeonSR).

Another option is to create a streaming format from scratch, coming
up with a completely new family of tokens and encoding rules. This
is attractive, as both current formats have three deficiencies:

1) they encode MapEntry key values twice, once in the leaf itself
   and once in the entry's NodeIdentifierWithPredicates
2) they are '0-happy', i.e. they do not recognize that integer codes
   and sizes are typically much smaller than the 4-byte range and thus
   much of the stream is just small ints encoded as 4 bytes
3) while they are simple and straighforward, they also end up wasting
   bits -- the four token families (codes, value types, node types,
   path argument types) each have at most 15 distinct values, and
   hence the bytes used to transmit them have 4 empty bits (or more)

Hence we take the other option and design a streaming format with
brand new tokens, which are structured to carry as much more
information per byte.

This is done by combining 'type' information with forward coding
hints, for example:

- a Boolean leaf value would previously require 2 bytes:
    (byte)    ValueTypes.BOOL_TYPE
    (byte)    true/falseIn the new tokens
  whereas new tokens express this in one byte:
    (byte)    LeafValue.BOOLEAN_{FALSE,TRUE}
- a byte[5] value would require 10 bytes to encode:
    (byte)    ValueTypes.BINARY_TYPE
    (int)     length
    (5 bytes) bytes
  whereas new tokens express this in 6 bytes:
    (byte)    ValueTypes.BINARY_0 + 5 (works up to 127)
    (5 bytes) bytes

A similar approach is taken when encoding NormalizedNode types. Here
we recognize there are only 14 node types (currently) and hence we
can provide up to 4 additional bits for information about how the
node's identifier is encoded.

For PathArguments, we also use separate coding, where the format
is flexible based on the 4 types on identifiers there are, each
having slightly different format. Most notable here is the integration
of QName reference coding (for normal PathArguments) and integrated
set size coding (for AugmentationIdentifiers).

This this patch adds just the token definitions, along with basic
documentation and version declaration.

JIRA: CONTROLLER-1919
Change-Id: I9f6f58a7cb77d9d98c46e13b8dc6955c8e3c0737
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 95bd6c9c8254844616a99bf40f73b4d2c5726686)
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/MagnesiumNode.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/MagnesiumPathArgument.java [new file with mode: 0644]
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/MagnesiumValue.java [new file with mode: 0644]