NormalizedNodeWriter: emit sizing hints 54/10654/2
authorRobert Varga <rovarga@cisco.com>
Tue, 2 Sep 2014 21:20:40 +0000 (23:20 +0200)
committerRobert Varga <rovarga@cisco.com>
Tue, 2 Sep 2014 21:22:39 +0000 (23:22 +0200)
This patch adds the minimum smarts to allow emitting child sizing hints.

Change-Id: I79a4728db1ec1cb9460e5750d3cce099185add94
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/NormalizedNodeWriter.java

index 340b9ed60d6c54ad80d7a9544ab22096508a5848..6a19b45f376a02b5d0346f3a28a7b704f0c6e098 100644 (file)
@@ -18,6 +18,7 @@ import com.google.common.collect.Iterables;
 import java.io.Closeable;
 import java.io.Flushable;
 import java.io.IOException;
+import java.util.Collection;
 import java.util.Set;
 
 import javax.xml.stream.XMLStreamReader;
@@ -98,7 +99,7 @@ public class NormalizedNodeWriter implements Closeable, Flushable {
      * @return
      * @throws IOException when thrown from the backing writer.
      */
-    public NormalizedNodeWriter write(final NormalizedNode<?, ?> node) throws IOException {
+    public final NormalizedNodeWriter write(final NormalizedNode<?, ?> node) throws IOException {
         if (wasProcessedAsCompositeNode(node)) {
             return this;
         }
@@ -110,6 +111,29 @@ public class NormalizedNodeWriter implements Closeable, Flushable {
         throw new IllegalStateException("It wasn't possible to serialize node " + node);
     }
 
+    @Override
+    public void flush() throws IOException {
+        writer.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        writer.flush();
+        writer.close();
+    }
+
+    /**
+     * Emit a best guess of a hint for a particular set of children. It evaluates the
+     * iterable to see if the size can be easily gotten to. If it is, we hint at the
+     * real number of child nodes. Otherwise we emit UNKNOWN_SIZE.
+     *
+     * @param children Child nodes
+     * @return Best estimate of the collection size required to hold all the children.
+     */
+    static final int childSizeHint(final Iterable<?> children) {
+        return (children instanceof Collection) ? ((Collection<?>) children).size() : UNKNOWN_SIZE;
+    }
+
     private boolean wasProcessAsSimpleNode(final NormalizedNode<?, ?> node) throws IOException {
         if (node instanceof LeafSetEntryNode) {
             final LeafSetEntryNode<?> nodeAsLeafList = (LeafSetEntryNode<?>)node;
@@ -135,7 +159,7 @@ public class NormalizedNodeWriter implements Closeable, Flushable {
      * @return True
      * @throws IOException when the writer reports it
      */
-    protected boolean writeChildren(final Iterable<? extends NormalizedNode<?, ?>> children) throws IOException {
+    protected final boolean writeChildren(final Iterable<? extends NormalizedNode<?, ?>> children) throws IOException {
         for (NormalizedNode<?, ?> child : children) {
             write(child);
         }
@@ -145,14 +169,14 @@ public class NormalizedNodeWriter implements Closeable, Flushable {
     }
 
     protected boolean writeMapEntryNode(final MapEntryNode node) throws IOException {
-        writer.startMapEntryNode(node.getIdentifier(), UNKNOWN_SIZE);
+        writer.startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue()));
         return writeChildren(node.getValue());
     }
 
     private boolean wasProcessedAsCompositeNode(final NormalizedNode<?, ?> node) throws IOException {
         if (node instanceof ContainerNode) {
             final ContainerNode n = (ContainerNode) node;
-            writer.startContainerNode(n.getIdentifier(), UNKNOWN_SIZE);
+            writer.startContainerNode(n.getIdentifier(), childSizeHint(n.getValue()));
             return writeChildren(n.getValue());
         }
         if (node instanceof MapEntryNode) {
@@ -160,12 +184,12 @@ public class NormalizedNodeWriter implements Closeable, Flushable {
         }
         if (node instanceof UnkeyedListEntryNode) {
             final UnkeyedListEntryNode n = (UnkeyedListEntryNode) node;
-            writer.startUnkeyedListItem(n.getIdentifier(), UNKNOWN_SIZE);
+            writer.startUnkeyedListItem(n.getIdentifier(), childSizeHint(n.getValue()));
             return writeChildren(n.getValue());
         }
         if (node instanceof ChoiceNode) {
             final ChoiceNode n = (ChoiceNode) node;
-            writer.startChoiceNode(n.getIdentifier(), UNKNOWN_SIZE);
+            writer.startChoiceNode(n.getIdentifier(), childSizeHint(n.getValue()));
             return writeChildren(n.getValue());
         }
         if (node instanceof AugmentationNode) {
@@ -175,39 +199,29 @@ public class NormalizedNodeWriter implements Closeable, Flushable {
         }
         if (node instanceof UnkeyedListNode) {
             final UnkeyedListNode n = (UnkeyedListNode) node;
-            writer.startUnkeyedList(n.getIdentifier(), UNKNOWN_SIZE);
+            writer.startUnkeyedList(n.getIdentifier(), childSizeHint(n.getValue()));
             return writeChildren(n.getValue());
         }
         if (node instanceof OrderedMapNode) {
             final OrderedMapNode n = (OrderedMapNode) node;
-            writer.startOrderedMapNode(n.getIdentifier(), UNKNOWN_SIZE);
+            writer.startOrderedMapNode(n.getIdentifier(), childSizeHint(n.getValue()));
             return writeChildren(n.getValue());
         }
         if (node instanceof MapNode) {
             final MapNode n = (MapNode) node;
-            writer.startMapNode(n.getIdentifier(), UNKNOWN_SIZE);
+            writer.startMapNode(n.getIdentifier(), childSizeHint(n.getValue()));
             return writeChildren(n.getValue());
         }
         if (node instanceof LeafSetNode) {
             //covers also OrderedLeafSetNode for which doesn't exist start* method
             final LeafSetNode<?> n = (LeafSetNode<?>) node;
-            writer.startLeafSet(n.getIdentifier(), UNKNOWN_SIZE);
+            writer.startLeafSet(n.getIdentifier(), childSizeHint(n.getValue()));
             return writeChildren(n.getValue());
         }
 
         return false;
     }
 
-    @Override
-    public void flush() throws IOException {
-        writer.flush();
-    }
-
-    @Override
-    public void close() throws IOException {
-        writer.close();
-    }
-
     private static final class OrderedNormalizedNodeWriter extends NormalizedNodeWriter {
         private static final Logger LOG = LoggerFactory.getLogger(OrderedNormalizedNodeWriter.class);
 
@@ -217,7 +231,7 @@ public class NormalizedNodeWriter implements Closeable, Flushable {
 
         @Override
         protected boolean writeMapEntryNode(final MapEntryNode node) throws IOException {
-            getWriter().startMapEntryNode(node.getIdentifier(), UNKNOWN_SIZE);
+            getWriter().startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue()));
 
             final Set<QName> qnames = node.getIdentifier().getKeyValues().keySet();
             // Write out all the key children