From 1ca7c20f49d1a1ef5217920fbd86676a8874be6a Mon Sep 17 00:00:00 2001 From: ousttrue Date: Sun, 10 Feb 2019 04:17:46 +0900 Subject: [PATCH] Add IListTreeItem.ChildCount for optimization of ListTreeNode.Children --- Assets/VRM/UniJSON/Scripts/ITreeNode.cs | 2 + Assets/VRM/UniJSON/Scripts/IValue.cs | 1 + Assets/VRM/UniJSON/Scripts/Json/JsonParser.cs | 6 +-- Assets/VRM/UniJSON/Scripts/Json/JsonValue.cs | 14 +++++ .../Scripts/ListTreeNode/ListTreeNode.cs | 51 +++++++++++++++---- .../UniJSON/Scripts/MsgPack/MsgPackParser.cs | 43 +++++++--------- .../UniJSON/Scripts/MsgPack/MsgPackValue.cs | 16 +++++- Assets/VRM/UniJSON/Scripts/Toml/TomlValue.cs | 17 +++++++ 8 files changed, 112 insertions(+), 38 deletions(-) diff --git a/Assets/VRM/UniJSON/Scripts/ITreeNode.cs b/Assets/VRM/UniJSON/Scripts/ITreeNode.cs index b1682dd04..1f8edfbbf 100644 --- a/Assets/VRM/UniJSON/Scripts/ITreeNode.cs +++ b/Assets/VRM/UniJSON/Scripts/ITreeNode.cs @@ -20,5 +20,7 @@ namespace UniJSON public interface IListTreeItem { int ParentIndex { get; } + int ChildCount { get; } + void SetChildCount(int count); } } diff --git a/Assets/VRM/UniJSON/Scripts/IValue.cs b/Assets/VRM/UniJSON/Scripts/IValue.cs index 95b68f78e..b88341f8a 100644 --- a/Assets/VRM/UniJSON/Scripts/IValue.cs +++ b/Assets/VRM/UniJSON/Scripts/IValue.cs @@ -24,6 +24,7 @@ namespace UniJSON T Key(Utf8String key, int parentIndex); ValueNodeType ValueType { get; } ArraySegment Bytes { get; } + void SetBytesCount(int count); Boolean GetBoolean(); String GetString(); Utf8String GetUtf8String(); diff --git a/Assets/VRM/UniJSON/Scripts/Json/JsonParser.cs b/Assets/VRM/UniJSON/Scripts/Json/JsonParser.cs index f67b01119..8936d8275 100644 --- a/Assets/VRM/UniJSON/Scripts/Json/JsonParser.cs +++ b/Assets/VRM/UniJSON/Scripts/Json/JsonParser.cs @@ -154,8 +154,7 @@ namespace UniJSON // fix array range var count = current.Bytes.Offset + 1 - segment.Bytes.Offset; - var arraySegment = segment.Subbytes(0, count); - array.SetValue(new JsonValue(arraySegment, ValueNodeType.Array, array.Value.ParentIndex)); + array.SetValueBytesCount(count); return array; } @@ -244,8 +243,7 @@ namespace UniJSON // fix obj range var count = current.Bytes.Offset + 1 - segment.Bytes.Offset; - var objSegment = segment.Subbytes(0, count); - obj.SetValue(new JsonValue(objSegment, ValueNodeType.Object, obj.Value.ParentIndex)); + obj.SetValueBytesCount(count); return obj; } diff --git a/Assets/VRM/UniJSON/Scripts/Json/JsonValue.cs b/Assets/VRM/UniJSON/Scripts/Json/JsonValue.cs index 0fb2e774e..97ddcef24 100644 --- a/Assets/VRM/UniJSON/Scripts/Json/JsonValue.cs +++ b/Assets/VRM/UniJSON/Scripts/Json/JsonValue.cs @@ -7,6 +7,10 @@ namespace UniJSON { public Utf8String Segment; public ArraySegment Bytes { get { return Segment.Bytes; } } + public void SetBytesCount(int count) + { + Segment = new Utf8String(new ArraySegment(Bytes.Array, Bytes.Offset, count)); + } public ValueNodeType ValueType { @@ -20,6 +24,16 @@ namespace UniJSON private set; } + int _childCount; + public int ChildCount + { + get { return _childCount; } + } + public void SetChildCount(int count) + { + _childCount = count; + } + public JsonValue(Utf8String segment, ValueNodeType valueType, int parentIndex) : this() { Segment = segment; diff --git a/Assets/VRM/UniJSON/Scripts/ListTreeNode/ListTreeNode.cs b/Assets/VRM/UniJSON/Scripts/ListTreeNode/ListTreeNode.cs index dc3f31407..c3cc147ab 100644 --- a/Assets/VRM/UniJSON/Scripts/ListTreeNode/ListTreeNode.cs +++ b/Assets/VRM/UniJSON/Scripts/ListTreeNode/ListTreeNode.cs @@ -303,10 +303,14 @@ namespace UniJSON /// /// This node index /// + int _valueIndex; public int ValueIndex { - get; - private set; + get + { + if (m_Values == null) return -1; + return _valueIndex; + } } public ListTreeNode Prev @@ -334,14 +338,21 @@ namespace UniJSON } #region Children + public int ChildCount + { + get { return Value.ChildCount; } + } + public IEnumerable> Children { get { - for (int i = ValueIndex; i < m_Values.Count; ++i) + int count = 0; + for (int i = ValueIndex; count < ChildCount && i < m_Values.Count; ++i) { if (m_Values[i].ParentIndex == ValueIndex) { + ++count; yield return new ListTreeNode(m_Values, i); } } @@ -372,7 +383,6 @@ namespace UniJSON } } #endregion - public bool HasParent { get @@ -399,27 +409,50 @@ namespace UniJSON public ListTreeNode(List values, int index = 0) : this() { m_Values = values; - ValueIndex = index; + _valueIndex = index; } #region JsonPointer - public void AddKey(Utf8String key) + public ListTreeNode AddKey(Utf8String key) { - m_Values.Add(default(T).Key(key, ValueIndex)); + return AddValue(default(T).Key(key, ValueIndex)); } public ListTreeNode AddValue(ArraySegment bytes, ValueNodeType valueType) + { + return AddValue(default(T).New(bytes, valueType, ValueIndex)); + } + + public ListTreeNode AddValue(T value) { if (m_Values == null) { // initialize empty tree m_Values = new List(); - ValueIndex = -1; + _valueIndex = -1; + } + else + { + IncrementChildCount(); } var index = m_Values.Count; - m_Values.Add(default(T).New(bytes, valueType, ValueIndex)); + m_Values.Add(value); return new ListTreeNode(m_Values, index); } + + void IncrementChildCount() + { + var value = Value; + value.SetChildCount(value.ChildCount + 1); + SetValue(value); + } + + public void SetValueBytesCount(int count) + { + var value = Value; + value.SetBytesCount(count); + SetValue(value); + } #endregion } } diff --git a/Assets/VRM/UniJSON/Scripts/MsgPack/MsgPackParser.cs b/Assets/VRM/UniJSON/Scripts/MsgPack/MsgPackParser.cs index 9d153f589..cf0e07f60 100644 --- a/Assets/VRM/UniJSON/Scripts/MsgPack/MsgPackParser.cs +++ b/Assets/VRM/UniJSON/Scripts/MsgPack/MsgPackParser.cs @@ -357,65 +357,60 @@ namespace UniJSON } } - static ArraySegment _Parse(ArraySegment bytes, List values, int parentIndex) + static ListTreeNode _Parse(ListTreeNode tree, ArraySegment bytes) { MsgPackType formatType = GetFormat(bytes); if (formatType.IsArray()) { - var index = values.Count; - var offset = bytes.Offset; - values.Add(new MsgPackValue(bytes, parentIndex)); + var array = tree.AddValue(bytes, ValueNodeType.Array); uint count; bytes = GetItemCount(bytes, formatType, out count); for (var i = 0; i < count; ++i) { - bytes = _Parse(bytes, values, index); + var child = _Parse(array, bytes); + bytes = bytes.Advance(child.Value.Bytes.Count); } - values[index] = new MsgPackValue( - new ArraySegment(bytes.Array, - offset, bytes.Offset - offset), - parentIndex); + array.SetValueBytesCount(bytes.Offset - array.Value.Bytes.Offset); + + return array; } else if (formatType.IsMap()) { - var index = values.Count; - var offset = bytes.Offset; - values.Add(new MsgPackValue(bytes, parentIndex)); + var obj = tree.AddValue(bytes, ValueNodeType.Object); uint count; bytes = GetItemCount(bytes, formatType, out count); for (var i = 0; i < count; ++i) { // key - bytes = _Parse(bytes, values, index); + var key = _Parse(obj, bytes); + bytes = bytes.Advance(key.Value.Bytes.Count); // value - bytes = _Parse(bytes, values, index); + var value = _Parse(obj, bytes); + bytes = bytes.Advance(value.Value.Bytes.Count); } - values[index] = new MsgPackValue( - new ArraySegment(bytes.Array, - offset, bytes.Offset - offset), - parentIndex); + obj.SetValueBytesCount(bytes.Offset - obj.Value.Bytes.Offset); + + return obj; } else { var body = GetBody(bytes, formatType); var headerSize = body.Offset - bytes.Offset; var size = headerSize + body.Count; - values.Add(new MsgPackValue(bytes.Take(size), parentIndex)); - bytes = bytes.Advance(size); + + var value = tree.AddValue(bytes.Take(size), ValueNodeType.Null); + return value; } - return bytes; } public static ListTreeNode Parse(ArraySegment bytes) { - var values = new List(); - _Parse(bytes, values, -1); - return new ListTreeNode(values); + return _Parse(default(ListTreeNode), bytes); } } } diff --git a/Assets/VRM/UniJSON/Scripts/MsgPack/MsgPackValue.cs b/Assets/VRM/UniJSON/Scripts/MsgPack/MsgPackValue.cs index b33c2bd5f..77c43f296 100644 --- a/Assets/VRM/UniJSON/Scripts/MsgPack/MsgPackValue.cs +++ b/Assets/VRM/UniJSON/Scripts/MsgPack/MsgPackValue.cs @@ -16,6 +16,10 @@ namespace UniJSON get; private set; } + public void SetBytesCount(int count) + { + Bytes = new ArraySegment(Bytes.Array, Bytes.Offset, count); + } public MsgPackType Format { @@ -71,6 +75,16 @@ namespace UniJSON } } + int _childCount; + public int ChildCount + { + get { return _childCount; } + } + public void SetChildCount(int count) + { + _childCount = count; + } + public MsgPackValue(ArraySegment segment, int parentIndex) : this() { Bytes = segment; @@ -79,7 +93,7 @@ namespace UniJSON public MsgPackValue New(ArraySegment bytes, ValueNodeType valueType, int parentIndex) { - throw new NotImplementedException(); + return new MsgPackValue(bytes, parentIndex); } public MsgPackValue Key(Utf8String key, int parentIndex) diff --git a/Assets/VRM/UniJSON/Scripts/Toml/TomlValue.cs b/Assets/VRM/UniJSON/Scripts/Toml/TomlValue.cs index 37ca04295..9a8391b66 100644 --- a/Assets/VRM/UniJSON/Scripts/Toml/TomlValue.cs +++ b/Assets/VRM/UniJSON/Scripts/Toml/TomlValue.cs @@ -62,7 +62,24 @@ namespace UniJSON } Utf8String m_segment; + public ArraySegment Bytes { get { return m_segment.Bytes; } } + public void SetBytesCount(int count) + { + throw new NotImplementedException(); + } + + public int ChildCount + { + get + { + throw new NotImplementedException(); + } + } + public void SetChildCount(int count) + { + throw new NotImplementedException(); + } public TomlValue(Utf8String segment, TomlValueType valueType, int parentIndex) : this() {