From 84b9e1e22d21d6d0a9c651c60096c441ef064401 Mon Sep 17 00:00:00 2001 From: rschoene <rene.schoene@tu-dresden.de> Date: Mon, 5 Sep 2022 13:47:49 +0200 Subject: [PATCH] move aspects into separate template file - also add method to reset evaluation counter --- .../main/resources/EvaluationCounter.mustache | 105 +++++++ .../resources/RagConnectObserver.mustache | 178 +++++++++++ .../src/main/resources/ragconnect.mustache | 276 +----------------- 3 files changed, 285 insertions(+), 274 deletions(-) create mode 100644 ragconnect.base/src/main/resources/EvaluationCounter.mustache create mode 100644 ragconnect.base/src/main/resources/RagConnectObserver.mustache diff --git a/ragconnect.base/src/main/resources/EvaluationCounter.mustache b/ragconnect.base/src/main/resources/EvaluationCounter.mustache new file mode 100644 index 0000000..5b43c20 --- /dev/null +++ b/ragconnect.base/src/main/resources/EvaluationCounter.mustache @@ -0,0 +1,105 @@ +aspect EvaluationCounter { + public String ASTNode.{{evaluationCounterSummaryMethodName}}() { + {{#configEvaluationCounter}} + return {{evaluationCounterVariable}}.summary(); + {{/configEvaluationCounter}} + {{^configEvaluationCounter}} + String message = "Option --evaluationCounter was not set. No Summary available"; + {{logWarn}}(message); + return message; + {{/configEvaluationCounter}} + } +{{#configEvaluationCounter}} + static EvaluationCounter ASTNode.{{evaluationCounterVariable}} = new EvaluationCounter(); + public void {{parentTypeName}}.ragconnectResetEvaluationCounter() { + {{#configEvaluationCounter}} + {{evaluationCounterVariable}}.reset(); + {{/configEvaluationCounter}} + {{^configEvaluationCounter}} + {{logWarn}}("Option --evaluationCounter was not set. Nothing to reset!"); + {{/configEvaluationCounter}} + } + + public class EvaluationCounter { + private java.util.Map<String, java.util.Map<String, {{evaluationCounterInnerClass}}>> counters = new java.util.HashMap<>(); + private final java.util.function.Function<? super String, ? extends java.util.Map<String, {{evaluationCounterInnerClass}}>> parentAbsent = key -> { + return new java.util.HashMap<>(); + }; + private final java.util.function.Function<? super String, ? extends {{evaluationCounterInnerClass}}> entityAbsent = key -> { + return new {{evaluationCounterInnerClass}}(); + }; + + public void incrementReceive(String parentTypeName, String entityName) { + getCounter(parentTypeName, entityName).receive += 1; + } + + public void incrementSend(String parentTypeName, String entityName) { + getCounter(parentTypeName, entityName).send += 1; + } + + public void incrementCall(String parentTypeName, String entityName) { + getCounter(parentTypeName, entityName).call += 1; + } + + public void incrementFirstNull(String parentTypeName, String entityName) { + getCounter(parentTypeName, entityName).firstNull += 1; + } + + public void incrementSkip(String parentTypeName, String entityName) { + getCounter(parentTypeName, entityName).skip += 1; + } + + public void incrementException(String parentTypeName, String entityName) { + getCounter(parentTypeName, entityName).exception += 1; + } + + public void incrementReject(String parentTypeName, String entityName) { + getCounter(parentTypeName, entityName).reject += 1; + } + + public String summary() { + StringBuilder sb = new StringBuilder(); + // header + sb.append("parentTypeName,entityName,receive,send,call,firstNull,skip,exception,reject").append("\n"); + // values + java.util.Set<String> sortedParentTypes = new java.util.TreeSet<>(counters.keySet()); + for (String parentType : sortedParentTypes) { + java.util.Set<String> sortedEntityNames = new java.util.TreeSet<>(counters.get(parentType).keySet()); + for (String entityName : sortedEntityNames) { + {{evaluationCounterInnerClass}} count = getCounter(parentType, entityName); + java.util.StringJoiner sj = new java.util.StringJoiner(",", "", "\n"); + sj.add(parentType) + .add(entityName) + .add(Integer.toString(count.receive)) + .add(Integer.toString(count.send)) + .add(Integer.toString(count.call)) + .add(Integer.toString(count.firstNull)) + .add(Integer.toString(count.skip)) + .add(Integer.toString(count.exception)) + .add(Integer.toString(count.reject)) + ; + sb.append(sj); + } + } + return sb.toString(); + } + + private {{evaluationCounterInnerClass}} getCounter(String parentTypeName, String entityName) { + return counters.computeIfAbsent(parentTypeName, parentAbsent).computeIfAbsent(entityName, entityAbsent); + } + public void reset() { + counters = new java.util.HashMap<>(); + } + } + + class {{evaluationCounterInnerClass}} { + int receive = 0; + int send = 0; + int call = 0; + int firstNull = 0; + int skip = 0; + int exception = 0; + int reject = 0; + } +{{/configEvaluationCounter}} +} diff --git a/ragconnect.base/src/main/resources/RagConnectObserver.mustache b/ragconnect.base/src/main/resources/RagConnectObserver.mustache new file mode 100644 index 0000000..24ed61c --- /dev/null +++ b/ragconnect.base/src/main/resources/RagConnectObserver.mustache @@ -0,0 +1,178 @@ +{{#configIncrementalOptionActive}} +aspect RagConnectObserver { + + class RagConnectObserver implements ASTState.Trace.Receiver { + + class RagConnectObserverEntry { + final ASTNode node; + final String attributeString; + final boolean compareParams; + final Object params; + final Runnable attributeCall; + //final RagConnectToken connectToken; + final java.util.List<RagConnectToken> connectList = new java.util.ArrayList<>(); + + RagConnectObserverEntry(ASTNode node, String attributeString, + boolean compareParams, Object params, Runnable attributeCall) { + this.node = node; + this.attributeString = attributeString; + this.compareParams = compareParams; + this.params = params; + this.attributeCall = attributeCall; + } + + boolean baseMembersEqualTo(RagConnectObserverEntry other) { + return baseMembersEqualTo(other.node, other.attributeString, other.compareParams, other.params); + } + + boolean baseMembersEqualTo(ASTNode otherNode, String otherAttributeString, + boolean forceCompareParams, Object otherParams) { + return this.node.equals(otherNode) && + this.attributeString.equals(otherAttributeString) && + //this.compareParams == otherCompareParams && + (!(this.compareParams || forceCompareParams) || java.util.Objects.equals(this.params, otherParams)); + } + } + +{{#configExperimentalJastAdd329}} + class RagConnectObserverStartEntry { + final ASTNode node; + final String attributeString; + final Object flushIncToken; + RagConnectObserverStartEntry(ASTNode node, String attributeString, Object flushIncToken) { + this.node = node; + this.attributeString = attributeString; + this.flushIncToken = flushIncToken; + } + } +{{/configExperimentalJastAdd329}} + + ASTState.Trace.Receiver oldReceiver; + + java.util.List<RagConnectObserverEntry> observedNodes = new java.util.ArrayList<>(); + +{{#configExperimentalJastAdd329}} + java.util.Set<RagConnectObserverEntry> entryQueue = new java.util.HashSet<>(); + java.util.Deque<RagConnectObserverStartEntry> startEntries = new java.util.LinkedList<>(); +{{/configExperimentalJastAdd329}} + + RagConnectObserver(ASTNode node) { + // set the receiver. potentially dangerous because overriding existing receiver! + oldReceiver = node.trace().getReceiver(); + node.trace().setReceiver(this); + } + + void add(RagConnectToken connectToken, ASTNode node, boolean compareParams, Object params, + Runnable attributeCall, String attributeString) { + {{#configLoggingEnabledForIncremental}} + {{logDebug}}("** observer add: {{log_}} on {{log_}}{{log_}}", + node, attributeString, (compareParams ? " (parameterized)" : "")); + {{/configLoggingEnabledForIncremental}} + // either add to an existing entry (with same node, attribute, params) or create new entry + boolean needNewEntry = true; + for (RagConnectObserverEntry entry : observedNodes) { + if (entry.baseMembersEqualTo(node, attributeString, true, params)) { + entry.connectList.add(connectToken); + needNewEntry = false; + break; + } + } + if (needNewEntry) { + RagConnectObserverEntry newEntry = new RagConnectObserverEntry(node, attributeString, + compareParams, params, attributeCall); + newEntry.connectList.add(connectToken); + observedNodes.add(newEntry); + } + } + + void remove(RagConnectToken connectToken) { + java.util.List<RagConnectObserverEntry> entriesToDelete = new java.util.ArrayList<>(); + for (RagConnectObserverEntry entry : observedNodes) { + entry.connectList.remove(connectToken); + if (entry.connectList.isEmpty()) { + entriesToDelete.add(entry); + } + } + observedNodes.removeAll(entriesToDelete); + } + + @Override + public void accept(ASTState.Trace.Event event, ASTNode node, String attribute, Object params, Object value) { + oldReceiver.accept(event, node, attribute, params, value); +{{#configExperimentalJastAdd329}} + // react to INC_FLUSH_START and remember entry + if (event == ASTState.Trace.Event.INC_FLUSH_START) { + {{#configLoggingEnabledForIncremental}} + {{logDebug}}("** observer start: {{log_}} on {{log_}}", node, attribute); + {{/configLoggingEnabledForIncremental}} + startEntries.addFirst(new RagConnectObserverStartEntry(node, attribute, value)); + return; + } + + // react to INC_FLUSH_END and process queued entries, if it matches start entry + if (event == ASTState.Trace.Event.INC_FLUSH_END) { + if (startEntries.isEmpty()) { + {{#configLoggingEnabledForIncremental}} + {{logDebug}}("** observer end without start! for {{log_}} on {{log_}}", node, attribute); + {{/configLoggingEnabledForIncremental}} + return; + } + RagConnectObserverStartEntry startEntry = startEntries.peekFirst(); + if (node == startEntry.node && + attribute == startEntry.attributeString && + value == startEntry.flushIncToken) { + // create a copy of the queue to avoid entering this again causing an endless recursion + RagConnectObserverEntry[] entriesToProcess = entryQueue.toArray(new RagConnectObserverEntry[entryQueue.size()]); + entryQueue.clear(); + startEntries.removeFirst(); + {{#configLoggingEnabledForIncremental}} + {{logDebug}}("** observer process (entries: {{log_}}): {{log_}} on {{log_}}", + entriesToProcess.length, node, attribute); + {{/configLoggingEnabledForIncremental}} + for (RagConnectObserverEntry entry : entriesToProcess) { + entry.attributeCall.run(); + } + return; + } + } + +{{/configExperimentalJastAdd329}} + // ignore all other events but INC_FLUSH_ATTR + if (event != ASTState.Trace.Event.INC_FLUSH_ATTR) { + return; + } + + {{#configLoggingEnabledForIncremental}} + {{logDebug}}("** observer check INC_FLUSH_ATTR event: {{log_}} on {{log_}}", node, attribute); + {{/configLoggingEnabledForIncremental}} + // iterate through list, if matching pair. could maybe be more efficient. + for (RagConnectObserverEntry entry : observedNodes) { + if (entry.baseMembersEqualTo(node, attribute, false, params)) { + // hit. call the attribute/nta-token + {{#configLoggingEnabledForIncremental}} + {{logDebug}}("** observer hit: {{log_}} on {{log_}}", entry.node, entry.attributeString); + {{/configLoggingEnabledForIncremental}} +{{#configExperimentalJastAdd329}} + entryQueue.add(entry); +{{/configExperimentalJastAdd329}} +{{^configExperimentalJastAdd329}} + entry.attributeCall.run(); +{{/configExperimentalJastAdd329}} + } + } + } + } + + private static RagConnectObserver ASTNode.{{observerInstanceFieldName}}; + RagConnectObserver ASTNode.{{observerInstanceSingletonMethodName}}() { + if ({{observerInstanceFieldName}} == null) { + // does not matter, which node is used to create the observer as ASTState/tracing is also static + {{observerInstanceFieldName}} = new RagConnectObserver(this); + } + return {{observerInstanceFieldName}}; + } + void ASTNode.{{observerInstanceResetMethodName}}() { + {{observerInstanceFieldName}} = null; + } +} +{{/configIncrementalOptionActive}} diff --git a/ragconnect.base/src/main/resources/ragconnect.mustache b/ragconnect.base/src/main/resources/ragconnect.mustache index 738ecbe..df44d40 100644 --- a/ragconnect.base/src/main/resources/ragconnect.mustache +++ b/ragconnect.base/src/main/resources/ragconnect.mustache @@ -63,8 +63,6 @@ aspect RagConnect { return this; } -{{!{{> ListAspect}} - static void ASTNode.{{logConsoleOut}}(String message, Object... args) { System.out.println(String.format(message, args)); } @@ -97,276 +95,6 @@ aspect RagConnect { } } -{{#configIncrementalOptionActive}} -aspect RagConnectObserver { - - class RagConnectObserver implements ASTState.Trace.Receiver { - - class RagConnectObserverEntry { - final ASTNode node; - final String attributeString; - final boolean compareParams; - final Object params; - final Runnable attributeCall; - //final RagConnectToken connectToken; - final java.util.List<RagConnectToken> connectList = new java.util.ArrayList<>(); - - RagConnectObserverEntry(ASTNode node, String attributeString, - boolean compareParams, Object params, Runnable attributeCall) { - this.node = node; - this.attributeString = attributeString; - this.compareParams = compareParams; - this.params = params; - this.attributeCall = attributeCall; - } +{{> RagConnectObserver}} - boolean baseMembersEqualTo(RagConnectObserverEntry other) { - return baseMembersEqualTo(other.node, other.attributeString, other.compareParams, other.params); - } - - boolean baseMembersEqualTo(ASTNode otherNode, String otherAttributeString, - boolean forceCompareParams, Object otherParams) { - return this.node.equals(otherNode) && - this.attributeString.equals(otherAttributeString) && - //this.compareParams == otherCompareParams && - (!(this.compareParams || forceCompareParams) || java.util.Objects.equals(this.params, otherParams)); - } - } - -{{#configExperimentalJastAdd329}} - class RagConnectObserverStartEntry { - final ASTNode node; - final String attributeString; - final Object flushIncToken; - RagConnectObserverStartEntry(ASTNode node, String attributeString, Object flushIncToken) { - this.node = node; - this.attributeString = attributeString; - this.flushIncToken = flushIncToken; - } - } -{{/configExperimentalJastAdd329}} - - ASTState.Trace.Receiver oldReceiver; - - java.util.List<RagConnectObserverEntry> observedNodes = new java.util.ArrayList<>(); - -{{#configExperimentalJastAdd329}} - java.util.Set<RagConnectObserverEntry> entryQueue = new java.util.HashSet<>(); - java.util.Deque<RagConnectObserverStartEntry> startEntries = new java.util.LinkedList<>(); -{{/configExperimentalJastAdd329}} - - RagConnectObserver(ASTNode node) { - // set the receiver. potentially dangerous because overriding existing receiver! - oldReceiver = node.trace().getReceiver(); - node.trace().setReceiver(this); - } - - void add(RagConnectToken connectToken, ASTNode node, boolean compareParams, Object params, - Runnable attributeCall, String attributeString) { - {{#configLoggingEnabledForIncremental}} - {{logDebug}}("** observer add: {{log_}} on {{log_}}{{log_}}", - node, attributeString, (compareParams ? " (parameterized)" : "")); - {{/configLoggingEnabledForIncremental}} - // either add to an existing entry (with same node, attribute, params) or create new entry - boolean needNewEntry = true; - for (RagConnectObserverEntry entry : observedNodes) { - if (entry.baseMembersEqualTo(node, attributeString, true, params)) { - entry.connectList.add(connectToken); - needNewEntry = false; - break; - } - } - if (needNewEntry) { - RagConnectObserverEntry newEntry = new RagConnectObserverEntry(node, attributeString, - compareParams, params, attributeCall); - newEntry.connectList.add(connectToken); - observedNodes.add(newEntry); - } - } - - void remove(RagConnectToken connectToken) { - java.util.List<RagConnectObserverEntry> entriesToDelete = new java.util.ArrayList<>(); - for (RagConnectObserverEntry entry : observedNodes) { - entry.connectList.remove(connectToken); - if (entry.connectList.isEmpty()) { - entriesToDelete.add(entry); - } - } - observedNodes.removeAll(entriesToDelete); - } - - @Override - public void accept(ASTState.Trace.Event event, ASTNode node, String attribute, Object params, Object value) { - oldReceiver.accept(event, node, attribute, params, value); -{{#configExperimentalJastAdd329}} - // react to INC_FLUSH_START and remember entry - if (event == ASTState.Trace.Event.INC_FLUSH_START) { - {{#configLoggingEnabledForIncremental}} - {{logDebug}}("** observer start: {{log_}} on {{log_}}", node, attribute); - {{/configLoggingEnabledForIncremental}} - startEntries.addFirst(new RagConnectObserverStartEntry(node, attribute, value)); - return; - } - - // react to INC_FLUSH_END and process queued entries, if it matches start entry - if (event == ASTState.Trace.Event.INC_FLUSH_END) { - if (startEntries.isEmpty()) { - {{#configLoggingEnabledForIncremental}} - {{logDebug}}("** observer end without start! for {{log_}} on {{log_}}", node, attribute); - {{/configLoggingEnabledForIncremental}} - return; - } - RagConnectObserverStartEntry startEntry = startEntries.peekFirst(); - if (node == startEntry.node && - attribute == startEntry.attributeString && - value == startEntry.flushIncToken) { - // create a copy of the queue to avoid entering this again causing an endless recursion - RagConnectObserverEntry[] entriesToProcess = entryQueue.toArray(new RagConnectObserverEntry[entryQueue.size()]); - entryQueue.clear(); - startEntries.removeFirst(); - {{#configLoggingEnabledForIncremental}} - {{logDebug}}("** observer process (entries: {{log_}}): {{log_}} on {{log_}}", - entriesToProcess.length, node, attribute); - {{/configLoggingEnabledForIncremental}} - for (RagConnectObserverEntry entry : entriesToProcess) { - entry.attributeCall.run(); - } - return; - } - } - -{{/configExperimentalJastAdd329}} - // ignore all other events but INC_FLUSH_ATTR - if (event != ASTState.Trace.Event.INC_FLUSH_ATTR) { - return; - } - - {{#configLoggingEnabledForIncremental}} - {{logDebug}}("** observer check INC_FLUSH_ATTR event: {{log_}} on {{log_}}", node, attribute); - {{/configLoggingEnabledForIncremental}} - // iterate through list, if matching pair. could maybe be more efficient. - for (RagConnectObserverEntry entry : observedNodes) { - if (entry.baseMembersEqualTo(node, attribute, false, params)) { - // hit. call the attribute/nta-token - {{#configLoggingEnabledForIncremental}} - {{logDebug}}("** observer hit: {{log_}} on {{log_}}", entry.node, entry.attributeString); - {{/configLoggingEnabledForIncremental}} -{{#configExperimentalJastAdd329}} - entryQueue.add(entry); -{{/configExperimentalJastAdd329}} -{{^configExperimentalJastAdd329}} - entry.attributeCall.run(); -{{/configExperimentalJastAdd329}} - } - } - } - } - - private static RagConnectObserver ASTNode.{{observerInstanceFieldName}}; - RagConnectObserver ASTNode.{{observerInstanceSingletonMethodName}}() { - if ({{observerInstanceFieldName}} == null) { - // does not matter, which node is used to create the observer as ASTState/tracing is also static - {{observerInstanceFieldName}} = new RagConnectObserver(this); - } - return {{observerInstanceFieldName}}; - } - void ASTNode.{{observerInstanceResetMethodName}}() { - {{observerInstanceFieldName}} = null; - } -} -{{/configIncrementalOptionActive}} - -aspect EvaluationCounter { - public String ASTNode.{{evaluationCounterSummaryMethodName}}() { - {{#configEvaluationCounter}} - return {{evaluationCounterVariable}}.summary(); - {{/configEvaluationCounter}} - {{^configEvaluationCounter}} - String message = "Option --evaluationCounter was not set. No Summary available"; - {{logWarn}}(message); - return message; - {{/configEvaluationCounter}} - } -{{#configEvaluationCounter}} - static EvaluationCounter ASTNode.{{evaluationCounterVariable}} = new EvaluationCounter(); - - public class EvaluationCounter { - private java.util.Map<String, java.util.Map<String, {{evaluationCounterInnerClass}}>> counters = new java.util.HashMap<>(); - private final java.util.function.Function<? super String, ? extends java.util.Map<String, {{evaluationCounterInnerClass}}>> parentAbsent = key -> { - return new java.util.HashMap<>(); - }; - private final java.util.function.Function<? super String, ? extends {{evaluationCounterInnerClass}}> entityAbsent = key -> { - return new {{evaluationCounterInnerClass}}(); - }; - - public void incrementReceive(String parentTypeName, String entityName) { - getCounter(parentTypeName, entityName).receive += 1; - } - - public void incrementSend(String parentTypeName, String entityName) { - getCounter(parentTypeName, entityName).send += 1; - } - - public void incrementCall(String parentTypeName, String entityName) { - getCounter(parentTypeName, entityName).call += 1; - } - - public void incrementFirstNull(String parentTypeName, String entityName) { - getCounter(parentTypeName, entityName).firstNull += 1; - } - - public void incrementSkip(String parentTypeName, String entityName) { - getCounter(parentTypeName, entityName).skip += 1; - } - - public void incrementException(String parentTypeName, String entityName) { - getCounter(parentTypeName, entityName).exception += 1; - } - - public void incrementReject(String parentTypeName, String entityName) { - getCounter(parentTypeName, entityName).reject += 1; - } - - public String summary() { - StringBuilder sb = new StringBuilder(); - // header - sb.append("parentTypeName,entityName,receive,send,call,firstNull,skip,exception,reject").append("\n"); - // values - java.util.Set<String> sortedParentTypes = new java.util.TreeSet<>(counters.keySet()); - for (String parentType : sortedParentTypes) { - java.util.Set<String> sortedEntityNames = new java.util.TreeSet<>(counters.get(parentType).keySet()); - for (String entityName : sortedEntityNames) { - {{evaluationCounterInnerClass}} count = getCounter(parentType, entityName); - java.util.StringJoiner sj = new java.util.StringJoiner(",", "", "\n"); - sj.add(parentType) - .add(entityName) - .add(Integer.toString(count.receive)) - .add(Integer.toString(count.send)) - .add(Integer.toString(count.call)) - .add(Integer.toString(count.firstNull)) - .add(Integer.toString(count.skip)) - .add(Integer.toString(count.exception)) - .add(Integer.toString(count.reject)) - ; - sb.append(sj); - } - } - return sb.toString(); - } - - private {{evaluationCounterInnerClass}} getCounter(String parentTypeName, String entityName) { - return counters.computeIfAbsent(parentTypeName, parentAbsent).computeIfAbsent(entityName, entityAbsent); - } - } - - class {{evaluationCounterInnerClass}} { - int receive = 0; - int send = 0; - int call = 0; - int firstNull = 0; - int skip = 0; - int exception = 0; - int reject = 0; - } -{{/configEvaluationCounter}} -} +{{> EvaluationCounter}} -- GitLab