diff --git a/Util/src/main/java/io/deephaven/util/NoExecutionContextRegisteredException.java b/Util/src/main/java/io/deephaven/util/NoExecutionContextRegisteredException.java
index 1045ccf3408..347305a0693 100644
--- a/Util/src/main/java/io/deephaven/util/NoExecutionContextRegisteredException.java
+++ b/Util/src/main/java/io/deephaven/util/NoExecutionContextRegisteredException.java
@@ -3,8 +3,8 @@
import io.deephaven.UncheckedDeephavenException;
/**
- * This exception is thrown when the thread-local QueryScope, QueryLibrary, or CompilerTools.Context are accessed from
- * user-code without an explicit ExecutionContext.
+ * This exception is thrown when the thread-local QueryScope, QueryLibrary, or QueryCompiler are accessed from user-code
+ * without an explicit ExecutionContext.
*/
public final class NoExecutionContextRegisteredException extends UncheckedDeephavenException {
public NoExecutionContextRegisteredException() {
diff --git a/engine/api/src/main/java/io/deephaven/engine/table/PartitionedTable.java b/engine/api/src/main/java/io/deephaven/engine/table/PartitionedTable.java
index 448e7ff6188..2d1f2838d33 100644
--- a/engine/api/src/main/java/io/deephaven/engine/table/PartitionedTable.java
+++ b/engine/api/src/main/java/io/deephaven/engine/table/PartitionedTable.java
@@ -203,7 +203,7 @@ default Proxy proxy() {
*
* @apiNote {@code transformer} must be stateless, safe for concurrent use, and able to return a valid result for an
* empty input table. It is required to install an ExecutionContext to access any
- * QueryLibrary/QueryScope/CompilerContext functionality from the {@code transformer}.
+ * QueryLibrary/QueryScope/QueryCompiler functionality from the {@code transformer}.
*
* @param transformer The {@link UnaryOperator} to apply to all constituent {@link Table tables}
* @return The new PartitionedTable containing the resulting constituents
@@ -245,7 +245,7 @@ default PartitionedTable transform(@NotNull UnaryOperator
transformer) {
*
* @apiNote {@code transformer} must be stateless, safe for concurrent use, and able to return a valid result for
* empty input tables. It is required to install an ExecutionContext to access any
- * QueryLibrary/QueryScope/CompilerContext functionality from the {@code transformer}.
+ * QueryLibrary/QueryScope/QueryCompiler functionality from the {@code transformer}.
*
* @param other The other PartitionedTable to find constituents in
* @param transformer The {@link BinaryOperator} to apply to all pairs of constituent {@link Table tables}
@@ -275,7 +275,7 @@ default PartitionedTable partitionedTransform(
*
*
* {@code transformer} must be stateless, safe for concurrent use, and able to return a valid result for empty input
- * tables. It is required to install an ExecutionContext to access any QueryLibrary/QueryScope/CompilerContext
+ * tables. It is required to install an ExecutionContext to access any QueryLibrary/QueryScope/QueryCompiler
* functionality from the {@code transformer}.
*
* @param other The other PartitionedTable to find constituents in
diff --git a/engine/context/build.gradle b/engine/context/build.gradle
index d6716f5eec2..11e6288abe8 100644
--- a/engine/context/build.gradle
+++ b/engine/context/build.gradle
@@ -3,7 +3,7 @@ plugins {
id 'io.deephaven.project.register'
}
-description 'Engine Context: QueryScope, QueryLibrary and CompilerTools via ExecutionContext'
+description 'Engine Context: QueryScope, QueryLibrary and QueryCompiler via ExecutionContext'
configurations {
testCompile.extendsFrom junit
diff --git a/engine/context/src/main/java/io/deephaven/engine/context/ExecutionContext.java b/engine/context/src/main/java/io/deephaven/engine/context/ExecutionContext.java
index 21157401555..3b7a8e2b2f6 100644
--- a/engine/context/src/main/java/io/deephaven/engine/context/ExecutionContext.java
+++ b/engine/context/src/main/java/io/deephaven/engine/context/ExecutionContext.java
@@ -26,7 +26,7 @@ public static ExecutionContext makeSystemicExecutionContext() {
return ExecutionContext.newBuilder()
.captureQueryScope()
.captureQueryLibrary()
- .captureCompilerContext()
+ .captureQueryCompiler()
.markSystemic()
.build();
}
@@ -37,7 +37,7 @@ public static ExecutionContext createForUnitTests() {
.markSystemic()
.newQueryScope()
.newQueryLibrary()
- .setCompilerContext(CompilerTools.createContextForUnitTests())
+ .setQueryCompiler(QueryCompiler.createForUnitTests())
.build();
}
@@ -96,17 +96,17 @@ static void setContext(final ExecutionContext context) {
private final QueryLibrary queryLibrary;
private final QueryScope queryScope;
- private final CompilerTools.Context compilerContext;
+ private final QueryCompiler queryCompiler;
private ExecutionContext(
final boolean isSystemic,
final QueryLibrary queryLibrary,
final QueryScope queryScope,
- final CompilerTools.Context compilerContext) {
+ final QueryCompiler queryCompiler) {
this.isSystemic = isSystemic;
this.queryLibrary = queryLibrary;
this.queryScope = queryScope;
- this.compilerContext = compilerContext;
+ this.queryCompiler = queryCompiler;
}
/**
@@ -154,8 +154,8 @@ public QueryScope getQueryScope() {
return queryScope;
}
- public CompilerTools.Context getCompilerContext() {
- return compilerContext;
+ public QueryCompiler getQueryCompiler() {
+ return queryCompiler;
}
@SuppressWarnings("unused")
@@ -164,7 +164,7 @@ public static class Builder {
private QueryLibrary queryLibrary = PoisonedQueryLibrary.INSTANCE;
private QueryScope queryScope = PoisonedQueryScope.INSTANCE;
- private CompilerTools.Context compilerContext = PoisonedCompilerToolsContext.INSTANCE;
+ private QueryCompiler queryCompiler = PoisonedQueryCompiler.INSTANCE;
/**
* A systemic execution context is one that is supplied by the system and not the user. A systemic context will
@@ -213,20 +213,20 @@ public Builder captureQueryLibrary() {
}
/**
- * Use the provided CompilerTools.Context.
+ * Use the provided QueryCompiler
*/
@ScriptApi
- public Builder setCompilerContext(final CompilerTools.Context compilerContext) {
- this.compilerContext = compilerContext;
+ public Builder setQueryCompiler(final QueryCompiler queryCompiler) {
+ this.queryCompiler = queryCompiler;
return this;
}
/**
- * Use the current ExecutionContext's CompilerTools.Context instance.
+ * Use the current ExecutionContext's QueryCompiler instance.
*/
@ScriptApi
- public Builder captureCompilerContext() {
- compilerContext = currentContext.get().getCompilerContext();
+ public Builder captureQueryCompiler() {
+ queryCompiler = currentContext.get().getQueryCompiler();
return this;
}
@@ -297,7 +297,7 @@ public Builder captureQueryScopeVars(String... vars) {
*/
@ScriptApi
public ExecutionContext build() {
- return new ExecutionContext(isSystemic, queryLibrary, queryScope, compilerContext);
+ return new ExecutionContext(isSystemic, queryLibrary, queryScope, queryCompiler);
}
}
}
diff --git a/engine/context/src/main/java/io/deephaven/engine/context/PoisonedCompilerToolsContext.java b/engine/context/src/main/java/io/deephaven/engine/context/PoisonedQueryCompiler.java
similarity index 52%
rename from engine/context/src/main/java/io/deephaven/engine/context/PoisonedCompilerToolsContext.java
rename to engine/context/src/main/java/io/deephaven/engine/context/PoisonedQueryCompiler.java
index fb3c094bf63..e12653801b7 100644
--- a/engine/context/src/main/java/io/deephaven/engine/context/PoisonedCompilerToolsContext.java
+++ b/engine/context/src/main/java/io/deephaven/engine/context/PoisonedQueryCompiler.java
@@ -6,49 +6,36 @@
import io.deephaven.internal.log.LoggerFactory;
import io.deephaven.io.logger.Logger;
import io.deephaven.util.NoExecutionContextRegisteredException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-public class PoisonedCompilerToolsContext implements CompilerTools.Context {
- private static final Logger logger = LoggerFactory.getLogger(PoisonedCompilerToolsContext.class);
- public static final PoisonedCompilerToolsContext INSTANCE = new PoisonedCompilerToolsContext();
+public class PoisonedQueryCompiler extends QueryCompiler {
+ private static final Logger logger = LoggerFactory.getLogger(PoisonedQueryCompiler.class);
+ public static final PoisonedQueryCompiler INSTANCE = new PoisonedQueryCompiler();
- private PoisonedCompilerToolsContext() {}
+ private PoisonedQueryCompiler() {}
private T fail() {
- logger.error().append("No ExecutionContext provided; cannot use CompilerTools").endl();
+ logger.error().append("No ExecutionContext provided; cannot use QueryCompiler").endl();
throw new NoExecutionContextRegisteredException();
}
@Override
- public Map>> getKnownClasses() {
- return fail();
- }
-
- @Override
- public ClassLoader getClassLoaderForFormula(Map> parameterClasses) {
- return fail();
- }
-
- @Override
- public File getClassDestination() {
+ public File getFakeClassDestination() {
return fail();
}
@Override
- public String getClassPath() {
- return fail();
+ public void setParentClassLoader(ClassLoader parentClassLoader) {
+ fail();
}
@Override
- public File getFakeClassDestination() {
+ public Class> compile(@NotNull String className, @NotNull String classBody, @NotNull String packageNameRoot,
+ @Nullable StringBuilder codeLog, @NotNull Map> parameterClasses) {
return fail();
}
-
- @Override
- public void setParentClassLoader(ClassLoader parentClassLoader) {
- fail();
- }
}
diff --git a/engine/context/src/main/java/io/deephaven/engine/context/CompilerTools.java b/engine/context/src/main/java/io/deephaven/engine/context/QueryCompiler.java
similarity index 71%
rename from engine/context/src/main/java/io/deephaven/engine/context/CompilerTools.java
rename to engine/context/src/main/java/io/deephaven/engine/context/QueryCompiler.java
index 919dacc8588..afd8375dca1 100644
--- a/engine/context/src/main/java/io/deephaven/engine/context/CompilerTools.java
+++ b/engine/context/src/main/java/io/deephaven/engine/context/QueryCompiler.java
@@ -41,8 +41,8 @@
import static java.security.AccessController.doPrivileged;
-public class CompilerTools {
- private static final Logger log = LoggerFactory.getLogger(CompilerTools.class);
+public class QueryCompiler {
+ private static final Logger log = LoggerFactory.getLogger(QueryCompiler.class);
/**
* We pick a number just shy of 65536, leaving a little elbow room for good luck.
*/
@@ -53,15 +53,78 @@ public class CompilerTools {
private static final String IDENTIFYING_FIELD_NAME = "_CLASS_BODY_";
- private static final String CODEGEN_TIMEOUT_PROP = "CompilerTools.codegen.timeoutMs";
+ private static final String CODEGEN_TIMEOUT_PROP = "QueryCompiler.codegen.timeoutMs";
private static final long CODEGEN_TIMEOUT_MS_DEFAULT = TimeUnit.SECONDS.toMillis(10); // 10 seconds
- private static final String CODEGEN_LOOP_DELAY_PROP = "CompilerTools.codegen.retry.delay";
+ private static final String CODEGEN_LOOP_DELAY_PROP = "QueryCompiler.codegen.retry.delay";
private static final long CODEGEN_LOOP_DELAY_MS_DEFAULT = 100;
private static final long codegenTimeoutMs =
Configuration.getInstance().getLongWithDefault(CODEGEN_TIMEOUT_PROP, CODEGEN_TIMEOUT_MS_DEFAULT);
private static final long codegenLoopDelayMs =
Configuration.getInstance().getLongWithDefault(CODEGEN_LOOP_DELAY_PROP, CODEGEN_LOOP_DELAY_MS_DEFAULT);
+ private static boolean logEnabled = Configuration.getInstance().getBoolean("QueryCompiler.logEnabledDefault");
+
+ public static final String FORMULA_PREFIX = "io.deephaven.temp";
+ public static final String DYNAMIC_GROOVY_CLASS_PREFIX = "io.deephaven.dynamic";
+
+ public static QueryCompiler create(File cacheDirectory, ClassLoader classLoader) {
+ return new QueryCompiler(cacheDirectory, classLoader, true);
+ }
+
+ static QueryCompiler createForUnitTests() {
+ return new QueryCompiler(new File(Configuration.getInstance().getWorkspacePath() +
+ File.separator + "cache" + File.separator + "classes"));
+ }
+
+ private final Map>> knownClasses = new HashMap<>();
+
+ private final String[] dynamicPatterns = new String[] {DYNAMIC_GROOVY_CLASS_PREFIX, FORMULA_PREFIX};
+
+ private final File classDestination;
+ private final boolean isCacheDirectory;
+ private final Set additionalClassLocations;
+ private volatile WritableURLClassLoader ucl;
+
+ /** package-private constructor for {@link io.deephaven.engine.context.PoisonedQueryCompiler} */
+ QueryCompiler() {
+ classDestination = null;
+ isCacheDirectory = false;
+ additionalClassLocations = null;
+ }
+
+ private QueryCompiler(File classDestination) {
+ this(classDestination, null, false);
+ }
+
+ private QueryCompiler(
+ final File classDestination,
+ final ClassLoader parentClassLoader,
+ final boolean isCacheDirectory) {
+ final ClassLoader parentClassLoaderToUse = parentClassLoader == null
+ ? QueryCompiler.class.getClassLoader()
+ : parentClassLoader;
+ this.classDestination = classDestination;
+ this.isCacheDirectory = isCacheDirectory;
+ ensureDirectories(this.classDestination, () -> "Failed to create missing class destination directory " +
+ classDestination.getAbsolutePath());
+ additionalClassLocations = new LinkedHashSet<>();
+
+ URL[] urls = new URL[1];
+ try {
+ urls[0] = (classDestination.toURI().toURL());
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("", e);
+ }
+ // We should be able to create this class loader, even if this is invoked from external code
+ // that does not have sufficient security permissions.
+ this.ucl = doPrivileged((PrivilegedAction) () -> new WritableURLClassLoader(urls,
+ parentClassLoaderToUse));
+
+ if (isCacheDirectory) {
+ addClassSource(classDestination);
+ }
+ }
+
/**
* Enables or disables compilation logging.
*
@@ -69,8 +132,8 @@ public class CompilerTools {
* @return The value of {@code logEnabled} before calling this method.
*/
public static boolean setLogEnabled(boolean logEnabled) {
- boolean original = CompilerTools.logEnabled;
- CompilerTools.logEnabled = logEnabled;
+ boolean original = QueryCompiler.logEnabled;
+ QueryCompiler.logEnabled = logEnabled;
return original;
}
@@ -84,18 +147,6 @@ public static void writeClass(final File destinationDirectory, final String clas
writeClass(destinationDirectory, className, data, null);
}
- private static void ensureDirectories(final File file, final Supplier runtimeErrMsg) {
- // File.mkdirs() checks for existrance on entry, in which case it returns false.
- // It may also return false on a failure to create.
- // Also note, two separate threads or JVMs may be running this code in parallel. It's possible that we could
- // lose the race
- // (and therefore mkdirs() would return false), but still get the directory we need (and therefore exists()
- // would return true)
- if (!file.mkdirs() && !file.isDirectory()) {
- throw new RuntimeException(runtimeErrMsg.get());
- }
- }
-
/*
* NB: This is (obviously) not thread safe if code tries to write the same className to the same
* destinationDirectory from multiple threads. Seeing as we don't currently have this use case, leaving
@@ -144,327 +195,257 @@ public static void writeClass(final File destinationDirectory, final String clas
fileOutStream.close();
}
- public static final String FORMULA_PREFIX = "io.deephaven.temp";
- public static final String DYNAMIC_GROOVY_CLASS_PREFIX = "io.deephaven.dynamic";
-
- public interface Context {
- Map>> getKnownClasses();
-
- ClassLoader getClassLoaderForFormula(Map> parameterClasses);
-
- File getClassDestination();
-
- File getFakeClassDestination();
-
- String getClassPath();
+ public File getFakeClassDestination() {
+ // Groovy classes need to be written out to a location where they can be found by the compiler
+ // (so that filters and formulae can use them).
+ //
+ // We don't want the regular runtime class loader to find them, because then they get "stuck" in there
+ // even if the class itself changes, and we can't forget it. So instead we use a single-use class loader
+ // for each formula, that will always read the class from disk.
+ return isCacheDirectory ? classDestination : null;
+ }
- void setParentClassLoader(ClassLoader parentClassLoader);
+ public void setParentClassLoader(final ClassLoader parentClassLoader) {
+ // The system should always be able to create this class loader, even if invoked from something that
+ // doesn't have the right security permissions for it.
+ ucl = doPrivileged(
+ (PrivilegedAction) () -> new WritableURLClassLoader(ucl.getURLs(),
+ parentClassLoader));
}
- public static Context newContext(File cacheDirectory, ClassLoader classLoader) {
- return new CompilerTools.ContextImpl(cacheDirectory, classLoader, true);
+ public final Class> compile(String className, String classBody, String packageNameRoot) {
+ return compile(className, classBody, packageNameRoot, null, Collections.emptyMap());
}
- private static class ContextImpl implements Context {
- private final Map>> knownClasses = new HashMap<>();
+ public final Class> compile(String className, String classBody, String packageNameRoot,
+ Map> parameterClasses) {
+ return compile(className, classBody, packageNameRoot, null, parameterClasses);
+ }
- String[] dynamicPatterns = new String[] {DYNAMIC_GROOVY_CLASS_PREFIX, FORMULA_PREFIX};
+ public final Class> compile(String className, String classBody, String packageNameRoot, StringBuilder codeLog) {
+ return compile(className, classBody, packageNameRoot, codeLog, Collections.emptyMap());
+ }
- private final File classDestination;
- private final boolean isCacheDirectory;
- private final Set additionalClassLocations;
- private volatile WritableURLClassLoader ucl;
+ /**
+ * Compile a class.
+ *
+ * @param className Class name
+ * @param classBody Class body, before update with "$CLASS_NAME$" replacement and package name prefixing
+ * @param packageNameRoot Package name prefix
+ * @param codeLog Optional "log" for final class code
+ * @param parameterClasses Generic parameters, empty if none required
+ * @return The compiled class
+ */
+ public Class> compile(@NotNull final String className,
+ @NotNull final String classBody,
+ @NotNull final String packageNameRoot,
+ @Nullable final StringBuilder codeLog,
+ @NotNull final Map> parameterClasses) {
+ CompletableFuture> promise;
+ final boolean promiseAlreadyMade;
- private ContextImpl(File classDestination) {
- this(classDestination, Context.class.getClassLoader(), false);
+ synchronized (this) {
+ promise = knownClasses.get(classBody);
+ if (promise != null) {
+ promiseAlreadyMade = true;
+ } else {
+ promise = new CompletableFuture<>();
+ knownClasses.put(classBody, promise);
+ promiseAlreadyMade = false;
+ }
}
- private ContextImpl(File classDestination, ClassLoader parentClassLoader, boolean isCacheDirectory) {
- this.classDestination = classDestination;
- this.isCacheDirectory = isCacheDirectory;
- ensureDirectories(this.classDestination, () -> "Failed to create missing class destination directory " +
- classDestination.getAbsolutePath());
- additionalClassLocations = new LinkedHashSet<>();
-
- URL[] urls = new URL[1];
+ // Someone else has already made the promise. I'll just wait for the answer.
+ if (promiseAlreadyMade) {
try {
- urls[0] = (classDestination.toURI().toURL());
- } catch (MalformedURLException e) {
- throw new RuntimeException("", e);
- }
- // We should be able to create this class loader, even if this is invoked from external code
- // that does not have sufficient security permissions.
- this.ucl = doPrivileged((PrivilegedAction) () -> new WritableURLClassLoader(urls,
- parentClassLoader));
-
- if (isCacheDirectory) {
- addClassSource(classDestination);
+ return promise.get();
+ } catch (InterruptedException | ExecutionException error) {
+ throw new UncheckedDeephavenException(error);
}
}
- @Override
- public Map>> getKnownClasses() {
- return knownClasses;
+ // It's my job to fulfill the promise
+ try {
+ return compileHelper(className, classBody, packageNameRoot, codeLog, parameterClasses);
+ } catch (RuntimeException e) {
+ promise.completeExceptionally(e);
+ throw e;
}
+ }
- @Override
- public ClassLoader getClassLoaderForFormula(final Map> parameterClasses) {
- // We should always be able to get our own class loader, even if this is invoked from external code
- // that doesn't have security permissions to make ITS own class loader.
- return doPrivileged((PrivilegedAction) () -> new URLClassLoader(ucl.getURLs(), ucl) {
- // Once we find a class that is missing, we should not attempt to load it again,
- // otherwise we can end up with a StackOverflow Exception
- final HashSet missingClasses = new HashSet<>();
-
- @Override
- protected Class> findClass(String name) throws ClassNotFoundException {
- // If we have a parameter that uses this class, return it
- final Class> paramClass = parameterClasses.get(name);
- if (paramClass != null) {
- return paramClass;
- }
-
- // Unless we are looking for a formula or Groovy class, we should use the default behavior
- if (!isFormulaClass(name)) {
- return super.findClass(name);
- }
-
- // if it is a groovy class, always try to use the instance in the shell
- if (name.startsWith(DYNAMIC_GROOVY_CLASS_PREFIX)) {
- try {
- return ucl.getParent().loadClass(name);
- } catch (final ClassNotFoundException ignored) {
- // we'll try to load it otherwise
- }
- }
+ private static void ensureDirectories(final File file, final Supplier runtimeErrMsg) {
+ // File.mkdirs() checks for existence on entry, in which case it returns false.
+ // It may also return false on a failure to create.
+ // Also note, two separate threads or JVMs may be running this code in parallel. It's possible that we could
+ // lose the race
+ // (and therefore mkdirs() would return false), but still get the directory we need (and therefore exists()
+ // would return true)
+ if (!file.mkdirs() && !file.isDirectory()) {
+ throw new RuntimeException(runtimeErrMsg.get());
+ }
+ }
- // We've already not found this class, so we should not try to search again
- if (missingClasses.contains(name)) {
- return super.findClass(name);
- }
+ private ClassLoader getClassLoaderForFormula(final Map> parameterClasses) {
+ // We should always be able to get our own class loader, even if this is invoked from external code
+ // that doesn't have security permissions to make ITS own class loader.
+ return doPrivileged((PrivilegedAction) () -> new URLClassLoader(ucl.getURLs(), ucl) {
+ // Once we find a class that is missing, we should not attempt to load it again,
+ // otherwise we can end up with a StackOverflow Exception
+ final HashSet missingClasses = new HashSet<>();
- final byte[] bytes;
- try {
- bytes = loadClassData(name);
- } catch (IOException ioe) {
- missingClasses.add(name);
- return super.loadClass(name);
- }
- return defineClass(name, bytes, 0, bytes.length);
+ @Override
+ protected Class> findClass(String name) throws ClassNotFoundException {
+ // If we have a parameter that uses this class, return it
+ final Class> paramClass = parameterClasses.get(name);
+ if (paramClass != null) {
+ return paramClass;
}
- @SuppressWarnings("BooleanMethodIsAlwaysInverted")
- private boolean isFormulaClass(String name) {
- return Arrays.stream(dynamicPatterns).anyMatch(name::startsWith);
+ // Unless we are looking for a formula or Groovy class, we should use the default behavior
+ if (!isFormulaClass(name)) {
+ return super.findClass(name);
}
- @Override
- public Class> loadClass(String name) throws ClassNotFoundException {
- if (!isFormulaClass(name)) {
- return super.loadClass(name);
+ // if it is a groovy class, always try to use the instance in the shell
+ if (name.startsWith(DYNAMIC_GROOVY_CLASS_PREFIX)) {
+ try {
+ return ucl.getParent().loadClass(name);
+ } catch (final ClassNotFoundException ignored) {
+ // we'll try to load it otherwise
}
- return findClass(name);
}
- private byte[] loadClassData(String name) throws IOException {
- try {
- // The compiler should always have access to the class-loader directories,
- // even if code that invokes this does not.
- return doPrivileged((PrivilegedExceptionAction) () -> {
- final File destFile = new File(classDestination,
- name.replace('.', File.separatorChar) + JavaFileObject.Kind.CLASS.extension);
- if (destFile.exists()) {
- return Files.readAllBytes(destFile.toPath());
- }
-
- for (File location : additionalClassLocations) {
- final File checkFile = new File(location,
- name.replace('.', File.separatorChar) + JavaFileObject.Kind.CLASS.extension);
- if (checkFile.exists()) {
- return Files.readAllBytes(checkFile.toPath());
- }
- }
+ // We've already not found this class, so we should not try to search again
+ if (missingClasses.contains(name)) {
+ return super.findClass(name);
+ }
- throw new FileNotFoundException(name);
- });
- } catch (final PrivilegedActionException pae) {
- final Exception inner = pae.getException();
- if (inner instanceof IOException) {
- throw (IOException) inner;
- } else {
- throw new RuntimeException(inner);
- }
- }
+ final byte[] bytes;
+ try {
+ bytes = loadClassData(name);
+ } catch (IOException ioe) {
+ missingClasses.add(name);
+ return super.loadClass(name);
}
- });
- }
+ return defineClass(name, bytes, 0, bytes.length);
+ }
- private static class WritableURLClassLoader extends URLClassLoader {
- private WritableURLClassLoader(URL[] urls, ClassLoader parent) {
- super(urls, parent);
+ @SuppressWarnings("BooleanMethodIsAlwaysInverted")
+ private boolean isFormulaClass(String name) {
+ return Arrays.stream(dynamicPatterns).anyMatch(name::startsWith);
}
@Override
- protected synchronized Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {
- Class> clazz = findLoadedClass(name);
- if (clazz != null) {
- return clazz;
+ public Class> loadClass(String name) throws ClassNotFoundException {
+ if (!isFormulaClass(name)) {
+ return super.loadClass(name);
}
+ return findClass(name);
+ }
+ private byte[] loadClassData(String name) throws IOException {
try {
- clazz = findClass(name);
- } catch (ClassNotFoundException e) {
- clazz = getParent().loadClass(name);
- }
+ // The compiler should always have access to the class-loader directories,
+ // even if code that invokes this does not.
+ return doPrivileged((PrivilegedExceptionAction) () -> {
+ final File destFile = new File(classDestination,
+ name.replace('.', File.separatorChar) + JavaFileObject.Kind.CLASS.extension);
+ if (destFile.exists()) {
+ return Files.readAllBytes(destFile.toPath());
+ }
- if (resolve) {
- resolveClass(clazz);
+ for (File location : additionalClassLocations) {
+ final File checkFile = new File(location,
+ name.replace('.', File.separatorChar) + JavaFileObject.Kind.CLASS.extension);
+ if (checkFile.exists()) {
+ return Files.readAllBytes(checkFile.toPath());
+ }
+ }
+
+ throw new FileNotFoundException(name);
+ });
+ } catch (final PrivilegedActionException pae) {
+ final Exception inner = pae.getException();
+ if (inner instanceof IOException) {
+ throw (IOException) inner;
+ } else {
+ throw new RuntimeException(inner);
+ }
}
- return clazz;
}
+ });
+ }
- @Override
- public synchronized void addURL(URL url) {
- super.addURL(url);
- }
+ private static class WritableURLClassLoader extends URLClassLoader {
+ private WritableURLClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent);
}
- protected void addClassSource(File classSourceDirectory) {
- synchronized (additionalClassLocations) {
- if (additionalClassLocations.contains(classSourceDirectory)) {
- return;
- }
- additionalClassLocations.add(classSourceDirectory);
+ @Override
+ protected synchronized Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ Class> clazz = findLoadedClass(name);
+ if (clazz != null) {
+ return clazz;
}
+
try {
- ucl.addURL(classSourceDirectory.toURI().toURL());
- } catch (MalformedURLException e) {
- throw new RuntimeException("", e);
+ clazz = findClass(name);
+ } catch (ClassNotFoundException e) {
+ if (getParent() != null) {
+ clazz = getParent().loadClass(name);
+ }
}
- }
- public File getFakeClassDestination() {
- // Groovy classes need to be written out to a location where they can be found by the compiler
- // (so that filters and formulae can use them).
- //
- // We don't want the regular runtime class loader to find them, because then they get "stuck" in there
- // even if the class itself changes, and we can't forget it. So instead we use a single-use class loader
- // for each formula, that will always read the class from disk.
- return isCacheDirectory ? classDestination : null;
+ if (resolve) {
+ resolveClass(clazz);
+ }
+ return clazz;
}
@Override
- public File getClassDestination() {
- return classDestination;
+ public synchronized void addURL(URL url) {
+ super.addURL(url);
}
+ }
- public String getClassPath() {
- StringBuilder sb = new StringBuilder();
- sb.append(classDestination.getAbsolutePath());
- synchronized (additionalClassLocations) {
- for (File classLoc : additionalClassLocations) {
- sb.append(File.pathSeparatorChar).append(classLoc.getAbsolutePath());
- }
+ private void addClassSource(File classSourceDirectory) {
+ synchronized (additionalClassLocations) {
+ if (additionalClassLocations.contains(classSourceDirectory)) {
+ return;
}
- return sb.toString();
- }
-
- public WritableURLClassLoader getClassLoader() {
- return ucl;
- }
-
- public void setParentClassLoader(final ClassLoader parentClassLoader) {
- // The system should always be able to create this class loader, even if invoked from something that
- // doesn't have the right security permissions for it.
- ucl = doPrivileged(
- (PrivilegedAction) () -> new WritableURLClassLoader(ucl.getURLs(),
- parentClassLoader));
+ additionalClassLocations.add(classSourceDirectory);
}
-
- public void cleanup() {
- FileUtils.deleteRecursively(classDestination);
+ try {
+ ucl.addURL(classSourceDirectory.toURI().toURL());
+ } catch (MalformedURLException e) {
+ throw new RuntimeException("", e);
}
}
- static Context createContextForUnitTests() {
- return new ContextImpl(new File(Configuration.getInstance().getWorkspacePath() +
- File.separator + "cache" + File.separator + "classes"));
- }
-
- public static Context getContext() {
- return ExecutionContext.getContext().getCompilerContext();
- }
-
- private static boolean logEnabled = Configuration.getInstance().getBoolean("CompilerTools.logEnabledDefault");
-
- public static Class> compile(String className, String classBody, String packageNameRoot) {
- return compile(className, classBody, packageNameRoot, null, Collections.emptyMap());
- }
-
- public static Class> compile(String className, String classBody, String packageNameRoot,
- Map> parameterClasses) {
- return compile(className, classBody, packageNameRoot, null, parameterClasses);
+ private File getClassDestination() {
+ return classDestination;
}
- public static Class> compile(String className, String classBody, String packageNameRoot, StringBuilder codeLog) {
- return compile(className, classBody, packageNameRoot, codeLog, Collections.emptyMap());
- }
-
- /**
- * Compile a class.
- *
- * @param className Class name
- * @param classBody Class body, before update with "$CLASS_NAME$" replacement and package name prefixing
- * @param packageNameRoot Package name prefix
- * @param codeLog Optional "log" for final class code
- * @param parameterClasses Generic parameters, empty if none required
- * @return The compiled class
- */
- public static Class> compile(@NotNull final String className,
- @NotNull final String classBody,
- @NotNull final String packageNameRoot,
- @Nullable final StringBuilder codeLog,
- @NotNull final Map> parameterClasses) {
- CompletableFuture> promise;
- final boolean promiseAlreadyMade;
-
- final Context context = getContext();
-
- synchronized (context) {
- promise = context.getKnownClasses().get(classBody);
- if (promise != null) {
- promiseAlreadyMade = true;
- } else {
- promise = new CompletableFuture<>();
- context.getKnownClasses().put(classBody, promise);
- promiseAlreadyMade = false;
- }
- }
-
- // Someone else has already made the promise. I'll just wait for the answer.
- if (promiseAlreadyMade) {
- try {
- return promise.get();
- } catch (InterruptedException | ExecutionException error) {
- throw new UncheckedDeephavenException(error);
+ private String getClassPath() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(classDestination.getAbsolutePath());
+ synchronized (additionalClassLocations) {
+ for (File classLoc : additionalClassLocations) {
+ sb.append(File.pathSeparatorChar).append(classLoc.getAbsolutePath());
}
}
+ return sb.toString();
+ }
- // It's my job to fulfill the promise
- try {
- return compileHelper(className, classBody, packageNameRoot, codeLog, parameterClasses, context);
- } catch (RuntimeException e) {
- promise.completeExceptionally(e);
- throw e;
- }
+ private WritableURLClassLoader getClassLoader() {
+ return ucl;
}
- private static Class> compileHelper(@NotNull final String className,
+ private Class> compileHelper(@NotNull final String className,
@NotNull final String classBody,
@NotNull final String packageNameRoot,
@Nullable final StringBuilder codeLog,
- @NotNull final Map> parameterClasses,
- @NotNull final Context context) {
+ @NotNull final Map> parameterClasses) {
// NB: We include class name hash in order to (hopefully) account for case insensitive file systems.
final int classNameHash = className.hashCode();
final int classBodyHash = classBody.hashCode();
@@ -518,13 +499,13 @@ private static Class> compileHelper(@NotNull final String className,
// We have a class. It either contains the formula we are looking for (cases 2, A, and B) or a different
// formula with the same name (cases 3 and C). In either case, we should store the result in our cache,
// either fulfilling an existing promise or making a new, fulfilled promise.
- synchronized (context) {
+ synchronized (this) {
// Note we are doing something kind of subtle here. We are removing an entry whose key was matched by
// value equality and replacing it with a value-equal but reference-different string that is a static
// member of the class we just loaded. This should be easier on the garbage collector because we are
// replacing a calculated value with a classloaded value and so in effect we are "canonicalizing" the
// string. This is important because these long strings stay in knownClasses forever.
- CompletableFuture> p = context.getKnownClasses().remove(identifyingFieldValue);
+ CompletableFuture> p = knownClasses.remove(identifyingFieldValue);
if (p == null) {
// If we encountered a different class than the one we're looking for, make a fresh promise and
// immediately fulfill it. This is for the purpose of populating the cache in case someone comes
@@ -532,7 +513,7 @@ private static Class> compileHelper(@NotNull final String className,
// throwing it away now, even though this is not the class we're looking for.
p = new CompletableFuture<>();
}
- context.getKnownClasses().put(identifyingFieldValue, p);
+ knownClasses.put(identifyingFieldValue, p);
// It's also possible that some other code has already fulfilled this promise with exactly the same
// class. That's ok though: the promise code does not reject multiple sets to the identical value.
p.complete(result);
@@ -554,9 +535,9 @@ private static Class> compileHelper(@NotNull final String className,
+ ", class body hash=" + classBodyHash + " - contact Deephaven support!");
}
- private static Class> tryLoadClassByFqName(String fqClassName, Map> parameterClasses) {
+ private Class> tryLoadClassByFqName(String fqClassName, Map> parameterClasses) {
try {
- return getContext().getClassLoaderForFormula(parameterClasses).loadClass(fqClassName);
+ return getClassLoaderForFormula(parameterClasses).loadClass(fqClassName);
} catch (ClassNotFoundException cnfe) {
return null;
}
@@ -641,7 +622,7 @@ private static int calcBytesConsumed(final char ch) {
return 3;
}
- static class JavaSourceFromString extends SimpleJavaFileObject {
+ private static class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
@@ -654,11 +635,11 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
}
}
- static class JavaSourceFromFile extends SimpleJavaFileObject {
+ private static class JavaSourceFromFile extends SimpleJavaFileObject {
private static final int JAVA_LENGTH = Kind.SOURCE.extension.length();
final String code;
- JavaSourceFromFile(File basePath, File file) {
+ private JavaSourceFromFile(File basePath, File file) {
super(URI.create("string:///" + createName(basePath, file).replace('.', '/') + Kind.SOURCE.extension),
Kind.SOURCE);
try {
@@ -682,12 +663,13 @@ private static String createName(File basePath, File file) {
}
}
+ @Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
- private static void maybeCreateClass(String className, String code, String packageName, String fqClassName) {
+ private void maybeCreateClass(String className, String code, String packageName, String fqClassName) {
final String finalCode = makeFinalCode(className, code, packageName);
// The 'compile' action does a bunch of things that need security permissions; this always needs to run
@@ -696,8 +678,7 @@ private static void maybeCreateClass(String className, String code, String packa
log.info().append("Generating code ").append(finalCode).endl();
}
- final Context ctx = getContext();
- final File ctxClassDestination = ctx.getClassDestination();
+ final File ctxClassDestination = getClassDestination();
final String[] splitPackageName = packageName.split("\\.");
if (splitPackageName.length == 0) {
@@ -735,7 +716,7 @@ private static void maybeCreateClass(String className, String code, String packa
}
try {
- maybeCreateClassHelper(fqClassName, finalCode, splitPackageName, ctx, rootPathAsString, tempDirAsString);
+ maybeCreateClassHelper(fqClassName, finalCode, splitPackageName, rootPathAsString, tempDirAsString);
} finally {
AccessController.doPrivileged((PrivilegedAction) () -> {
try {
@@ -748,8 +729,8 @@ private static void maybeCreateClass(String className, String code, String packa
}
}
- private static void maybeCreateClassHelper(String fqClassName, String finalCode, String[] splitPackageName,
- Context ctx, String rootPathAsString, String tempDirAsString) {
+ private void maybeCreateClassHelper(String fqClassName, String finalCode, String[] splitPackageName,
+ String rootPathAsString, String tempDirAsString) {
final StringWriter compilerOutput = new StringWriter();
final JavaCompiler compiler =
@@ -758,7 +739,7 @@ private static void maybeCreateClassHelper(String fqClassName, String finalCode,
throw new RuntimeException("No Java compiler provided - are you using a JRE instead of a JDK?");
}
- final String classPathAsString = ctx.getClassPath() + File.pathSeparator + getJavaClassPath();
+ final String classPathAsString = getClassPath() + File.pathSeparator + getJavaClassPath();
final List compilerOptions = AccessController.doPrivileged(
(PrivilegedAction>) () -> Arrays.asList("-d", tempDirAsString, "-cp", classPathAsString));
@@ -772,14 +753,13 @@ private static void maybeCreateClassHelper(String fqClassName, String finalCode,
Collections.singletonList(new JavaSourceFromString(fqClassName, finalCode)))
.call();
if (!result) {
- throw new RuntimeException("Error compiling class " + fqClassName + ":\n" + compilerOutput.toString());
+ throw new RuntimeException("Error compiling class " + fqClassName + ":\n" + compilerOutput);
}
// The above has compiled into into e.g.
// /tmp/workspace/cache/classes/temporaryCompilationDirectory12345/io/deephaven/test/cm12862183232603186v52_0/{various
// class files}
// We want to atomically move it to e.g.
// /tmp/workspace/cache/classes/io/deephaven/test/cm12862183232603186v52_0/{various class files}
- // Our strategy
try {
AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
Path srcDir = Paths.get(tempDirAsString, splitPackageName);
@@ -809,7 +789,7 @@ private static void maybeCreateClassHelper(String fqClassName, String finalCode,
* @param javaFiles the java source files
* @return a Pair of success, and the compiler output
*/
- public static Pair tryCompile(File basePath, Collection javaFiles) throws IOException {
+ private Pair tryCompile(File basePath, Collection javaFiles) throws IOException {
try {
// We need multiple filesystem accesses et al, so make this whole section privileged.
return AccessController.doPrivileged((PrivilegedExceptionAction>) () -> {
@@ -823,7 +803,6 @@ public static Pair tryCompile(File basePath, Collection j
try {
final StringWriter compilerOutput = new StringWriter();
- final Context ctx = getContext();
final String javaClasspath = getJavaClassPath();
final Collection javaFileObjects = javaFiles.stream()
@@ -831,7 +810,7 @@ public static Pair tryCompile(File basePath, Collection j
final boolean result = compiler.getTask(compilerOutput, null, null,
Arrays.asList("-d", outputDirectory.getAbsolutePath(), "-cp",
- ctx.getClassPath() + File.pathSeparator + javaClasspath),
+ getClassPath() + File.pathSeparator + javaClasspath),
null, javaFileObjects).call();
return new Pair<>(result, compilerOutput.toString());
@@ -854,7 +833,7 @@ public static Pair tryCompile(File basePath, Collection j
*
* @return
*/
- public static String getJavaClassPath() {
+ private static String getJavaClassPath() {
String javaClasspath;
{
final StringBuilder javaClasspathBuilder = new StringBuilder(System.getProperty("java.class.path"));
@@ -862,18 +841,18 @@ public static String getJavaClassPath() {
final String teamCityWorkDir = System.getProperty("teamcity.build.workingDir");
if (teamCityWorkDir != null) {
// We are running in TeamCity, get the classpath differently
- final File classDirs[] = new File(teamCityWorkDir + "/_out_/classes").listFiles();
+ final File[] classDirs = new File(teamCityWorkDir + "/_out_/classes").listFiles();
for (File f : classDirs) {
javaClasspathBuilder.append(File.pathSeparator).append(f.getAbsolutePath());
}
- final File testDirs[] = new File(teamCityWorkDir + "/_out_/test-classes").listFiles();
+ final File[] testDirs = new File(teamCityWorkDir + "/_out_/test-classes").listFiles();
for (File f : testDirs) {
javaClasspathBuilder.append(File.pathSeparator).append(f.getAbsolutePath());
}
- final File jars[] = FileUtils.findAllFiles(new File(teamCityWorkDir + "/lib"));
+ final File[] jars = FileUtils.findAllFiles(new File(teamCityWorkDir + "/lib"));
for (File f : jars) {
if (f.getName().endsWith(".jar")) {
javaClasspathBuilder.append(File.pathSeparator).append(f.getAbsolutePath());
@@ -890,7 +869,7 @@ public static String getJavaClassPath() {
if (javaClasspath.matches(intellijClassPathJarRegex)) {
try {
final Enumeration resources =
- CompilerTools.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
+ QueryCompiler.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
final Attributes.Name createdByAttribute = new Attributes.Name("Created-By");
final Attributes.Name classPathAttribute = new Attributes.Name("Class-Path");
while (resources.hasMoreElements()) {
diff --git a/engine/context/src/test/java/io/deephaven/engine/context/TestCompilerTools.java b/engine/context/src/test/java/io/deephaven/engine/context/TestQueryCompiler.java
similarity index 93%
rename from engine/context/src/test/java/io/deephaven/engine/context/TestCompilerTools.java
rename to engine/context/src/test/java/io/deephaven/engine/context/TestQueryCompiler.java
index f43ac9b6d08..6d22a650162 100644
--- a/engine/context/src/test/java/io/deephaven/engine/context/TestCompilerTools.java
+++ b/engine/context/src/test/java/io/deephaven/engine/context/TestQueryCompiler.java
@@ -17,7 +17,7 @@
import java.util.Collections;
import java.util.List;
-public class TestCompilerTools {
+public class TestQueryCompiler {
private final static int NUM_THREADS = 500;
private final static int NUM_METHODS = 5000;
private final static long WAIT_BETWEEN_THREAD_START_MILLIS = 5;
@@ -158,7 +158,8 @@ private void compile(boolean printDetails, final String className) throws Except
} else {
startMillis = 0;
}
- CompilerTools.compile(className, CLASS_CODE, "io.deephaven.temp");
+ ExecutionContext.getContext().getQueryCompiler()
+ .compile(className, CLASS_CODE, "io.deephaven.temp");
if (printDetails) {
final long endMillis = System.currentTimeMillis();
System.out.println(printMillis(endMillis) + ": Thread 0 ending compile: (" + (endMillis - startMillis)
@@ -185,8 +186,8 @@ public void testSimpleCompile() throws Exception {
"}");
StringBuilder codeLog = new StringBuilder();
- final Class> clazz1 =
- CompilerTools.compile("Test", program1Text, "com.deephaven.test", codeLog, Collections.emptyMap());
+ final Class> clazz1 = ExecutionContext.getContext().getQueryCompiler()
+ .compile("Test", program1Text, "com.deephaven.test", codeLog, Collections.emptyMap());
final Method m1 = clazz1.getMethod("main", String[].class);
Object[] args1 = new Object[] {new String[] {"hello", "there"}};
m1.invoke(null, args1);
@@ -208,8 +209,9 @@ public void testCollidingCompile() throws Exception {
Thread t = new Thread(() -> {
StringBuilder codeLog = new StringBuilder();
try {
- final Class> clazz1 = CompilerTools.compile("Test", program1Text, "com.deephaven.test", codeLog,
- Collections.emptyMap());
+ final Class> clazz1 = ExecutionContext.getContext().getQueryCompiler()
+ .compile("Test", program1Text, "com.deephaven.test", codeLog,
+ Collections.emptyMap());
final Method m1 = clazz1.getMethod("main", String[].class);
Object[] args1 = new Object[] {new String[] {"hello", "there"}};
m1.invoke(null, args1);
diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/typed/TypedHasherFactory.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/by/typed/TypedHasherFactory.java
index 1025d408ab5..ecc83cc6a16 100644
--- a/engine/table/src/main/java/io/deephaven/engine/table/impl/by/typed/TypedHasherFactory.java
+++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/by/typed/TypedHasherFactory.java
@@ -10,7 +10,8 @@
import io.deephaven.chunk.*;
import io.deephaven.chunk.attributes.Values;
import io.deephaven.chunk.util.hashing.CharChunkHasher;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.ExecutionContext;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.configuration.Configuration;
import io.deephaven.engine.rowset.*;
import io.deephaven.engine.rowset.chunkattributes.OrderedRowKeys;
@@ -33,11 +34,11 @@
import io.deephaven.util.compare.CharComparisons;
import org.apache.commons.lang3.mutable.MutableInt;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.lang.model.element.Modifier;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.security.spec.ECField;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -476,7 +477,7 @@ public static T make(HasherConfig hasherConfig, ColumnSource>[] tableKe
final String javaString =
Arrays.stream(javaStrings).filter(s -> !s.startsWith("package ")).collect(Collectors.joining("\n"));
- final Class> clazz = CompilerTools.compile(className, javaString,
+ final Class> clazz = ExecutionContext.getContext().getQueryCompiler().compile(className, javaString,
"io.deephaven.engine.table.impl.by.typed." + hasherConfig.packageMiddle + ".gen");
if (!hasherConfig.baseClass.isAssignableFrom(clazz)) {
throw new IllegalStateException("Generated class is not a " + hasherConfig.baseClass.getCanonicalName());
diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/partitioned/PartitionedTableProxyImpl.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/partitioned/PartitionedTableProxyImpl.java
index 7738d7ec678..4960878ec81 100644
--- a/engine/table/src/main/java/io/deephaven/engine/table/impl/partitioned/PartitionedTableProxyImpl.java
+++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/partitioned/PartitionedTableProxyImpl.java
@@ -132,7 +132,7 @@ private static ExecutionContext getOrCreateExecutionContext(final boolean requir
ExecutionContext context = ExecutionContext.getContextToRecord();
if (context == null) {
final ExecutionContext.Builder builder = ExecutionContext.newBuilder()
- .captureCompilerContext()
+ .captureQueryCompiler()
.markSystemic();
if (requiresFullContext) {
builder.newQueryLibrary();
diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/ConditionFilter.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/ConditionFilter.java
index fbeb6ed341f..0bb90ca9505 100644
--- a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/ConditionFilter.java
+++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/ConditionFilter.java
@@ -5,7 +5,7 @@
import io.deephaven.base.Pair;
import io.deephaven.chunk.attributes.Any;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.engine.context.ExecutionContext;
import io.deephaven.engine.rowset.RowSetFactory;
import io.deephaven.engine.table.Context;
@@ -390,8 +390,9 @@ protected void generateFilterCode(TableDefinition tableDefinition, DateTimeUtils
addParamClass.accept(QueryScopeParamTypeUtil.getDeclaredClass(param.getValue()));
}
- filterKernelClass = CompilerTools.compile("GeneratedFilterKernel", this.classBody = classBody.toString(),
- CompilerTools.FORMULA_PREFIX, QueryScopeParamTypeUtil.expandParameterClasses(paramClasses));
+ filterKernelClass = ExecutionContext.getContext().getQueryCompiler()
+ .compile("GeneratedFilterKernel", this.classBody = classBody.toString(),
+ QueryCompiler.FORMULA_PREFIX, QueryScopeParamTypeUtil.expandParameterClasses(paramClasses));
} finally {
nugget.done();
}
diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/DhFormulaColumn.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/DhFormulaColumn.java
index dd1fe98b2d9..da4de5afd46 100644
--- a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/DhFormulaColumn.java
+++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/DhFormulaColumn.java
@@ -4,7 +4,7 @@
package io.deephaven.engine.table.impl.select;
import io.deephaven.configuration.Configuration;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.engine.context.ExecutionContext;
import io.deephaven.engine.table.ColumnDefinition;
import io.deephaven.engine.table.Table;
@@ -344,7 +344,7 @@ private CodeGenerator generateApplyFormulaPerItem(final TypeAnalyzer ta) {
g.replace("ARGS", makeCommaSeparatedList(args));
g.replace("FORMULA_STRING", ta.wrapWithCastIfNecessary(formulaString));
g.replace("COLUMN_NAME", StringEscapeUtils.escapeJava(columnName));
- final String joinedFormulaString = CompilerTools.createEscapedJoinedString(formulaString);
+ final String joinedFormulaString = QueryCompiler.createEscapedJoinedString(formulaString);
g.replace("JOINED_FORMULA_STRING", joinedFormulaString);
g.replace("EXCEPTION_TYPE", EVALUATION_EXCEPTION_CLASSNAME);
return g.freeze();
@@ -765,10 +765,11 @@ private Class> compileFormula(final String what, final String classBody, final
addParamClass.accept(p.type);
return null;
});
+ final QueryCompiler compiler = ExecutionContext.getContext().getQueryCompiler();
return AccessController
.doPrivileged(
- (PrivilegedExceptionAction>) () -> CompilerTools.compile(className, classBody,
- CompilerTools.FORMULA_PREFIX,
+ (PrivilegedExceptionAction>) () -> compiler.compile(className, classBody,
+ QueryCompiler.FORMULA_PREFIX,
QueryScopeParamTypeUtil.expandParameterClasses(paramClasses)));
} catch (PrivilegedActionException pae) {
throw new FormulaCompilationException("Formula compilation error for: " + what, pae.getException());
diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/QueryScopeParamTypeUtil.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/QueryScopeParamTypeUtil.java
index c1a25668420..eff4220e584 100644
--- a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/QueryScopeParamTypeUtil.java
+++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/QueryScopeParamTypeUtil.java
@@ -4,7 +4,7 @@
package io.deephaven.engine.table.impl.select;
import groovy.lang.Closure;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.util.type.TypeUtils;
import java.lang.reflect.Modifier;
@@ -48,7 +48,7 @@ private static void visitParameterClass(final Map> found, Class
}
final String name = cls.getName();
- if (!name.startsWith(CompilerTools.DYNAMIC_GROOVY_CLASS_PREFIX)) {
+ if (!name.startsWith(QueryCompiler.DYNAMIC_GROOVY_CLASS_PREFIX)) {
return;
}
diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/SelectColumn.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/SelectColumn.java
index f1aec384ff6..f4fbe37fa48 100644
--- a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/SelectColumn.java
+++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/SelectColumn.java
@@ -8,6 +8,7 @@
import io.deephaven.api.Selectable;
import io.deephaven.api.expression.Expression;
import io.deephaven.api.value.Value;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.engine.table.*;
import io.deephaven.engine.table.WritableColumnSource;
import io.deephaven.engine.rowset.TrackingRowSet;
@@ -69,8 +70,7 @@ static SelectColumn[] copyFrom(SelectColumn[] selectColumns) {
*
* @return a list of columns on which the result of this is dependent
* @apiNote Any {@link io.deephaven.engine.context.QueryLibrary}, {@link io.deephaven.engine.context.QueryScope}, or
- * {@link io.deephaven.engine.context.CompilerTools} usage needs to be resolved within initDef.
- * Implementations must be idempotent.
+ * {@link QueryCompiler} usage needs to be resolved within initDef. Implementations must be idempotent.
*/
List initDef(Map> columnDefinitionMap);
diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/WhereFilter.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/WhereFilter.java
index 38a349cf544..e17bf6fca8d 100644
--- a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/WhereFilter.java
+++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/WhereFilter.java
@@ -8,6 +8,7 @@
import io.deephaven.api.Strings;
import io.deephaven.api.filter.*;
import io.deephaven.api.value.Value;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.engine.rowset.WritableRowSet;
import io.deephaven.engine.table.Table;
import io.deephaven.engine.table.TableDefinition;
@@ -107,8 +108,7 @@ interface RecomputeListener {
*
* @param tableDefinition the definition of the table that will be filtered
* @apiNote Any {@link io.deephaven.engine.context.QueryLibrary}, {@link io.deephaven.engine.context.QueryScope}, or
- * {@link io.deephaven.engine.context.CompilerTools} usage needs to be resolved within init.
- * Implementations must be idempotent.
+ * {@link QueryCompiler} usage needs to be resolved within init. Implementations must be idempotent.
*/
void init(TableDefinition tableDefinition);
diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/codegen/JavaKernelBuilder.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/codegen/JavaKernelBuilder.java
index f650ec164c8..3cd97dbe1d7 100644
--- a/engine/table/src/main/java/io/deephaven/engine/table/impl/select/codegen/JavaKernelBuilder.java
+++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/select/codegen/JavaKernelBuilder.java
@@ -3,7 +3,7 @@
*/
package io.deephaven.engine.table.impl.select.codegen;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.engine.context.ExecutionContext;
import io.deephaven.vector.Vector;
import io.deephaven.engine.context.QueryScopeParam;
@@ -217,7 +217,7 @@ private CodeGenerator generateApplyFormulaPerItem(final TypeAnalyzer ta) {
null);
g.replace("ARGS", makeCommaSeparatedList(args));
g.replace("FORMULA_STRING", ta.wrapWithCastIfNecessary(cookedFormulaString));
- final String joinedFormulaString = CompilerTools.createEscapedJoinedString(cookedFormulaString);
+ final String joinedFormulaString = QueryCompiler.createEscapedJoinedString(cookedFormulaString);
g.replace("JOINED_FORMULA_STRING", joinedFormulaString);
g.replace("EXCEPTION_TYPE", FormulaEvaluationException.class.getCanonicalName());
return g.freeze();
@@ -266,8 +266,9 @@ private static Class> compileFormula(final String what, final String classBody
try (final QueryPerformanceNugget nugget =
QueryPerformanceRecorder.getInstance().getNugget("Compile:" + what)) {
// Compilation needs to take place with elevated privileges, but the created object should not have them.
- return AccessController.doPrivileged((PrivilegedExceptionAction>) () -> CompilerTools
- .compile(className, classBody, CompilerTools.FORMULA_PREFIX));
+ final QueryCompiler compiler = ExecutionContext.getContext().getQueryCompiler();
+ return AccessController.doPrivileged((PrivilegedExceptionAction>) () -> compiler.compile(className,
+ classBody, QueryCompiler.FORMULA_PREFIX));
} catch (PrivilegedActionException pae) {
throw new FormulaCompilationException("Formula compilation error for: " + what, pae.getException());
}
diff --git a/engine/table/src/main/java/io/deephaven/engine/util/AbstractScriptSession.java b/engine/table/src/main/java/io/deephaven/engine/util/AbstractScriptSession.java
index c2afafea72a..8caa1b24282 100644
--- a/engine/table/src/main/java/io/deephaven/engine/util/AbstractScriptSession.java
+++ b/engine/table/src/main/java/io/deephaven/engine/util/AbstractScriptSession.java
@@ -7,14 +7,13 @@
import io.deephaven.UncheckedDeephavenException;
import io.deephaven.api.util.NameValidator;
import io.deephaven.base.FileUtils;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.engine.context.ExecutionContext;
import io.deephaven.engine.liveness.LivenessScope;
import io.deephaven.engine.liveness.LivenessScopeStack;
import io.deephaven.engine.table.PartitionedTable;
import io.deephaven.engine.table.Table;
import io.deephaven.engine.table.TableDefinition;
-import io.deephaven.engine.context.QueryLibrary;
import io.deephaven.engine.context.QueryScope;
import io.deephaven.engine.context.QueryScopeParam;
import io.deephaven.plugin.type.ObjectType;
@@ -75,14 +74,13 @@ protected AbstractScriptSession(ObjectTypeLookup objectTypeLookup, @Nullable Lis
createOrClearDirectory(classCacheDirectory);
final QueryScope queryScope = newQueryScope();
- final CompilerTools.Context compilerContext =
- CompilerTools.newContext(classCacheDirectory, getClass().getClassLoader());
+ final QueryCompiler compilerContext = QueryCompiler.create(classCacheDirectory, getClass().getClassLoader());
executionContext = ExecutionContext.newBuilder()
.markSystemic()
.newQueryLibrary()
.setQueryScope(queryScope)
- .setCompilerContext(compilerContext)
+ .setQueryCompiler(compilerContext)
.build();
}
diff --git a/engine/table/src/main/java/io/deephaven/engine/util/DynamicCompileUtils.java b/engine/table/src/main/java/io/deephaven/engine/util/DynamicCompileUtils.java
index b9e79e81865..6991153b155 100644
--- a/engine/table/src/main/java/io/deephaven/engine/util/DynamicCompileUtils.java
+++ b/engine/table/src/main/java/io/deephaven/engine/util/DynamicCompileUtils.java
@@ -3,7 +3,8 @@
*/
package io.deephaven.engine.util;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.ExecutionContext;
+import io.deephaven.engine.context.QueryCompiler;
import java.util.*;
import java.util.function.Supplier;
@@ -51,8 +52,8 @@ public static Supplier compileSimpleFunction(final Class extends T> res
classBody.append(" }\n");
classBody.append("}\n");
- final Class partitionClass =
- CompilerTools.compile("Function", classBody.toString(), CompilerTools.FORMULA_PREFIX);
+ final Class> partitionClass = ExecutionContext.getContext().getQueryCompiler()
+ .compile("Function", classBody.toString(), QueryCompiler.FORMULA_PREFIX);
try {
// noinspection unchecked
@@ -70,8 +71,8 @@ public static Class getClassThroughCompilation(final String object) {
classBody.append(" public Class get() { return ").append(object).append(".class; }\n");
classBody.append("}\n");
- final Class partitionClass =
- CompilerTools.compile("Function", classBody.toString(), CompilerTools.FORMULA_PREFIX);
+ final Class> partitionClass = ExecutionContext.getContext().getQueryCompiler()
+ .compile("Function", classBody.toString(), QueryCompiler.FORMULA_PREFIX);
try {
// noinspection unchecked
diff --git a/engine/table/src/main/java/io/deephaven/engine/util/GroovyDeephavenSession.java b/engine/table/src/main/java/io/deephaven/engine/util/GroovyDeephavenSession.java
index 814cd175363..bac9aa5c942 100644
--- a/engine/table/src/main/java/io/deephaven/engine/util/GroovyDeephavenSession.java
+++ b/engine/table/src/main/java/io/deephaven/engine/util/GroovyDeephavenSession.java
@@ -11,7 +11,8 @@
import io.deephaven.base.FileUtils;
import io.deephaven.base.Pair;
import io.deephaven.base.StringUtils;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.ExecutionContext;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.configuration.Configuration;
import io.deephaven.engine.exceptions.CancellationException;
import io.deephaven.engine.updategraph.UpdateGraphProcessor;
@@ -58,7 +59,7 @@ public class GroovyDeephavenSession extends AbstractScriptSession fullCommand(String command) {
}
public static byte[] getDynamicClass(String name) {
- return readClass(CompilerTools.getContext().getFakeClassDestination(), name);
+ return readClass(ExecutionContext.getContext().getQueryCompiler().getFakeClassDestination(), name);
}
private static byte[] readClass(final File rootDirectory, final String className) {
@@ -573,7 +574,7 @@ private void updateClassloader(String currentCommand) {
} catch (RuntimeException e) {
throw new GroovyExceptionWrapper(e);
}
- final File dynamicClassDestination = CompilerTools.getContext().getFakeClassDestination();
+ final File dynamicClassDestination = ExecutionContext.getContext().getQueryCompiler().getFakeClassDestination();
if (dynamicClassDestination == null) {
return;
}
@@ -601,7 +602,7 @@ && isAnInteger(aClass.getName().substring(SCRIPT_PREFIX.length()))) {
}
try {
- CompilerTools.writeClass(dynamicClassDestination, entry.getKey(), entry.getValue());
+ QueryCompiler.writeClass(dynamicClassDestination, entry.getKey(), entry.getValue());
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -714,7 +715,7 @@ public Throwable sanitizeThrowable(Throwable e) {
@Override
public void onApplicationInitializationBegin(Supplier pathLoaderSupplier,
ScriptPathLoaderState scriptLoaderState) {
- CompilerTools.getContext().setParentClassLoader(getShell().getClassLoader());
+ ExecutionContext.getContext().getQueryCompiler().setParentClassLoader(getShell().getClassLoader());
setScriptPathLoader(pathLoaderSupplier, true);
}
@@ -764,7 +765,7 @@ public boolean setUseOriginalScriptLoaderState(boolean useOriginal) {
}
} else {
log.warn().append("Incorrect closure type for query: ")
- .append(sourceClosure == null ? "(null)" : sourceClosure.getClass().toString()).endl();
+ .append(sourceClosure.getClass().toString()).endl();
}
return false;
diff --git a/engine/table/src/test/java/io/deephaven/engine/table/impl/PartitionedTableTest.java b/engine/table/src/test/java/io/deephaven/engine/table/impl/PartitionedTableTest.java
index b01e68201b0..d435f55615c 100644
--- a/engine/table/src/test/java/io/deephaven/engine/table/impl/PartitionedTableTest.java
+++ b/engine/table/src/test/java/io/deephaven/engine/table/impl/PartitionedTableTest.java
@@ -465,7 +465,7 @@ public void testCrossDependencies() {
final ExecutionContext executionContext = ExecutionContext.newBuilder()
.captureQueryScopeVars("pauseHelper2")
.captureQueryLibrary()
- .captureCompilerContext()
+ .captureQueryCompiler()
.build();
final PartitionedTable result2 =
sourceTable2.update("SlowItDown=pauseHelper.pauseValue(k)").partitionBy("USym2")
@@ -552,7 +552,7 @@ public void testCrossDependencies2() {
final ExecutionContext executionContext = ExecutionContext.newBuilder()
.captureQueryScopeVars("pauseHelper")
.captureQueryLibrary()
- .captureCompilerContext()
+ .captureQueryCompiler()
.build();
final PartitionedTable result2 = sourceTable2.partitionBy("USym2")
.transform(executionContext, t -> t.update("SlowItDown2=pauseHelper.pauseValue(2 * k)"));
@@ -755,7 +755,7 @@ public void testMergeConstituentChanges() {
final Table underlying;
try (final SafeCloseable ignored = ExecutionContext.newBuilder()
.captureQueryLibrary()
- .captureCompilerContext()
+ .captureQueryCompiler()
.captureQueryScope()
.build().open()) {
underlying = base.update(
@@ -818,7 +818,7 @@ private EvalNugget newExecutionContextNugget(
protected Table e() {
// note we cannot reuse the execution context and remove the values as the table is built each iteration
try (final SafeCloseable ignored = ExecutionContext.newBuilder()
- .captureCompilerContext()
+ .captureQueryCompiler()
.captureQueryLibrary()
.newQueryScope()
.build().open()) {
diff --git a/engine/table/src/test/java/io/deephaven/engine/table/impl/RefreshingTableTestCase.java b/engine/table/src/test/java/io/deephaven/engine/table/impl/RefreshingTableTestCase.java
index a3d6bb2574d..bb050f156f5 100644
--- a/engine/table/src/test/java/io/deephaven/engine/table/impl/RefreshingTableTestCase.java
+++ b/engine/table/src/test/java/io/deephaven/engine/table/impl/RefreshingTableTestCase.java
@@ -6,7 +6,7 @@
import io.deephaven.base.testing.BaseArrayTestCase;
import io.deephaven.chunk.util.pools.ChunkPoolReleaseTracking;
import io.deephaven.configuration.Configuration;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.engine.context.ExecutionContext;
import io.deephaven.engine.liveness.LivenessScope;
import io.deephaven.engine.liveness.LivenessScopeStack;
@@ -30,8 +30,8 @@
abstract public class RefreshingTableTestCase extends BaseArrayTestCase implements UpdateErrorReporter {
public static boolean printTableUpdates = Configuration.getInstance()
.getBooleanForClassWithDefault(RefreshingTableTestCase.class, "printTableUpdates", false);
- private static final boolean ENABLE_COMPILER_TOOLS_LOGGING = Configuration.getInstance()
- .getBooleanForClassWithDefault(RefreshingTableTestCase.class, "CompilerTools.logEnabled", false);
+ private static final boolean ENABLE_QUERY_COMPILER_LOGGING = Configuration.getInstance()
+ .getBooleanForClassWithDefault(RefreshingTableTestCase.class, "QueryCompile.logEnabled", false);
private boolean oldMemoize;
private UpdateErrorReporter oldReporter;
@@ -62,7 +62,7 @@ protected void setUp() throws Exception {
// initialize the unit test's execution context
executionContext = ExecutionContext.createForUnitTests().open();
- oldLogEnabled = CompilerTools.setLogEnabled(ENABLE_COMPILER_TOOLS_LOGGING);
+ oldLogEnabled = QueryCompiler.setLogEnabled(ENABLE_QUERY_COMPILER_LOGGING);
oldCheckLtm = UpdateGraphProcessor.DEFAULT.setCheckTableOperations(false);
UpdatePerformanceTracker.getInstance().enableUnitTestMode();
ChunkPoolReleaseTracking.enableStrict();
@@ -72,7 +72,7 @@ protected void setUp() throws Exception {
protected void tearDown() throws Exception {
ChunkPoolReleaseTracking.checkAndDisable();
UpdateGraphProcessor.DEFAULT.setCheckTableOperations(oldCheckLtm);
- CompilerTools.setLogEnabled(oldLogEnabled);
+ QueryCompiler.setLogEnabled(oldLogEnabled);
// reset the execution context
executionContext.close();
diff --git a/engine/table/src/test/java/io/deephaven/engine/table/impl/TestSort.java b/engine/table/src/test/java/io/deephaven/engine/table/impl/TestSort.java
index 67c3d70b30c..284c1a3327a 100644
--- a/engine/table/src/test/java/io/deephaven/engine/table/impl/TestSort.java
+++ b/engine/table/src/test/java/io/deephaven/engine/table/impl/TestSort.java
@@ -4,7 +4,7 @@
package io.deephaven.engine.table.impl;
import io.deephaven.base.testing.BaseArrayTestCase;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.configuration.Configuration;
import io.deephaven.engine.exceptions.NotSortableException;
import io.deephaven.engine.table.DataColumn;
@@ -32,11 +32,11 @@
@Category(OutOfBandTest.class)
public class TestSort extends BaseArrayTestCase {
- private static final boolean ENABLE_COMPILER_TOOLS_LOGGING = Configuration.getInstance()
- .getBooleanForClassWithDefault(TestSort.class, "CompilerTools.logEnabled", false);
+ private static final boolean ENABLE_QUERY_COMPILER_LOGGING = Configuration.getInstance()
+ .getBooleanForClassWithDefault(TestSort.class, "QueryCompiler.logEnabled", false);
private boolean lastMemoize = false;
- private boolean oldCompilerToolsLogEnabled;
+ private boolean oldQueryCompilerLogEnabled;
private SafeCloseable executionContext;
@Override
@@ -45,14 +45,14 @@ protected void setUp() throws Exception {
UpdateGraphProcessor.DEFAULT.enableUnitTestMode();
UpdateGraphProcessor.DEFAULT.resetForUnitTests(false);
lastMemoize = QueryTable.setMemoizeResults(false);
- oldCompilerToolsLogEnabled = CompilerTools.setLogEnabled(ENABLE_COMPILER_TOOLS_LOGGING);
+ oldQueryCompilerLogEnabled = QueryCompiler.setLogEnabled(ENABLE_QUERY_COMPILER_LOGGING);
executionContext = ExecutionContext.createForUnitTests().open();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
- CompilerTools.setLogEnabled(oldCompilerToolsLogEnabled);
+ QueryCompiler.setLogEnabled(oldQueryCompilerLogEnabled);
QueryTable.setMemoizeResults(lastMemoize);
UpdateGraphProcessor.DEFAULT.resetForUnitTests(true);
executionContext.close();
diff --git a/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestConditionFilterGeneration.java b/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestConditionFilterGeneration.java
index 05fd0dea8d7..af6571a86f8 100644
--- a/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestConditionFilterGeneration.java
+++ b/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestConditionFilterGeneration.java
@@ -27,7 +27,7 @@ public class TestConditionFilterGeneration {
public void setUp() {
executionContext = ExecutionContext.newBuilder()
.newQueryLibrary("DEFAULT")
- .captureCompilerContext()
+ .captureQueryCompiler()
.captureQueryScope()
.build().open();
diff --git a/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestFormulaColumn.java b/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestFormulaColumn.java
index 6daf482aa16..372cd34f166 100644
--- a/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestFormulaColumn.java
+++ b/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestFormulaColumn.java
@@ -189,8 +189,8 @@ public void testArrayEvaluation() {
@Test
public void testNoInput() {
- final String oldValue = Configuration.getInstance().getProperty("CompilerTools.logEnabledDefault");
- Configuration.getInstance().setProperty("CompilerTools.logEnabledDefault", "true");
+ final String oldValue = Configuration.getInstance().getProperty("QueryCompiler.logEnabledDefault");
+ Configuration.getInstance().setProperty("QueryCompiler.logEnabledDefault", "true");
try {
FormulaColumn formulaColumn = FormulaColumn.createFormulaColumn("Foo", "(String)\"1234\"");
formulaColumn.initDef(Collections.emptyMap());
@@ -202,7 +202,7 @@ public void testNoInput() {
final long longResult = longFormulaColumn.getDataView().getLong(0);
assertEquals(longResult, 1234L);
} finally {
- Configuration.getInstance().setProperty("CompilerTools.logEnabledDefault", oldValue);
+ Configuration.getInstance().setProperty("QueryCompiler.logEnabledDefault", oldValue);
}
}
diff --git a/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestFormulaColumnGeneration.java b/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestFormulaColumnGeneration.java
index 28190f20058..356d85a5fce 100644
--- a/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestFormulaColumnGeneration.java
+++ b/engine/table/src/test/java/io/deephaven/engine/table/impl/select/TestFormulaColumnGeneration.java
@@ -5,7 +5,6 @@
import io.deephaven.engine.context.ExecutionContext;
import io.deephaven.engine.table.Table;
-import io.deephaven.engine.context.QueryLibrary;
import io.deephaven.engine.context.QueryScope;
import io.deephaven.engine.util.TableTools;
import io.deephaven.engine.table.impl.util.ModelFileGenerator;
@@ -48,7 +47,7 @@ public void generateFiles() throws FileNotFoundException {
public void setUp() {
executionContext = ExecutionContext.newBuilder()
.newQueryLibrary("DEFAULT")
- .captureCompilerContext()
+ .captureQueryCompiler()
.captureQueryScope()
.build().open();
}
diff --git a/engine/table/src/test/java/io/deephaven/engine/util/TestTableTools.java b/engine/table/src/test/java/io/deephaven/engine/util/TestTableTools.java
index 67eff6709c8..20b2bfe9c53 100644
--- a/engine/table/src/test/java/io/deephaven/engine/util/TestTableTools.java
+++ b/engine/table/src/test/java/io/deephaven/engine/util/TestTableTools.java
@@ -5,7 +5,7 @@
import io.deephaven.chunk.attributes.Values;
import io.deephaven.configuration.Configuration;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.datastructures.util.CollectionUtil;
import io.deephaven.engine.context.ExecutionContext;
import io.deephaven.engine.rowset.RowSet;
@@ -48,8 +48,8 @@
@Category(OutOfBandTest.class)
public class TestTableTools extends TestCase implements UpdateErrorReporter {
- private static final boolean ENABLE_COMPILER_TOOLS_LOGGING = Configuration.getInstance()
- .getBooleanForClassWithDefault(TestTableTools.class, "CompilerTools.logEnabled", false);
+ private static final boolean ENABLE_QUERY_COMPILER_LOGGING = Configuration.getInstance()
+ .getBooleanForClassWithDefault(TestTableTools.class, "QueryCompiler.logEnabled", false);
private UpdateErrorReporter oldReporter;
@@ -68,7 +68,7 @@ public void setUp() throws Exception {
super.setUp();
oldCheckUgp = UpdateGraphProcessor.DEFAULT.setCheckTableOperations(false);
- oldLogEnabled = CompilerTools.setLogEnabled(ENABLE_COMPILER_TOOLS_LOGGING);
+ oldLogEnabled = QueryCompiler.setLogEnabled(ENABLE_QUERY_COMPILER_LOGGING);
UpdateGraphProcessor.DEFAULT.enableUnitTestMode();
UpdateGraphProcessor.DEFAULT.resetForUnitTests(false);
UpdatePerformanceTracker.getInstance().enableUnitTestMode();
@@ -97,7 +97,7 @@ public void tearDown() throws Exception {
LivenessScopeStack.pop(scope);
scope.release();
executionContext.close();
- CompilerTools.setLogEnabled(oldLogEnabled);
+ QueryCompiler.setLogEnabled(oldLogEnabled);
UpdateGraphProcessor.DEFAULT.setCheckTableOperations(oldCheckUgp);
AsyncClientErrorNotifier.setReporter(oldReporter);
UpdateGraphProcessor.DEFAULT.resetForUnitTests(true);
diff --git a/props/configs/src/main/resources/dh-defaults.prop b/props/configs/src/main/resources/dh-defaults.prop
index 0b76987dac1..24a71e5ffaf 100644
--- a/props/configs/src/main/resources/dh-defaults.prop
+++ b/props/configs/src/main/resources/dh-defaults.prop
@@ -1,4 +1,4 @@
-CompilerTools.logEnabledDefault=false
+QueryCompiler.logEnabledDefault=false
UpdatePerformanceTracker.reportingMode=LISTENER_ONLY
UpdatePerformanceTracker.reportIntervalMillis=60000
measurement.per_thread_cpu=false
diff --git a/props/test-configs/src/main/resources/dh-tests.prop b/props/test-configs/src/main/resources/dh-tests.prop
index 3001014dc3c..e270fa9e6de 100644
--- a/props/test-configs/src/main/resources/dh-tests.prop
+++ b/props/test-configs/src/main/resources/dh-tests.prop
@@ -3,7 +3,7 @@ include=
measurement.per_thread_cpu=false
-CompilerTools.logEnabledDefault=false
+QueryCompiler.logEnabledDefault=false
UpdatePerformanceTracker.reportingMode=NONE
UpdatePerformanceTracker.reportIntervalMillis=60000
diff --git a/py/server/tests/test_partitioned_table.py b/py/server/tests/test_partitioned_table.py
index f64625daa17..dd2b7c89bb5 100644
--- a/py/server/tests/test_partitioned_table.py
+++ b/py/server/tests/test_partitioned_table.py
@@ -119,7 +119,7 @@ def test_constituents(self):
def test_transform(self):
_JExecutionContext = jpy.get_type("io.deephaven.engine.context.ExecutionContext")
context = _JExecutionContext.newBuilder() \
- .captureCompilerContext() \
+ .captureQueryCompiler() \
.captureQueryLibrary() \
.emptyQueryScope() \
.build().open()
@@ -137,7 +137,7 @@ def test_transform(self):
def test_partitioned_transform(self):
_JExecutionContext = jpy.get_type("io.deephaven.engine.context.ExecutionContext")
context = _JExecutionContext.newBuilder() \
- .captureCompilerContext() \
+ .captureQueryCompiler() \
.captureQueryLibrary() \
.emptyQueryScope() \
.build().open()
diff --git a/py/server/tests/test_table.py b/py/server/tests/test_table.py
index 592babc66aa..31e7913d7d3 100644
--- a/py/server/tests/test_table.py
+++ b/py/server/tests/test_table.py
@@ -625,7 +625,7 @@ def closure_fn() -> str:
def test_nested_scopes(self):
_JExecutionContext = jpy.get_type("io.deephaven.engine.context.ExecutionContext")
context = _JExecutionContext.newBuilder() \
- .captureCompilerContext() \
+ .captureQueryCompiler() \
.captureQueryLibrary() \
.captureQueryScope() \
.build()
@@ -642,7 +642,7 @@ def test_nested_scope_ticking(self):
import jpy
_JExecutionContext = jpy.get_type("io.deephaven.engine.context.ExecutionContext")
j_context = (_JExecutionContext.newBuilder()
- .captureCompilerContext()
+ .captureQueryCompiler()
.captureQueryLibrary()
.captureQueryScope()
.build())
diff --git a/py/server/tests/test_ugp.py b/py/server/tests/test_ugp.py
index 033721ecb7d..b49b85975e7 100644
--- a/py/server/tests/test_ugp.py
+++ b/py/server/tests/test_ugp.py
@@ -209,11 +209,11 @@ def test_auto_locking_partitioned_table(self):
_ExecutionContext = jpy.get_type("io.deephaven.engine.context.ExecutionContext")
_context = _ExecutionContext.newBuilder() \
- .captureCompilerContext() \
- .captureQueryLibrary() \
- .emptyQueryScope() \
- .build() \
- .open()
+ .captureQueryCompiler() \
+ .captureQueryLibrary() \
+ .emptyQueryScope() \
+ .build() \
+ .open()
with self.subTest("Merge"):
ugp.auto_locking = False
diff --git a/python-engine-test/src/test/java/io/deephaven/engine/table/impl/select/TestConditionFilter.java b/python-engine-test/src/test/java/io/deephaven/engine/table/impl/select/TestConditionFilter.java
index bf989294696..89cb4e93029 100644
--- a/python-engine-test/src/test/java/io/deephaven/engine/table/impl/select/TestConditionFilter.java
+++ b/python-engine-test/src/test/java/io/deephaven/engine/table/impl/select/TestConditionFilter.java
@@ -13,7 +13,7 @@
import io.deephaven.io.log.LogLevel;
import io.deephaven.io.logger.StreamLoggerImpl;
import io.deephaven.util.process.ProcessEnvironment;
-import io.deephaven.engine.context.CompilerTools;
+import io.deephaven.engine.context.QueryCompiler;
import io.deephaven.engine.table.Table;
import io.deephaven.engine.context.QueryScopeParam;
import io.deephaven.engine.context.QueryScope;
@@ -48,11 +48,11 @@ public class TestConditionFilter extends PythonTest {
}
}
- private static final boolean ENABLE_COMPILER_TOOLS_LOGGING = Configuration.getInstance()
- .getBooleanForClassWithDefault(TestConditionFilter.class, "CompilerTools.logEnabled", false);
+ private static final boolean ENABLE_QUERY_COMPILER_LOGGING = Configuration.getInstance()
+ .getBooleanForClassWithDefault(TestConditionFilter.class, "QueryCompiler.logEnabled", false);
private final Table testDataTable;
- private boolean compilerToolsLogEnabledInitial = false;
+ private boolean queryCompilerLogEnabledInitial = false;
public TestConditionFilter() {
testDataTable = getTestDataTable();
@@ -67,12 +67,12 @@ public void setUp() throws Exception {
ProcessEnvironment.basicInteractiveProcessInitialization(Configuration.getInstance(),
PythonMatchFilterTest.class.getCanonicalName(), new StreamLoggerImpl(System.out, LogLevel.INFO));
}
- compilerToolsLogEnabledInitial = CompilerTools.setLogEnabled(ENABLE_COMPILER_TOOLS_LOGGING);
+ queryCompilerLogEnabledInitial = QueryCompiler.setLogEnabled(ENABLE_QUERY_COMPILER_LOGGING);
}
@After
public void tearDown() throws Exception {
- CompilerTools.setLogEnabled(compilerToolsLogEnabledInitial);
+ QueryCompiler.setLogEnabled(queryCompilerLogEnabledInitial);
}
@Test