diff --git a/src/Hyperbee.Json/JsonPathBuilder.cs b/src/Hyperbee.Json/JsonPathBuilder.cs index bd071195..1e78abdb 100644 --- a/src/Hyperbee.Json/JsonPathBuilder.cs +++ b/src/Hyperbee.Json/JsonPathBuilder.cs @@ -1,4 +1,4 @@ -using System.Text.Json; +using System.Text.Json; namespace Hyperbee.Json; @@ -24,25 +24,25 @@ public JsonPathBuilder( JsonElement rootElement ) } // OPTIMIZED TO USE SEGMENT DICTIONARY CACHE - + public string GetPath( JsonElement targetElement ) { // quick out - + var targetId = GetIdx( targetElement ); - + if ( _parentMap.ContainsKey( targetId ) ) return BuildPath( targetId, _parentMap ); - + // take a walk - + var stack = new Stack( [_rootElement] ); while ( stack.Count > 0 ) { var currentElement = stack.Pop(); var elementId = GetIdx( currentElement ); - + if ( _comparer.Equals( currentElement, targetElement ) ) return BuildPath( elementId, _parentMap ); @@ -52,10 +52,10 @@ public string GetPath( JsonElement targetElement ) foreach ( var property in currentElement.EnumerateObject() ) { var childElementId = GetIdx( property.Value ); - + if ( !_parentMap.ContainsKey( childElementId ) ) _parentMap[childElementId] = (elementId, $".{property.Name}"); - + stack.Push( property.Value ); } break; @@ -68,7 +68,7 @@ public string GetPath( JsonElement targetElement ) if ( !_parentMap.ContainsKey( childElementId ) ) _parentMap[childElementId] = (elementId, $"[{arrayIdx}]"); - + stack.Push( element ); arrayIdx++; } @@ -102,39 +102,42 @@ private static string BuildPath( int elementId, Dictionary( 4 ); - stack.Push( (_rootElement, "$") ); - - while ( stack.Count > 0 ) + public string GetPath( JsonElement targetElement ) { - var (currentElement, currentPath) = stack.Pop(); - - if ( _comparer.Equals( currentElement, targetElement ) ) - return currentPath; + var stack = new Stack<(JsonElement element, string path)>( 4 ); + stack.Push( (_rootElement, "$") ); - switch ( currentElement.ValueKind ) + while ( stack.Count > 0 ) { - case JsonValueKind.Object: - foreach ( var property in currentElement.EnumerateObject() ) - { - var newPath = $"{currentPath}.{property.Name}"; - stack.Push( (property.Value, newPath) ); - } - - break; - - case JsonValueKind.Array: - var index = 0; - foreach ( var element in currentElement.EnumerateArray() ) - { - var newPath = $"{currentPath}[{index++}]"; - stack.Push( (element, newPath) ); - } - - break; + var (currentElement, currentPath) = stack.Pop(); + + if ( _comparer.Equals( currentElement, targetElement ) ) + return currentPath; + + switch ( currentElement.ValueKind ) + { + case JsonValueKind.Object: + foreach ( var property in currentElement.EnumerateObject() ) + { + var newPath = $"{currentPath}.{property.Name}"; + stack.Push( (property.Value, newPath) ); + } + + break; + + case JsonValueKind.Array: + var index = 0; + foreach ( var element in currentElement.EnumerateArray() ) + { + var newPath = $"{currentPath}[{index++}]"; + stack.Push( (element, newPath) ); + } + + break; + } } + + return null; // Target no } return null; // Target no