From f2d8ad2449b97f9762a45979245be842135ee49a Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Sun, 29 Dec 2024 00:01:27 -0800 Subject: [PATCH] recurse_until rpath func; fix GetOpenFileNames ADD: recurse_until RemesPath function for recursively searching for children that satisfy a condition. FIX: remove reference to badly implemented NPPM_GETOPENFILENAMES to fix a crash that suddenly started happening whenever I ran UI tests --- CHANGELOG.md | 5 + .../JSONTools/RemesPathFunctions.cs | 35 ++++++ JsonToolsNppPlugin/JsonToolsNppPlugin.csproj | 1 - .../PluginInfrastructure/ClikeStringArray.cs | 77 ------------- .../PluginInfrastructure/Msgs_h.cs | 4 +- .../PluginInfrastructure/NotepadPPGateway.cs | 25 +++-- JsonToolsNppPlugin/Properties/AssemblyInfo.cs | 4 +- JsonToolsNppPlugin/Tests/RemesPathTests.cs | 6 + docs/RemesPath.md | 23 ++++ most recent errors.txt | 106 +++++++++--------- 10 files changed, 144 insertions(+), 142 deletions(-) delete mode 100644 JsonToolsNppPlugin/PluginInfrastructure/ClikeStringArray.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 88d3b26..1bd8a31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,9 +50,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [8.4.0] - (UNRELEASED) YYYY-MM-DD +### Added + +1. Add [`recurse_until` RemesPath function](/docs/RemesPath.md#non-vectorized-functions) to recursively search arrays and objects for anything inside that satisfies a condition. + ### Fixed 1. Mostly fix bug where icons would disappear when going from light to dark mode. As a side effect, the icons when using "standard icons: small" are smaller, but the icons under other conditions are larger. +2. Fix [intermittent crash during UI tests in 64-bit Notepad++](https://community.notepad-plus-plus.org/topic/26509/intermittent-notepad-crash-related-to-nppm_getopenfilenames-only-on-64-bit-npp) by eliminating reference to the dangerous `NPPM_GETOPENFILENAMES` message. ## [8.3.1] - 2024-12-22 diff --git a/JsonToolsNppPlugin/JSONTools/RemesPathFunctions.cs b/JsonToolsNppPlugin/JSONTools/RemesPathFunctions.cs index 11af791..f8c6a28 100644 --- a/JsonToolsNppPlugin/JSONTools/RemesPathFunctions.cs +++ b/JsonToolsNppPlugin/JSONTools/RemesPathFunctions.cs @@ -1746,6 +1746,40 @@ public static JNode Range(List args) return nums; } + public static JNode RecurseUntil(List args) + { + JNode node = args[0]; + if (!(args[1] is CurJson cj)) + throw new RemesPathArgumentException("second argument must be a functiont that returns a boolean", 1, FUNCTIONS["recurse_until"], args[1].type); + Func func = cj.function; + var results = new List(); + RecurseUntilHelper(node, func, results); + return new JArray(0, results); + } + + private static void RecurseUntilHelper(JNode node, Func func, List results) + { + try + { + if (func(node).value is bool b && b) + { + results.Add(node); + return; + } + } + catch { } + if (node is JArray jar && jar.children is List car) + { + for (int ii = 0; ii < car.Count; ii++) + RecurseUntilHelper(car[ii], func, results); + } + else if (node is JObject obj && obj.children is Dictionary cobj) + { + foreach (JNode child in cobj.Values) + RecurseUntilHelper(child, func, results); + } + } + public static JNode Values(List args) { var vals = new JArray(0, ((JObject)args[0]).children.Values.ToList()); @@ -3688,6 +3722,7 @@ public static JNode ObjectsToJNode(object obj) ["rand_schema"] = new ArgFunction(RandomFromSchema, "rand_schema", Dtype.ANYTHING, 1, 5, false, new Dtype[] { Dtype.OBJ, Dtype.INT, Dtype.INT, Dtype.BOOL, Dtype.BOOL }, isDeterministic: false), ["randint"] = new ArgFunction(RandomInteger, "randint", Dtype.INT, 1, 2, false, new Dtype[] {Dtype.INT, Dtype.INT}, false), ["range"] = new ArgFunction(Range, "range", Dtype.ARR, 1, 3, false, new Dtype[] {Dtype.INT, Dtype.INT, Dtype.INT}), + ["recurse_until"] = new ArgFunction(RecurseUntil, "recurse_until", Dtype.ARR, 2, 2, false, new Dtype[] { Dtype.ARR_OR_OBJ, Dtype.FUNCTION | Dtype.ANYTHING }, conditionalExecution: true), ["s_cat"] = new ArgFunction(StrCat, "s_cat", Dtype.STR, 1, int.MaxValue, false, new Dtype[] {Dtype.ANYTHING, /* any # of args */ Dtype.ANYTHING}), ["s_join"] = new ArgFunction(StringJoin, "s_join", Dtype.STR, 2, 2, false, new Dtype[] {Dtype.STR, Dtype.ARR}), ["set"] = new ArgFunction(Set, "set", Dtype.OBJ, 1, 1, false, new Dtype[] {Dtype.ARR}), diff --git a/JsonToolsNppPlugin/JsonToolsNppPlugin.csproj b/JsonToolsNppPlugin/JsonToolsNppPlugin.csproj index 4d3ce25..14e3d77 100644 --- a/JsonToolsNppPlugin/JsonToolsNppPlugin.csproj +++ b/JsonToolsNppPlugin/JsonToolsNppPlugin.csproj @@ -118,7 +118,6 @@ - diff --git a/JsonToolsNppPlugin/PluginInfrastructure/ClikeStringArray.cs b/JsonToolsNppPlugin/PluginInfrastructure/ClikeStringArray.cs deleted file mode 100644 index 05a6121..0000000 --- a/JsonToolsNppPlugin/PluginInfrastructure/ClikeStringArray.cs +++ /dev/null @@ -1,77 +0,0 @@ -// NPP plugin platform for .Net v0.94.00 by Kasper B. Graversen etc. -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Windows.Forms; - -namespace Kbg.NppPluginNET.PluginInfrastructure -{ - public class ClikeStringArray : IDisposable - { - IntPtr _nativeArray; - List _nativeItems; - bool _disposed = false; - - public ClikeStringArray(int num, int stringCapacity) - { - _nativeArray = Marshal.AllocHGlobal((num + 1) * IntPtr.Size); - _nativeItems = new List(); - for (int i = 0; i < num; i++) - { - IntPtr item = Marshal.AllocHGlobal(stringCapacity); - Marshal.WriteIntPtr(_nativeArray + (i * IntPtr.Size), item); - _nativeItems.Add(item); - } - Marshal.WriteIntPtr(_nativeArray + (num * IntPtr.Size), IntPtr.Zero); - } - public ClikeStringArray(List lstStrings) - { - _nativeArray = Marshal.AllocHGlobal((lstStrings.Count + 1) * IntPtr.Size); - _nativeItems = new List(); - for (int i = 0; i < lstStrings.Count; i++) - { - IntPtr item = Marshal.StringToHGlobalUni(lstStrings[i]); - Marshal.WriteIntPtr(_nativeArray + (i * IntPtr.Size), item); - _nativeItems.Add(item); - } - Marshal.WriteIntPtr(_nativeArray + (lstStrings.Count * IntPtr.Size), IntPtr.Zero); - } - - public IntPtr NativePointer { get { return _nativeArray; } } - public List ManagedStringsAnsi { get { return _getManagedItems(false); } } - public List ManagedStringsUnicode { get { return _getManagedItems(true); } } - List _getManagedItems(bool unicode) - { - List _managedItems = new List(); - for (int i = 0; i < _nativeItems.Count; i++) - { - if (unicode) _managedItems.Add(Marshal.PtrToStringUni(_nativeItems[i])); - else _managedItems.Add(Marshal.PtrToStringAnsi(_nativeItems[i])); - } - return _managedItems; - } - - public void Dispose() - { - try - { - if (!_disposed) - { - for (int i = 0; i < _nativeItems.Count; i++) - if (_nativeItems[i] != IntPtr.Zero) Marshal.FreeHGlobal(_nativeItems[i]); - if (_nativeArray != IntPtr.Zero) Marshal.FreeHGlobal(_nativeArray); - _disposed = true; - } - } - catch (Exception e) - { - MessageBox.Show(MethodBase.GetCurrentMethod().ToString() +": "+ e.Message, this.GetType().Name); - } - } - ~ClikeStringArray() - { - Dispose(); - } - } -} diff --git a/JsonToolsNppPlugin/PluginInfrastructure/Msgs_h.cs b/JsonToolsNppPlugin/PluginInfrastructure/Msgs_h.cs index a92ecc0..773b105 100644 --- a/JsonToolsNppPlugin/PluginInfrastructure/Msgs_h.cs +++ b/JsonToolsNppPlugin/PluginInfrastructure/Msgs_h.cs @@ -51,7 +51,9 @@ public enum NppMsg : uint ALL_OPEN_FILES = 0, PRIMARY_VIEW = 1, SECOND_VIEW = 2, - + /// + /// DO NOT USE! The internal Notepad++ code for this message uses lstrcpy, which is explicitly deprecated by Microsoft. + /// NPPM_GETOPENFILENAMES = Constants.NPPMSG + 8, NPPM_MODELESSDIALOG = Constants.NPPMSG + 12, diff --git a/JsonToolsNppPlugin/PluginInfrastructure/NotepadPPGateway.cs b/JsonToolsNppPlugin/PluginInfrastructure/NotepadPPGateway.cs index c973d59..a780ec1 100644 --- a/JsonToolsNppPlugin/PluginInfrastructure/NotepadPPGateway.cs +++ b/JsonToolsNppPlugin/PluginInfrastructure/NotepadPPGateway.cs @@ -1,5 +1,6 @@ // NPP plugin platform for .Net v0.94.00 by Kasper B. Graversen etc. using System; +using System.Collections.Generic; using System.Drawing; using System.Runtime.InteropServices; using System.Text; @@ -222,16 +223,24 @@ public int[] GetNppVersion() return new int[] { major, minor, bugfix }; } + /// + /// Get all open filenames in both views (all in first view, then all in second view).

