From 0bea335f570e86072427c96871c13780e621f17c Mon Sep 17 00:00:00 2001 From: Cameron Ross Date: Wed, 18 Apr 2018 15:21:13 -0300 Subject: [PATCH] massive speed increase for mapping construction --- source/dyaml/composer.d | 16 ++++++++++++---- source/dyaml/node.d | 16 ---------------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/source/dyaml/composer.d b/source/dyaml/composer.d index 85c64b7..001869b 100644 --- a/source/dyaml/composer.d +++ b/source/dyaml/composer.d @@ -12,9 +12,11 @@ module dyaml.composer; import core.memory; +import std.algorithm; import std.array; import std.conv; import std.exception; +import std.range; import std.typecons; import dyaml.constructor; @@ -314,12 +316,12 @@ final class Composer else { auto temp = Node.Pair(key, value); - merge(*pairAppender, temp); + pairAppender.put(temp); } } foreach(node; toMerge) { - merge(*pairAppender, flatten(node, startMark, endMark, + pairAppender.put(flatten(node, startMark, endMark, pairAppenderLevel + 1, nodeAppenderLevel)); } } @@ -327,7 +329,7 @@ final class Composer else if(root.isSequence) foreach(ref Node node; root) { if(!node.isType!(Node.Pair[])){error(node);} - merge(*pairAppender, flatten(node, startMark, endMark, + pairAppender.put(flatten(node, startMark, endMark, pairAppenderLevel + 1, nodeAppenderLevel)); } else @@ -368,7 +370,7 @@ final class Composer //Not YAMLMerge, just add the pair. else { - merge(*pairAppender, pair); + pairAppender.put(pair); } } foreach(node; toMerge) @@ -376,6 +378,12 @@ final class Composer merge(*pairAppender, flatten(node[0], startEvent.startMark, node[1], pairAppenderLevel + 1, nodeAppenderLevel)); } + auto numUnique = pairAppender.data.dup + .sort!((x,y) => x.key > y.key) + .uniq!((x,y) => x.key == y.key) + .walkLength; + enforce(numUnique == pairAppender.data.length, + new ComposerException("Duplicate key found in mapping", parser_.getEvent().startMark)); Node node = constructor_.node(startEvent.startMark, parser_.getEvent().endMark, tag, pairAppender.data.dup, startEvent.collectionStyle); diff --git a/source/dyaml/node.d b/source/dyaml/node.d index e60aa42..80ca94f 100644 --- a/source/dyaml/node.d +++ b/source/dyaml/node.d @@ -2195,22 +2195,6 @@ struct Node } package: -// Merge a pair into an array of pairs based on merge rules in the YAML spec. -// -// The new pair will only be added if there is not already a pair -// with the same key. -// -// Params: pairs = Appender managing the array of pairs to merge into. -// toMerge = Pair to merge. -void merge(ref Appender!(Node.Pair[]) pairs, ref Node.Pair toMerge) @safe -{ - foreach(ref pair; pairs.data) - { - if(pair.key == toMerge.key){return;} - } - pairs.put(toMerge); -} - // Merge pairs into an array of pairs based on merge rules in the YAML spec. // // Any new pair will only be added if there is not already a pair