Deduplicate MapNode key leaf values 98/83998/9
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 26 Aug 2019 20:44:30 +0000 (22:44 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 27 Aug 2019 12:49:38 +0000 (14:49 +0200)
When we are encountering a leaf node inside a MapEntryNode, it can
be a leaf corresponding to a key -- in which case its value is
already present in NodeIdentifierWithPredicates and we do want to
de-duplicate those objects.

JIRA: CONTROLLER-1908
Change-Id: I2ed65c311f9921aa77c9f23bd1f7681d7f11355a
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/LithiumNormalizedNodeInputStreamReader.java

index 552f1e96a2de23011832c18c0bc6c8d5e20a19af..e069d901d1b56aebd599148360456d97a214b574 100755 (executable)
@@ -155,10 +155,28 @@ class LithiumNormalizedNodeInputStreamReader extends ForwardingDataInput impleme
     }
 
     private void streamLeaf(final NormalizedNodeStreamWriter writer) throws IOException {
     }
 
     private void streamLeaf(final NormalizedNodeStreamWriter writer) throws IOException {
+        startLeaf(writer);
+        endLeaf(writer, readObject());
+    }
+
+    // Leaf inside a MapEntryNode, it can potentially be a key leaf, in which case we want to de-duplicate values.
+    private void streamLeaf(final NormalizedNodeStreamWriter writer, final NodeIdentifierWithPredicates entryId)
+            throws IOException {
+        final NodeIdentifier identifier = startLeaf(writer);
+        final Object value = readObject();
+        final Object entryValue = entryId.getValue(identifier.getNodeType());
+        endLeaf(writer, entryValue == null ? value : entryValue);
+    }
+
+    private NodeIdentifier startLeaf(final NormalizedNodeStreamWriter writer) throws IOException {
         final NodeIdentifier identifier = readNodeIdentifier();
         LOG.trace("Streaming leaf node {}", identifier);
         writer.startLeafNode(identifier);
         final NodeIdentifier identifier = readNodeIdentifier();
         LOG.trace("Streaming leaf node {}", identifier);
         writer.startLeafNode(identifier);
-        writer.scalarValue(readObject());
+        return identifier;
+    }
+
+    private static void endLeaf(final NormalizedNodeStreamWriter writer, final Object value) throws IOException {
+        writer.scalarValue(value);
         writer.endNode();
     }
 
         writer.endNode();
     }
 
@@ -215,7 +233,17 @@ class LithiumNormalizedNodeInputStreamReader extends ForwardingDataInput impleme
         final NodeIdentifierWithPredicates entryIdentifier = readNormalizedNodeWithPredicates();
         LOG.trace("Streaming map entry node {}", entryIdentifier);
         writer.startMapEntryNode(entryIdentifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
         final NodeIdentifierWithPredicates entryIdentifier = readNormalizedNodeWithPredicates();
         LOG.trace("Streaming map entry node {}", entryIdentifier);
         writer.startMapEntryNode(entryIdentifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
-        commonStreamContainer(writer);
+
+        // Same loop as commonStreamContainer(), but ...
+        for (byte nodeType = input.readByte(); nodeType != NodeTypes.END_NODE; nodeType = input.readByte()) {
+            if (nodeType == NodeTypes.LEAF_NODE) {
+                // ... leaf nodes may need de-duplication
+                streamLeaf(writer, entryIdentifier);
+            } else {
+                streamNormalizedNode(writer, nodeType);
+            }
+        }
+        writer.endNode();
     }
 
     private void streamUnkeyedList(final NormalizedNodeStreamWriter writer) throws IOException {
     }
 
     private void streamUnkeyedList(final NormalizedNodeStreamWriter writer) throws IOException {