+ /// Note that if the second view is not open, the last name in the array will be "new 1" because that is the name of the placeholder buffer that is always in an empty view. + ///
+ /// public string[] GetOpenFileNames() { - int nbFile = (int)Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_GETNBOPENFILES, 0, 0); - - using (ClikeStringArray cStrArray = new ClikeStringArray(nbFile, Win32.MAX_PATH)) - { - if (Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_GETOPENFILENAMES, cStrArray.NativePointer, nbFile) != IntPtr.Zero) - return cStrArray.ManagedStringsUnicode.ToArray(); - } - return null; + var bufs = new List(); + for (int view = 0; view < 2; view++) + { + int nbOpenFiles = (int)Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_GETNBOPENFILES, 0, view + 1); + for (int ii = 0; ii < nbOpenFiles; ii++) + { + IntPtr bufId = Win32.SendMessage(PluginBase.nppData._nppHandle, (uint)NppMsg.NPPM_GETBUFFERIDFROMPOS, ii, view); + bufs.Add(Npp.notepad.GetFilePath(bufId)); + } + } + return bufs.ToArray(); } public void AddModelessDialog(IntPtr formHandle) diff --git a/JsonToolsNppPlugin/Properties/AssemblyInfo.cs b/JsonToolsNppPlugin/Properties/AssemblyInfo.cs index 720c73d..70333d1 100644 --- a/JsonToolsNppPlugin/Properties/AssemblyInfo.cs +++ b/JsonToolsNppPlugin/Properties/AssemblyInfo.cs @@ -28,5 +28,5 @@ // Build Number // Revision // -[assembly: AssemblyVersion("8.3.1.1")] -[assembly: AssemblyFileVersion("8.3.1.1")] +[assembly: AssemblyVersion("8.3.1.2")] +[assembly: AssemblyFileVersion("8.3.1.2")] diff --git a/JsonToolsNppPlugin/Tests/RemesPathTests.cs b/JsonToolsNppPlugin/Tests/RemesPathTests.cs index eb9c515..5e0f99d 100644 --- a/JsonToolsNppPlugin/Tests/RemesPathTests.cs +++ b/JsonToolsNppPlugin/Tests/RemesPathTests.cs @@ -742,6 +742,12 @@ public static bool Test() new Query_DesiredResult("items(items(@)[1][1])", "[[\"a\",false],[\"b\",[\"a`g\",\"bah\"]]]"), new Query_DesiredResult("items(items(@)[1][1][a,b])", "[[\"a\",false],[\"b\",[\"a`g\",\"bah\"]]]"), new Query_DesiredResult("items(items(@)[1][1].g`[ab]`)", "[[\"a\",false],[\"b\",[\"a`g\",\"bah\"]]]"), + // ====================== recurse_until function for recursively searching for JNodes that satisfy a condition ====================== + new Query_DesiredResult("recurse_until(@, sum(@) <= 3)", "[[0, 1, 2], [], [1], [2], [3]]"), + new Query_DesiredResult("recurse_until(@.`7`, in(foo, @))", "[{\"foo\": 2}]"), + new Query_DesiredResult("recurse_until(@, in(foo, @))", $"[{fooStr}]"), + new Query_DesiredResult("recurse_until(j`[{\"Value\":100,\"Name\":\"GOOD\"},{\"Value\":200,\"Name\":\"GOOD\"}, {\"Value\":50,\"Name\":\"BAD\"},{\"Value\":150,\"Name\":\"BAD\"}]`, and(@.Name == GOOD, @.Value > 100))", "[{\"Value\": 200, \"Name\": \"GOOD\"}]"), + new Query_DesiredResult("recurse_until(@.bar, is_str(@))", "[\"a`g\", \"bah\"]"), }; int ii = 0; int testsFailed = 0; diff --git a/docs/RemesPath.md b/docs/RemesPath.md index d2ef6f5..3e3f220 100644 --- a/docs/RemesPath.md +++ b/docs/RemesPath.md @@ -565,6 +565,29 @@ Returns an array of integers. * `range(3, 1, -1)` returns `[3, 2]`. * `range(0, 6, 3)` returns `[0, 3]`. +--- +`recurse_until(node: anything, condition: function) -> array` + +Recursively searches `node` for any children `child` such that `condition(child)` returns `true`. + +Consider the input +```json +{ + "foo": {"value": 1, "name": "GOOD"}, + "bar_array": [ + {"name": "BAD", "value": 2}, + {"name": "GOOD", "value": -1}, + {"name": "GOOD", "value": 3} + ], + "name": "blah" +} +``` + +__Examples:__ +1. `recurse_until(@, in(name, @))` returns an array containing the input as its first and only element, because the recursive search halts as soon as `in(name, @)` is satisfied by the input. +2. `recurse_until(@, and(@.name == GOOD, @.value >= 0))` will return `[{"value":1,"name":"GOOD"},{"name":"GOOD","value":3}]`, because those are the two `name,value` arrays such that `name=GOOD` and `value>=0` +3. ``recurse_until(@, @ =~ `^[bB]`)`` will return `["BAD","blah"]`, because those are the two string values that start with `b` or `B`. + --- `s_cat(x: anything, ...: anything) -> string` diff --git a/most recent errors.txt b/most recent errors.txt index e38f6f4..2bc3d28 100644 --- a/most recent errors.txt +++ b/most recent errors.txt @@ -1,4 +1,4 @@ -Test results for JsonTools v8.3.1 on Notepad++ 8.7.4 64bit +Test results for JsonTools v8.3.1.2 on Notepad++ 8.7.4 64bit NOTE: Ctrl-F (regular expressions *on*) for "Failed [1-9]\d*" to find all failed tests Tests failed: YAML dumper ========================= @@ -107,7 +107,7 @@ Testing RemesPath parser and compiler The queried JSON in the RemesParser tests is named foo:{"foo": [[0, 1, 2], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]], "bar": {"a": false, "b": ["a`g", "bah"]}, "baz": "z", "quz": {}, "jub": [], "guzo": [[[1]], [[2], [3]]], "7": [{"foo": 2}, 1], "_": {"0": 0}} Failed 0 tests. -Passed 537 tests. +Passed 542 tests. ========================= Testing RemesPath throws errors on bad inputs ========================= @@ -206,33 +206,33 @@ Testing JsonParser performance Preview of json: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... -To convert JSON string of size 89556 into JNode took 2.904 +/- 1.895 ms over 32 trials -Load times (ms): 1, 2, 4, 8, 2, 6, 2, 2, 1, 4, 1, 1, 6, 1, 1, 1, 4, 1, 1, 1, 4, 1, 2, 4, 1, 1, 1, 4, 1, 1, 5, 1 +To convert JSON string of size 89556 into JNode took 2.952 +/- 1.999 ms over 32 trials +Load times (ms): 5, 4, 4, 1, 1, 1, 5, 1, 1, 6, 1, 1, 1, 4, 1, 1, 2, 7, 1, 1, 6, 1, 1, 1, 3, 1, 1, 6, 1, 1, 1, 4 ========================= Performance tests for RemesPath (float arithmetic) ========================= -Compiling query "@[@[:].a * @[:].t < @[:].e]" took 0.054 ms the first time, including approximately 0.057 ms to tokenize the query. Subsequent executions are effectively free due to caching. -To run pre-compiled query "@[@[:].a * @[:].t < @[:].e]" on JNode from JSON of size 89556 into took 0.026 +/- 0.007 ms over 40 trials -Query times (ms): 0.058, 0.035, 0.022, 0.022, 0.022, 0.023, 0.022, 0.03, 0.023, 0.023, 0.023, 0.022, 0.022, 0.026, 0.023, 0.023, 0.023, 0.024, 0.022, 0.025, 0.024, 0.023, 0.022, 0.022, 0.023, 0.026, 0.023, 0.023, 0.022, 0.023, 0.022, 0.026, 0.023, 0.024, 0.037, 0.036, 0.024, 0.045, 0.023, 0.024 +Compiling query "@[@[:].a * @[:].t < @[:].e]" took 0.063 ms the first time, including approximately 0.059 ms to tokenize the query. Subsequent executions are effectively free due to caching. +To run pre-compiled query "@[@[:].a * @[:].t < @[:].e]" on JNode from JSON of size 89556 into took 0.026 +/- 0.015 ms over 40 trials +Query times (ms): 0.119, 0.041, 0.023, 0.022, 0.023, 0.023, 0.023, 0.03, 0.023, 0.023, 0.022, 0.022, 0.04, 0.026, 0.022, 0.022, 0.022, 0.023, 0.022, 0.024, 0.022, 0.022, 0.022, 0.022, 0.023, 0.024, 0.022, 0.022, 0.023, 0.022, 0.021, 0.025, 0.024, 0.022, 0.022, 0.022, 0.022, 0.024, 0.022, 0.023 Preview of result: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... ========================= Performance tests for RemesPath (string operations) ========================= -Compiling query "@[@[:].z =~ `(?i)[a-z]{5}`]" took 0.036 ms the first time, including approximately 0.039 ms to tokenize the query. Subsequent executions are effectively free due to caching. -To run pre-compiled query "@[@[:].z =~ `(?i)[a-z]{5}`]" on JNode from JSON of size 89556 into took 0.124 +/- 0.423 ms over 40 trials -Query times (ms): 0.095, 0.06, 0.058, 0.057, 0.057, 0.056, 0.057, 0.057, 0.056, 0.056, 0.056, 0.056, 0.058, 0.053, 0.052, 0.053, 0.053, 0.052, 0.053, 0.053, 0.053, 0.052, 0.053, 0.052, 0.054, 0.053, 0.053, 0.06, 0.052, 0.052, 0.052, 0.053, 2.766, 0.064, 0.058, 0.056, 0.055, 0.055, 0.055, 0.055 +Compiling query "@[@[:].z =~ `(?i)[a-z]{5}`]" took 0.047 ms the first time, including approximately 0.05 ms to tokenize the query. Subsequent executions are effectively free due to caching. +To run pre-compiled query "@[@[:].z =~ `(?i)[a-z]{5}`]" on JNode from JSON of size 89556 into took 0.058 +/- 0.009 ms over 40 trials +Query times (ms): 0.102, 0.06, 0.059, 0.058, 0.064, 0.083, 0.056, 0.057, 0.056, 0.056, 0.056, 0.056, 0.056, 0.057, 0.056, 0.057, 0.056, 0.057, 0.057, 0.057, 0.057, 0.057, 0.057, 0.056, 0.057, 0.056, 0.057, 0.056, 0.055, 0.052, 0.053, 0.053, 0.052, 0.053, 0.053, 0.053, 0.053, 0.053, 0.052, 0.053 Preview of result: [{"A": "\n]o1VQ5t6g", "a": 4710024278, "b": 3268860721, "B": "g4Y7+ew^.v", "C": "NK nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" took 0.134 ms the first time, including approximately 0.132 ms to tokenize the query. Subsequent executions are effectively free due to caching. +ifelse(nmax_q > nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" took 0.267 ms the first time, including approximately 0.147 ms to tokenize the query. Subsequent executions are effectively free due to caching. To run pre-compiled query "var qmask = @[:].q; var nmax_q = max(@[qmask].n); var nmax_notq = max(@[not qmask].n); -ifelse(nmax_q > nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" on JNode from JSON of size 89556 into took 0.017 +/- 0.006 ms over 40 trials -Query times (ms): 0.055, 0.018, 0.016, 0.016, 0.015, 0.016, 0.015, 0.016, 0.015, 0.017, 0.016, 0.015, 0.015, 0.016, 0.015, 0.015, 0.016, 0.016, 0.016, 0.015, 0.016, 0.016, 0.015, 0.015, 0.016, 0.016, 0.015, 0.015, 0.016, 0.016, 0.016, 0.015, 0.016, 0.015, 0.015, 0.015, 0.016, 0.015, 0.015, 0.015 +ifelse(nmax_q > nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" on JNode from JSON of size 89556 into took 0.017 +/- 0.009 ms over 40 trials +Query times (ms): 0.074, 0.018, 0.016, 0.015, 0.015, 0.015, 0.015, 0.015, 0.016, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.016, 0.015, 0.015, 0.016, 0.016, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.016, 0.015, 0.015, 0.015, 0.016, 0.015, 0.015, 0.015, 0.016, 0.016, 0.015, 0.015, 0.015 Preview of result: "when q=false, nmax= 9830935647.0" ... ========================= @@ -271,11 +271,11 @@ Performance tests for RemesPath (references to compile-time constant variables) Compiling query "var X = X; var onetwo = j`[1, 2]`; -@[:]->at(@, X)->at(@, onetwo)" took 0.082 ms the first time, including approximately 0.106 ms to tokenize the query. Subsequent executions are effectively free due to caching. +@[:]->at(@, X)->at(@, onetwo)" took 0.072 ms the first time, including approximately 0.073 ms to tokenize the query. Subsequent executions are effectively free due to caching. To run pre-compiled query "var X = X; var onetwo = j`[1, 2]`; -@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.026 +/- 0.079 ms over 40 trials -Query times (ms): 0.045, 0.013, 0.013, 0.013, 0.012, 0.013, 0.012, 0.012, 0.013, 0.012, 0.013, 0.013, 0.012, 0.013, 0.013, 0.012, 0.013, 0.012, 0.013, 0.013, 0.012, 0.013, 0.012, 0.012, 0.013, 0.012, 0.013, 0.013, 0.518, 0.016, 0.012, 0.013, 0.012, 0.012, 0.012, 0.012, 0.012, 0.013, 0.012, 0.012 +@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.018 +/- 0.021 ms over 40 trials +Query times (ms): 0.042, 0.012, 0.012, 0.012, 0.012, 0.011, 0.14, 0.045, 0.023, 0.033, 0.022, 0.016, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.011, 0.012, 0.011, 0.012, 0.012, 0.011, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.011, 0.012, 0.012, 0.011, 0.012, 0.011 Preview of result: [[1695727848, 0.287562638736685], [2126430375, 0.00767794129708177], [5310550656, 0.380769772645687], [2519183283, 0.153176220930558], [6610062385, 0.662996225870666], [987168256, 0.924410189999928], [6615003609, 0.917112691225947], [4465232046, 0.684311931851536], [8654414565, 0.631485392105992], [ ... ========================= @@ -284,29 +284,29 @@ Performance tests for RemesPath (references to variables that are not compile-ti Compiling query "var X = @->`X`; var onetwo = @{1, 2}; -@[:]->at(@, X)->at(@, onetwo)" took 0.181 ms the first time, including approximately 0.118 ms to tokenize the query. Subsequent executions are effectively free due to caching. +@[:]->at(@, X)->at(@, onetwo)" took 0.096 ms the first time, including approximately 0.091 ms to tokenize the query. Subsequent executions are effectively free due to caching. To run pre-compiled query "var X = @->`X`; var onetwo = @{1, 2}; -@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.02 +/- 0.011 ms over 40 trials -Query times (ms): 0.066, 0.028, 0.016, 0.015, 0.016, 0.016, 0.016, 0.016, 0.034, 0.026, 0.046, 0.027, 0.048, 0.017, 0.016, 0.016, 0.016, 0.039, 0.015, 0.016, 0.016, 0.016, 0.016, 0.016, 0.015, 0.016, 0.016, 0.015, 0.016, 0.016, 0.015, 0.016, 0.016, 0.015, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016 +@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.033 +/- 0.078 ms over 40 trials +Query times (ms): 0.048, 0.016, 0.016, 0.016, 0.015, 0.016, 0.518, 0.024, 0.038, 0.019, 0.016, 0.043, 0.016, 0.016, 0.017, 0.016, 0.025, 0.026, 0.06, 0.017, 0.019, 0.017, 0.015, 0.015, 0.024, 0.015, 0.016, 0.03, 0.015, 0.016, 0.016, 0.016, 0.018, 0.017, 0.015, 0.016, 0.016, 0.026, 0.017, 0.017 Preview of result: [[1695727848, 0.287562638736685], [2126430375, 0.00767794129708177], [5310550656, 0.380769772645687], [2519183283, 0.153176220930558], [6610062385, 0.662996225870666], [987168256, 0.924410189999928], [6615003609, 0.917112691225947], [4465232046, 0.684311931851536], [8654414565, 0.631485392105992], [ ... ========================= Performance tests for RemesPath (simple string mutations) ========================= -Compiling query "@[:].z = s_sub(@, g, B)" took 0.04 ms the first time, including approximately 0.038 ms to tokenize the query. Subsequent executions are effectively free due to caching. -To run pre-compiled query "@[:].z = s_sub(@, g, B)" on JNode from JSON of size 89556 into took 0.018 +/- 0.019 ms over 40 trials -Query times (ms): 0.02, 0.011, 0.017, 0.017, 0.016, 0.015, 0.015, 0.014, 0.014, 0.014, 0.014, 0.111, 0.016, 0.014, 0.014, 0.014, 0.021, 0.015, 0.086, 0.024, 0.011, 0.01, 0.011, 0.01, 0.013, 0.01, 0.01, 0.01, 0.011, 0.02, 0.01, 0.009, 0.011, 0.011, 0.011, 0.01, 0.011, 0.009, 0.011, 0.011 +Compiling query "@[:].z = s_sub(@, g, B)" took 0.046 ms the first time, including approximately 0.046 ms to tokenize the query. Subsequent executions are effectively free due to caching. +To run pre-compiled query "@[:].z = s_sub(@, g, B)" on JNode from JSON of size 89556 into took 0.016 +/- 0.007 ms over 40 trials +Query times (ms): 0.025, 0.013, 0.012, 0.039, 0.012, 0.01, 0.012, 0.026, 0.01, 0.01, 0.012, 0.012, 0.015, 0.013, 0.015, 0.013, 0.014, 0.016, 0.014, 0.013, 0.016, 0.026, 0.013, 0.01, 0.011, 0.011, 0.011, 0.011, 0.011, 0.01, 0.034, 0.024, 0.015, 0.021, 0.026, 0.032, 0.027, 0.019, 0.014, 0.013 Preview of result: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... ========================= Performance tests for RemesPath (simple number mutations) ========================= -Compiling query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" took 0.057 ms the first time, including approximately 0.059 ms to tokenize the query. Subsequent executions are effectively free due to caching. -To run pre-compiled query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" on JNode from JSON of size 89556 into took 0.021 +/- 0.009 ms over 40 trials -Query times (ms): 0.031, 0.025, 0.019, 0.018, 0.019, 0.018, 0.018, 0.018, 0.02, 0.018, 0.019, 0.016, 0.017, 0.036, 0.029, 0.022, 0.018, 0.017, 0.017, 0.017, 0.017, 0.017, 0.018, 0.018, 0.016, 0.019, 0.016, 0.07, 0.034, 0.019, 0.018, 0.017, 0.017, 0.018, 0.017, 0.018, 0.017, 0.033, 0.017, 0.023 +Compiling query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" took 0.068 ms the first time, including approximately 0.078 ms to tokenize the query. Subsequent executions are effectively free due to caching. +To run pre-compiled query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" on JNode from JSON of size 89556 into took 0.031 +/- 0.015 ms over 40 trials +Query times (ms): 0.049, 0.035, 0.023, 0.017, 0.018, 0.022, 0.025, 0.025, 0.02, 0.02, 0.016, 0.016, 0.018, 0.019, 0.018, 0.019, 0.033, 0.028, 0.024, 0.022, 0.024, 0.018, 0.018, 0.018, 0.018, 0.023, 0.06, 0.039, 0.045, 0.045, 0.038, 0.038, 0.034, 0.068, 0.028, 0.025, 0.061, 0.052, 0.068, 0.048 Preview of result: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... ========================= @@ -316,55 +316,55 @@ Performance tests for RemesPath (mutations with a for loop) Compiling query "var xhalf = @[:].x < 0.5; for lx = zip(@[:].l, xhalf); lx[0] = ifelse(lx[1], foo, bar); -end for;" took 0.149 ms the first time, including approximately 0.141 ms to tokenize the query. Subsequent executions are effectively free due to caching. +end for;" took 0.225 ms the first time, including approximately 0.136 ms to tokenize the query. Subsequent executions are effectively free due to caching. To run pre-compiled query "var xhalf = @[:].x < 0.5; for lx = zip(@[:].l, xhalf); lx[0] = ifelse(lx[1], foo, bar); -end for;" on JNode from JSON of size 89556 into took 0.091 +/- 0.185 ms over 40 trials -Query times (ms): 0.063, 0.04, 0.042, 0.041, 0.038, 0.038, 1.232, 0.056, 0.087, 0.071, 0.048, 0.161, 0.076, 0.084, 0.046, 0.05, 0.039, 0.055, 0.103, 0.113, 0.08, 0.078, 0.051, 0.043, 0.04, 0.042, 0.051, 0.045, 0.043, 0.073, 0.047, 0.075, 0.09, 0.073, 0.074, 0.051, 0.061, 0.04, 0.041, 0.039 +end for;" on JNode from JSON of size 89556 into took 0.082 +/- 0.037 ms over 40 trials +Query times (ms): 0.071, 0.071, 0.073, 0.055, 0.096, 0.18, 0.253, 0.093, 0.075, 0.088, 0.102, 0.098, 0.076, 0.082, 0.074, 0.08, 0.11, 0.078, 0.078, 0.076, 0.079, 0.077, 0.08, 0.075, 0.069, 0.069, 0.071, 0.073, 0.069, 0.051, 0.042, 0.047, 0.076, 0.066, 0.046, 0.075, 0.048, 0.045, 0.056, 0.151 Preview of result: [["bar", false], ["bar", false], ["foo", true], ["foo", true], ["foo", true], ["foo", true], ["foo", true], ["bar", false], ["bar", false], ["bar", false], ["foo", true], ["foo", true], ["bar", false], ["bar", false], ["foo", true], ["bar", false], ["bar", false], ["bar", false], ["foo", true], ["ba ... ========================= Testing performance and correctness of parsing and dumping arrays of non-integer numbers ========================= -To parse arrays of 5500 non-integer numbers (representative length = 105255, representative example preview: "[-175.04e-98, 64.07492021348542271, 96016142.6131511921e3, 3666242.81693e-48, 69.62439108824, -750528233.5574e96, -5401.260, 6631.972631338, -4519.1738e-41, -24796623.587, 1729.367354467e-29, 81663.55...") took 2.041 +/- 0.364 ms over 40 trials -Times to parse (ms): 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2 -To re-compress (convert back to minimal JSON strings) the arrays made from parsing those strings took 6.853 +/- 0.407 ms over 40 trials -Times to re-compress (ms): 6, 7, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 7, 7, 7, 6, 6, 7, 6, 7, 6, 6, 6, 6, 6, 7, 7, 6 -Representative example of result of re-compression = "[-1.7504E-96, 64.074920213485427, 96016142613.1512, 3.66624281693E-42, 69.62439108824, -7.505282335574E+104, -5401.26, 6631.972631338, -4.5191738E-38, -24796623.587, 1.729367354467E-26, 81663.5592, 8...." +To parse arrays of 5500 non-integer numbers (representative length = 105744, representative example preview: "[-7.094011463950096597, 510.6600752103829e58, -587523.06995757435, 632995.291345032233400e-23, -808.133085452777e51, -25.1121855e83, 7743001.188605723e75, 36.581453851600, 4964534.513, -9.5177187979, ...") took 2.887 +/- 2.733 ms over 40 trials +Times to parse (ms): 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 1, 1, 2, 2, 2, 2, 2, 12, 1, 2, 3, 2, 1, 2, 1, 1, 1, 1, 1, 2, 16, 1, 1 +To re-compress (convert back to minimal JSON strings) the arrays made from parsing those strings took 8.552 +/- 1.55 ms over 40 trials +Times to re-compress (ms): 7, 8, 7, 8, 7, 8, 7, 9, 10, 9, 10, 10, 10, 10, 10, 10, 13, 8, 8, 9, 8, 10, 7, 8, 9, 8, 8, 10, 8, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 7 +Representative example of result of re-compression = "[-7.0940114639500962, 5.1066007521038287E+60, -587523.06995757436, 6.3299529134503223E-18, -8.08133085452777E+53, -2.51121855E+84, 7.7430011886057231E+81, 36.5814538516, 4964534.513, -9.5177187979, -5..." ========================= Testing performance of JSON compression and pretty-printing ========================= Preview of json: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... -To compress JNode from JSON string of 89556 took 3.985 +/- 0.709 ms over 64 trials (minimal whitespace, sortKeys=TRUE) -To compress JNode from JSON string of 89556 took 2.042 +/- 0.186 ms over 64 trials (minimal whitespace, sortKeys=FALSE) -To Google-style pretty-print JNode from JSON string of 89556 took 4.205 +/- 0.232 ms over 64 trials (sortKeys=true, indent=4) -To Whitesmith-style pretty-print JNode from JSON string of 89556 took 4.174 +/- 0.201 ms over 64 trials (sortKeys=true, indent=4) -To PPrint-style pretty-print JNode from JSON string of 89556 took 6.072 +/- 0.473 ms over 64 trials (sortKeys=true, indent=4) +To compress JNode from JSON string of 89556 took 3.99 +/- 0.52 ms over 64 trials (minimal whitespace, sortKeys=TRUE) +To compress JNode from JSON string of 89556 took 2.09 +/- 0.314 ms over 64 trials (minimal whitespace, sortKeys=FALSE) +To Google-style pretty-print JNode from JSON string of 89556 took 4.252 +/- 0.273 ms over 64 trials (sortKeys=true, indent=4) +To Whitesmith-style pretty-print JNode from JSON string of 89556 took 4.224 +/- 0.205 ms over 64 trials (sortKeys=true, indent=4) +To PPrint-style pretty-print JNode from JSON string of 89556 took 6.189 +/- 0.622 ms over 64 trials (sortKeys=true, indent=4) ========================= Testing performance of JsonSchemaValidator and random JSON creation ========================= -To create a random set of JSON from file at path C:\Program Files\Notepad++\plugins\JsonTools\testfiles\tweet_schema.json of size 194689 (array of 15 items) based on the matching schema took 6.294 +/- 2.844 ms over 25 trials -To compile the schema to a validation function took 0.561 +/- 0.98 ms over 25 trials -To validate JSON of size 194689 (array of 15 items) based on the compiled schema took 1.004 +/- 0.141 ms over 25 trials +To create a random set of JSON from file at path C:\Program Files\Notepad++\plugins\JsonTools\testfiles\tweet_schema.json of size 124239 (array of 15 items) based on the matching schema took 5.846 +/- 2.84 ms over 25 trials +To compile the schema to a validation function took 0.643 +/- 1.184 ms over 25 trials +To validate JSON of size 124239 (array of 15 items) based on the compiled schema took 0.965 +/- 0.18 ms over 25 trials ========================= Testing performance of random JSON from schema with patterns and patternProperties ========================= -To create a random set of JSON from string (see TestRunner.cs) of size 31672 (array of 120 items) based on the matching schema took 1.848 +/- 0.828 ms over 25 trials -To compile the schema to a validation function took 0.307 +/- 0.271 ms over 25 trials -To validate JSON of size 31672 (array of 120 items) based on the compiled schema took 8.986 +/- 0.257 ms over 25 trials +To create a random set of JSON from string (see TestRunner.cs) of size 33442 (array of 120 items) based on the matching schema took 1.443 +/- 0.669 ms over 25 trials +To compile the schema to a validation function took 0.278 +/- 0.122 ms over 25 trials +To validate JSON of size 33442 (array of 120 items) based on the compiled schema took 9.382 +/- 0.789 ms over 25 trials ========================= Testing performance of random JSON from schema *ignoring* patterns and patternProperties ========================= -To create a random set of JSON from string (see TestRunner.cs) of size 10943 (array of 120 items) based on the matching schema took 0.881 +/- 0.585 ms over 25 trials -To compile the schema to a validation function took 0.227 +/- 0.02 ms over 25 trials -To validate JSON of size 10943 (array of 120 items) based on the compiled schema took 5.422 +/- 0.261 ms over 25 trials +To create a random set of JSON from string (see TestRunner.cs) of size 12196 (array of 120 items) based on the matching schema took 0.891 +/- 0.722 ms over 25 trials +To compile the schema to a validation function took 0.233 +/- 0.037 ms over 25 trials +To validate JSON of size 12196 (array of 120 items) based on the compiled schema took 5.473 +/- 0.216 ms over 25 trials ========================= Testing JSON grepper's API request tool =========================