b3183a3d95ee93fbcf7194bca6cb19223923a666
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / main / java / org / opendaylight / controller / cluster / datastore / node / utils / stream / NeonSR2NormalizedNodeOutputStreamWriter.java
1 /*
2  * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.datastore.node.utils.stream;
9
10 import java.io.DataOutput;
11 import java.io.IOException;
12 import java.util.HashMap;
13 import java.util.Map;
14 import org.opendaylight.yangtools.yang.common.QName;
15 import org.opendaylight.yangtools.yang.common.QNameModule;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
17
18 /**
19  * NormalizedNodeOutputStreamWriter will be used by distributed datastore to send normalized node in
20  * a stream.
21  * A stream writer wrapper around this class will write node objects to stream in recursive manner.
22  * for example - If you have a ContainerNode which has a two LeafNode as children, then
23  * you will first call
24  * {@link #startContainerNode(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier, int)},
25  * then will call
26  * {@link #leafNode(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier, Object)} twice
27  * and then, {@link #endNode()} to end container node.
28  *
29  * <p>Based on the each node, the node type is also written to the stream, that helps in reconstructing the object,
30  * while reading.
31  */
32 final class NeonSR2NormalizedNodeOutputStreamWriter extends AbstractLithiumDataOutput {
33     private final Map<AugmentationIdentifier, Integer> aidCodeMap = new HashMap<>();
34     private final Map<QNameModule, Integer> moduleCodeMap = new HashMap<>();
35     private final Map<QName, Integer> qnameCodeMap = new HashMap<>();
36
37     NeonSR2NormalizedNodeOutputStreamWriter(final DataOutput output) {
38         super(output);
39     }
40
41     @Override
42     protected short streamVersion() {
43         return TokenTypes.NEON_SR2_VERSION;
44     }
45
46     @Override
47     public void writeQName(final QName qname) throws IOException {
48         final Integer value = qnameCodeMap.get(qname);
49         if (value == null) {
50             // Fresh QName, remember it and emit as three strings
51             qnameCodeMap.put(qname, qnameCodeMap.size());
52             writeByte(TokenTypes.IS_QNAME_VALUE);
53             defaultWriteQName(qname);
54         } else {
55             // We have already seen this QName: write its code
56             writeByte(TokenTypes.IS_QNAME_CODE);
57             writeInt(value);
58         }
59     }
60
61     @Override
62     void writeAugmentationIdentifier(final AugmentationIdentifier aid) throws IOException {
63         final Integer value = aidCodeMap.get(aid);
64         if (value == null) {
65             // Fresh AugmentationIdentifier, remember it and emit as three strings
66             aidCodeMap.put(aid, aidCodeMap.size());
67             writeByte(TokenTypes.IS_AUGMENT_VALUE);
68             super.writeAugmentationIdentifier(aid);
69         } else {
70             // We have already seen this AugmentationIdentifier: write its code
71             writeByte(TokenTypes.IS_AUGMENT_CODE);
72             writeInt(value);
73         }
74     }
75
76     @Override
77     void writeModule(final QNameModule module) throws IOException {
78         final Integer value = moduleCodeMap.get(module);
79         if (value == null) {
80             // Fresh QNameModule, remember it and emit as three strings
81             moduleCodeMap.put(module, moduleCodeMap.size());
82             writeByte(TokenTypes.IS_MODULE_VALUE);
83             defaultWriteModule(module);
84         } else {
85             // We have already seen this QNameModule: write its code
86             writeByte(TokenTypes.IS_MODULE_CODE);
87             writeInt(value);
88         }
89     }
90 }