diff options
author | James Newton-King <james@newtonking.com> | 2012-03-07 13:59:10 +0400 |
---|---|---|
committer | James Newton-King <james@newtonking.com> | 2012-03-07 13:59:10 +0400 |
commit | d32061cd1659203acacb8bca9e08d15c70d7d3d8 (patch) | |
tree | 952f0578909f32ec8c6ee6c6ee6e113afbf5f81f | |
parent | c7f52087690ea8e54e52366f1be2506cb313e45e (diff) |
-Improved performance issue fix for deeply nested LINQ to JSON objects
-rw-r--r-- | Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs | 9 | ||||
-rw-r--r-- | Src/Newtonsoft.Json.Tests/PerformanceTests.cs | 17 | ||||
-rw-r--r-- | Src/Newtonsoft.Json/Linq/JContainer.cs | 29 |
3 files changed, 34 insertions, 21 deletions
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs index a25c7fc..dc6cd1b 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs @@ -21,6 +21,15 @@ namespace Newtonsoft.Json.Tests.Linq }
[Test]
+ public void AddToSelf()
+ {
+ JArray a = new JArray();
+ a.Add(a);
+
+ Assert.IsFalse(ReferenceEquals(a[0], a));
+ }
+
+ [Test]
public void Contains()
{
JValue v = new JValue(1);
diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs index 57c9e8e..7d3b8bd 100644 --- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs +++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs @@ -704,6 +704,21 @@ namespace Newtonsoft.Json.Tests }
[Test]
+ public void RecursiveLoop()
+ {
+ JArray a1 = new JArray();
+ JArray a2 = new JArray();
+ JArray a3 = new JArray();
+ JArray a4 = new JArray();
+
+ a1.Add(a2);
+ a2.Add(a3);
+ a3.Add(a4);
+
+
+ }
+
+ [Test]
public void NestedJToken()
{
Stopwatch sw;
@@ -716,7 +731,7 @@ namespace Newtonsoft.Json.Tests for (int j = 0; j < i; j++)
{
JArray temp = new JArray();
- ija.AddAndSkipParentCheck(temp);
+ ija.Add(temp);
ija = temp;
}
ija.Add(1);
diff --git a/Src/Newtonsoft.Json/Linq/JContainer.cs b/Src/Newtonsoft.Json/Linq/JContainer.cs index d1f83e0..ec992fe 100644 --- a/Src/Newtonsoft.Json/Linq/JContainer.cs +++ b/Src/Newtonsoft.Json/Linq/JContainer.cs @@ -266,27 +266,16 @@ namespace Newtonsoft.Json.Linq if (item == null)
return new JValue((object) null);
- if (item.Parent != null)
- {
+ if (skipParentCheck)
+ return item;
+
+ // to avoid a token having multiple parents or creating a recursive loop, create a copy if...
+ // the item already has a parent
+ // the item is being added to itself
+ // the item is being added to the root parent of itself
+ if (item.Parent != null || item == this || (item.HasValues && Root == item))
item = item.CloneToken();
- }
- else
- {
- // check whether attempting to add a token to itself
- // not possible with a value, only a container
- if (item is JContainer && !skipParentCheck)
- {
- JContainer parent = this;
- while (parent.Parent != null)
- {
- parent = parent.Parent;
- }
- if (item == parent)
- {
- item = item.CloneToken();
- }
- }
- }
+
return item;
}
|