mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-09 20:38:56 -05:00
Add IListTreeItem.ChildCount for optimization of ListTreeNode.Children
This commit is contained in:
@@ -20,5 +20,7 @@ namespace UniJSON
|
||||
public interface IListTreeItem
|
||||
{
|
||||
int ParentIndex { get; }
|
||||
int ChildCount { get; }
|
||||
void SetChildCount(int count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace UniJSON
|
||||
T Key(Utf8String key, int parentIndex);
|
||||
ValueNodeType ValueType { get; }
|
||||
ArraySegment<Byte> Bytes { get; }
|
||||
void SetBytesCount(int count);
|
||||
Boolean GetBoolean();
|
||||
String GetString();
|
||||
Utf8String GetUtf8String();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ namespace UniJSON
|
||||
{
|
||||
public Utf8String Segment;
|
||||
public ArraySegment<Byte> Bytes { get { return Segment.Bytes; } }
|
||||
public void SetBytesCount(int count)
|
||||
{
|
||||
Segment = new Utf8String(new ArraySegment<byte>(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;
|
||||
|
||||
@@ -303,10 +303,14 @@ namespace UniJSON
|
||||
/// <summary>
|
||||
/// This node index
|
||||
/// </summary>
|
||||
int _valueIndex;
|
||||
public int ValueIndex
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
get
|
||||
{
|
||||
if (m_Values == null) return -1;
|
||||
return _valueIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public ListTreeNode<T> Prev
|
||||
@@ -334,14 +338,21 @@ namespace UniJSON
|
||||
}
|
||||
|
||||
#region Children
|
||||
public int ChildCount
|
||||
{
|
||||
get { return Value.ChildCount; }
|
||||
}
|
||||
|
||||
public IEnumerable<ListTreeNode<T>> 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<T>(m_Values, i);
|
||||
}
|
||||
}
|
||||
@@ -372,7 +383,6 @@ namespace UniJSON
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public bool HasParent
|
||||
{
|
||||
get
|
||||
@@ -399,27 +409,50 @@ namespace UniJSON
|
||||
public ListTreeNode(List<T> values, int index = 0) : this()
|
||||
{
|
||||
m_Values = values;
|
||||
ValueIndex = index;
|
||||
_valueIndex = index;
|
||||
}
|
||||
|
||||
#region JsonPointer
|
||||
public void AddKey(Utf8String key)
|
||||
public ListTreeNode<T> AddKey(Utf8String key)
|
||||
{
|
||||
m_Values.Add(default(T).Key(key, ValueIndex));
|
||||
return AddValue(default(T).Key(key, ValueIndex));
|
||||
}
|
||||
|
||||
public ListTreeNode<T> AddValue(ArraySegment<byte> bytes, ValueNodeType valueType)
|
||||
{
|
||||
return AddValue(default(T).New(bytes, valueType, ValueIndex));
|
||||
}
|
||||
|
||||
public ListTreeNode<T> AddValue(T value)
|
||||
{
|
||||
if (m_Values == null)
|
||||
{
|
||||
// initialize empty tree
|
||||
m_Values = new List<T>();
|
||||
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<T>(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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,65 +357,60 @@ namespace UniJSON
|
||||
}
|
||||
}
|
||||
|
||||
static ArraySegment<Byte> _Parse(ArraySegment<Byte> bytes, List<MsgPackValue> values, int parentIndex)
|
||||
static ListTreeNode<MsgPackValue> _Parse(ListTreeNode<MsgPackValue> tree, ArraySegment<Byte> 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<byte>(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<byte>(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<MsgPackValue> Parse(ArraySegment<Byte> bytes)
|
||||
{
|
||||
var values = new List<MsgPackValue>();
|
||||
_Parse(bytes, values, -1);
|
||||
return new ListTreeNode<MsgPackValue>(values);
|
||||
return _Parse(default(ListTreeNode<MsgPackValue>), bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@ namespace UniJSON
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public void SetBytesCount(int count)
|
||||
{
|
||||
Bytes = new ArraySegment<byte>(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<Byte> segment, int parentIndex) : this()
|
||||
{
|
||||
Bytes = segment;
|
||||
@@ -79,7 +93,7 @@ namespace UniJSON
|
||||
|
||||
public MsgPackValue New(ArraySegment<byte> bytes, ValueNodeType valueType, int parentIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return new MsgPackValue(bytes, parentIndex);
|
||||
}
|
||||
|
||||
public MsgPackValue Key(Utf8String key, int parentIndex)
|
||||
|
||||
@@ -62,7 +62,24 @@ namespace UniJSON
|
||||
}
|
||||
|
||||
Utf8String m_segment;
|
||||
|
||||
public ArraySegment<byte> 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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user