Skip to content

Commit

Permalink
initial effort to move global variables to JQueryContext
Browse files Browse the repository at this point in the history
the current status quo means that RemesPath functions
    using global variables like loopCountValue can't be multithreadedd
    because of race conditions.
If I could figure out a way to make these global variables thread-safe,
    that would open up the possibility of multithreaded RemesPath.
Unfortunately this is a bit more difficult than I had envisioned, so I'm
    leaving this unfinished for the time being.
  • Loading branch information
molsonkiko committed May 22, 2024
1 parent 3ecaf28 commit 52edb18
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 76 deletions.
42 changes: 14 additions & 28 deletions JsonToolsNppPlugin/JSONTools/JNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,8 @@ public class JQueryContext : JNode
/// Will the query mutate input?
/// </summary>
private bool mutatesInput = false;
public Dictionary<string, object> Globals;
public bool UsesGlobals { get; private set; } = false;
public override bool CanOperate => true;
public override bool IsMutator => mutatesInput;
private List<JNode> statements;
Expand All @@ -1975,33 +1977,40 @@ public class JQueryContext : JNode
public JQueryContext() : base(null, Dtype.UNKNOWN, 0)
{
statements = new List<JNode>();
Globals = new Dictionary<string, object>();
locals = new Dictionary<string, JNode>();
cachedLocals = new Dictionary<string, JNode>();
loopVariableAssignmentStack = new List<VarAssign>();
tokenIndicesOfVariableReferences = new Dictionary<int, string>();
}

private void InitializeGlobals()
{
if (UsesGlobals)
Globals = new Dictionary<string, object>();
}

/// <summary>
/// Run all the statements, and return the result.
/// </summary>
public override JNode Operate(JNode inp)
{
ArgFunction.InitializeGlobals(mutatesInput);
InitializeGlobals();
JNode lastStatement = EvaluateStatementsFromStartToEnd(inp, 0, statements.Count);
Reset();
return lastStatement;
}

/// <summary>
/// a "simple query" is a query with one statement and no variable assignments.<br></br>
/// a "simple query" is a query with one statement and no variable assignments and no mutation of this object's <see cref="Globals"/> value<br></br>
/// This definition is useful because up until JsonTools 5.7 it was the only kind of query possible.<br></br>
/// If true, you can keep the first statement and discard the context.
/// </summary>
public bool IsSimpleQuery
{
get
{
if (statements.Count > 1)
if (statements.Count > 1 || UsesGlobals)
return false;
JNode firstStatement = statements[0];
return !(firstStatement is VarAssign);
Expand Down Expand Up @@ -2095,30 +2104,7 @@ public JNode GetQuery()
{
if (IsSimpleQuery)
{
JNode firstStatement = statements[0];
if (firstStatement is CurJson cj)
{
Func<JNode, JNode> fun = cj.function;
JNode outfunc(JNode x)
{
// need to reset globals before each evalutation
ArgFunction.InitializeGlobals(false);
return fun(x);
}
return new CurJson(cj.type, outfunc);
}
else if (firstStatement is JMutator jm && jm.selector is CurJson selector)
{
Func<JNode, JNode> selectorFunc = selector.function;
JNode newSelector(JNode x)
{
ArgFunction.InitializeGlobals(true);
return selectorFunc(x);
}
jm.selector = new CurJson(selector.type, newSelector);
return jm;
}
return firstStatement;
return statements[0];
}
// clear locals because it was necessary to use actual values while building for propagation
Reset();
Expand Down Expand Up @@ -2224,7 +2210,6 @@ private JNode EvaluateStatementsFromStartToEnd(JNode inp, int start, int end)
indexInStatements++;
}
}
ArgFunction.regexSearchResultsShouldBeCached = true;
return lastStatement;
}

Expand All @@ -2233,6 +2218,7 @@ private JNode EvaluateStatementsFromStartToEnd(JNode inp, int start, int end)
/// </summary>
private void Reset()
{
Globals = new Dictionary<string, object>();
foreach (string varname in Varnames())
locals[varname] = null;
cachedLocals.Clear();
Expand Down
Loading

0 comments on commit 52edb18

Please sign in to comment.