Add Magnesium encoding tokens 57/84557/13
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 20 Sep 2019 08:07:10 +0000 (10:07 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 25 Sep 2019 08:21:16 +0000 (10:21 +0200)
commit95bd6c9c8254844616a99bf40f73b4d2c5726686
treea5c1d7d6f1590638db20bf66450b4b5c56e704af
parent548d175b3ebb0bdefe6d5073f039aa18ccd0ad81
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>
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]