Also made optimization improvements to reuse primitive (using valueOf) and coded String
values (using intern) when read from the stream.
Also added a reusable StringBuilder instance for building qnames. After
use, the StringBuilder is cleared via the delete method. This
effectively resets the char count to 0. Previously, the
code used string concatenation which the compiler will translate to use
an imlicit StringBuilder. These changes avoid the implicit creation of a
StringBuilder instance each time which should reduce object churn.
Change-Id: Ic9c745d97d1b5eed2dd24bc5d252d05ac1355cbb
Signed-off-by: tpantelis <tpanteli@brocade.com>
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.Node;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.DataInput;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
/**
* NormalizedNodeInputStreamReader reads the byte stream and constructs the normalized node including its children nodes.
private NormalizedNodeAttrBuilder<NodeWithValue, Object,
LeafSetEntryNode<Object>> leafSetEntryBuilder;
+ private final StringBuilder reusableStringBuilder = new StringBuilder(50);
+
public NormalizedNodeInputStreamReader(InputStream stream) throws IOException {
Preconditions.checkNotNull(stream);
input = new DataInputStream(stream);
case NodeTypes.ANY_XML_NODE :
LOG.debug("Read xml node");
- Node<?> value = (Node<?>) readObject();
return Builders.anyXmlBuilder().withValue((Node<?>) readObject()).build();
case NodeTypes.MAP_NODE :
String namespace = readCodedString();
String revision = readCodedString();
- // Not using stringbuilder as compiler optimizes string concatenation of +
String qName;
if(!Strings.isNullOrEmpty(revision)) {
- qName = "(" + namespace + REVISION_ARG + revision + ")" +localName;
+ qName = reusableStringBuilder.append('(').append(namespace).append(REVISION_ARG).
+ append(revision).append(')').append(localName).toString();
} else {
- qName = "(" + namespace + ")" + localName;
+ qName = reusableStringBuilder.append('(').append(namespace).append(')').
+ append(localName).toString();
}
+ reusableStringBuilder.delete(0, reusableStringBuilder.length());
return QNameFactory.create(qName);
}
if(valueType == NormalizedNodeOutputStreamWriter.IS_CODE_VALUE) {
return codedStringMap.get(input.readInt());
} else if(valueType == NormalizedNodeOutputStreamWriter.IS_STRING_VALUE) {
- String value = input.readUTF();
+ String value = input.readUTF().intern();
codedStringMap.put(Integer.valueOf(codedStringMap.size()), value);
return value;
}
return readObjSet();
case ValueTypes.BOOL_TYPE :
- return input.readBoolean();
+ return Boolean.valueOf(input.readBoolean());
case ValueTypes.BYTE_TYPE :
- return input.readByte();
+ return Byte.valueOf(input.readByte());
case ValueTypes.INT_TYPE :
- return input.readInt();
+ return Integer.valueOf(input.readInt());
case ValueTypes.LONG_TYPE :
- return input.readLong();
+ return Long.valueOf(input.readLong());
case ValueTypes.QNAME_TYPE :
return readQName();
case ValueTypes.SHORT_TYPE :
- return input.readShort();
+ return Short.valueOf(input.readShort());
case ValueTypes.STRING_TYPE :
return input.readUTF();
case ValueTypes.BIG_INTEGER_TYPE :
return new BigInteger(input.readUTF());
+ case ValueTypes.BINARY_TYPE :
+ byte[] bytes = new byte[input.readInt()];
+ input.readFully(bytes);
+ return bytes;
+
case ValueTypes.YANG_IDENTIFIER_TYPE :
return readYangInstanceIdentifier();
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* NormalizedNodeOutputStreamWriter will be used by distributed datastore to send normalized node in
case ValueTypes.BITS_TYPE:
writeObjSet((Set<?>) value);
break;
+ case ValueTypes.BINARY_TYPE:
+ byte[] bytes = (byte[]) value;
+ output.writeInt(bytes.length);
+ output.write(bytes);
+ break;
case ValueTypes.YANG_IDENTIFIER_TYPE:
writeYangInstanceIdentifier((YangInstanceIdentifier) value);
break;
package org.opendaylight.controller.cluster.datastore.node.utils.stream;
import com.google.common.base.Preconditions;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
public class ValueTypes {
public static final byte SHORT_TYPE = 1;
public static final byte STRING_TYPE = 9;
public static final byte BIG_INTEGER_TYPE = 10;
public static final byte BIG_DECIMAL_TYPE = 11;
+ public static final byte BINARY_TYPE = 12;
private static Map<Class<?>, Byte> types = new HashMap<>();
types.put(Short.class, Byte.valueOf(SHORT_TYPE));
types.put(BigInteger.class, Byte.valueOf(BIG_INTEGER_TYPE));
types.put(BigDecimal.class, Byte.valueOf(BIG_DECIMAL_TYPE));
+ types.put(byte[].class, Byte.valueOf(BINARY_TYPE));
}
public static final byte getSerializableType(Object node){
import org.junit.Test;
import org.opendaylight.controller.cluster.datastore.util.TestModel;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
public class NormalizedNodeStreamReaderWriterTest {
@Test
public void testNormalizedNodeStreamReaderWriter() throws IOException {
- testNormalizedNodeStreamReaderWriter(TestModel.createTestContainer());
+ testNormalizedNodeStreamReaderWriter(createTestContainer());
QName toaster = QName.create("http://netconfcentral.org/ns/toaster","2009-11-20","toaster");
QName darknessFactor = QName.create("http://netconfcentral.org/ns/toaster","2009-11-20","darknessFactor");
withChild(toasterNode).build());
}
+ private NormalizedNode<?, ?> createTestContainer() {
+ byte[] bytes1 = {1,2,3};
+ LeafSetEntryNode<Object> entry1 = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
+ new YangInstanceIdentifier.NodeWithValue(TestModel.BINARY_LEAF_LIST_QNAME, bytes1)).
+ withValue(bytes1).build();
+
+ byte[] bytes2 = {};
+ LeafSetEntryNode<Object> entry2 = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
+ new YangInstanceIdentifier.NodeWithValue(TestModel.BINARY_LEAF_LIST_QNAME, bytes2)).
+ withValue(bytes2).build();
+
+ return TestModel.createBaseTestContainerBuilder().
+ withChild(ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(
+ new YangInstanceIdentifier.NodeIdentifier(TestModel.BINARY_LEAF_LIST_QNAME)).
+ withChild(entry1).withChild(entry2).build()).
+ withChild(ImmutableNodes.leafNode(TestModel.SOME_BINARY_DATE_QNAME, new byte[]{1,2,3,4})).
+ build();
+ }
+
private void testNormalizedNodeStreamReaderWriter(NormalizedNode<?, ?> input) throws IOException {
byte[] byteData = null;
package org.opendaylight.controller.cluster.datastore.util;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
import com.google.common.collect.ImmutableSet;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
-import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
-import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
-
public class TestModel {
public static final QName TEST_QNAME = QName.create(
public static final QName DESC_QNAME = QName.create(TEST_QNAME, "desc");
public static final QName POINTER_QNAME = QName.create(TEST_QNAME, "pointer");
public static final QName SOME_BINARY_DATE_QNAME = QName.create(TEST_QNAME, "some-binary-data");
+ public static final QName BINARY_LEAF_LIST_QNAME = QName.create(TEST_QNAME, "binary_leaf_list");
public static final QName SOME_REF_QNAME = QName.create(TEST_QNAME,
"some-ref");
public static final QName MYIDENTITY_QNAME = QName.create(TEST_QNAME,
type uint8;
}
+ leaf-list binary_leaf_list {
+ type binary;
+ }
+
leaf pointer {
type leafref {
path "/network-topology/topology/node/termination-point/tp-id";