Skip to content

Commit

Permalink
Improve framing performance with large sets of objects. (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
dtivel authored and goofballLogic committed Jul 11, 2018
1 parent 508c988 commit 66f585b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 6 deletions.
24 changes: 22 additions & 2 deletions src/json-ld.net/Core/JsonLdApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1072,14 +1072,34 @@ internal virtual void GenerateNodeMap(JToken element, JObject
/// <exception cref="JsonLD.Core.JsonLdError"></exception>
internal virtual void GenerateNodeMap(JToken element, JObject
nodeMap, string activeGraph, JToken activeSubject, string activeProperty, JObject list)
{
GenerateNodeMap(element, nodeMap, activeGraph, activeSubject, activeProperty, list, skipSetContainsCheck: false);
}

private void GenerateNodeMap(JToken element, JObject nodeMap,
string activeGraph, JToken activeSubject, string activeProperty, JObject list, bool skipSetContainsCheck)
{
// 1)
if (element is JArray)
{
JsonLdSet set = null;

if (list == null)
{
set = new JsonLdSet();
}

// 1.1)
foreach (JToken item in (JArray)element)
{
GenerateNodeMap(item, nodeMap, activeGraph, activeSubject, activeProperty, list);
skipSetContainsCheck = false;

if (set != null)
{
skipSetContainsCheck = set.Add(item);
}

GenerateNodeMap(item, nodeMap, activeGraph, activeSubject, activeProperty, list, skipSetContainsCheck);
}
return;
}
Expand Down Expand Up @@ -1204,7 +1224,7 @@ internal virtual void GenerateNodeMap(JToken element, JObject
if (list == null)
{
// 6.6.2.1+2)
JsonLdUtils.MergeValue(node, activeProperty, reference);
JsonLdUtils.MergeValue(node, activeProperty, reference, skipSetContainsCheck);
}
else
{
Expand Down
33 changes: 33 additions & 0 deletions src/json-ld.net/Core/JsonLdSet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;

namespace JsonLD.Core
{
internal sealed class JsonLdSet
{
private readonly Lazy<HashSet<string>> _objects;

internal JsonLdSet()
{
_objects = new Lazy<HashSet<string>>(() => new HashSet<string>(StringComparer.Ordinal));
}

internal bool Add(JToken token)
{
if (token == null)
{
throw new ArgumentNullException(nameof(token));
}

if (token is JObject)
{
var id = token["@id"];

return id != null && _objects.Value.Add(id.Value<string>());
}

return false;
}
}
}
14 changes: 10 additions & 4 deletions src/json-ld.net/Core/JsonLdUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,12 @@ public static bool DeepContains(JArray values, JToken value)
return false;
}

internal static void MergeValue(JObject obj, string key, JToken
value)
internal static void MergeValue(JObject obj, string key, JToken value)
{
MergeValue(obj, key, value, skipSetContainsCheck: false);
}

internal static void MergeValue(JObject obj, string key, JToken value, bool skipSetContainsCheck)
{
if (obj == null)
{
Expand All @@ -161,8 +165,10 @@ internal static void MergeValue(JObject obj, string key, JToken
values = new JArray();
obj[key] = values;
}
if ("@list".Equals(key) || (value is JObject && ((IDictionary<string, JToken>
)value).ContainsKey("@list")) || !DeepContains(values, (JToken)value))
if (skipSetContainsCheck ||
"@list".Equals(key) ||
(value is JObject && ((IDictionary<string, JToken>)value).ContainsKey("@list")) ||
!DeepContains(values, (JToken)value))
{
values.Add(value);
}
Expand Down

0 comments on commit 66f585b

Please sign in to comment.