From 1d471fee92c3ff45d7cdfe582c0ccbc61748921a Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 14 Aug 2019 17:02:57 +1200 Subject: [PATCH] #1768 - Initial refactor extracting CallOrigin interface (#1791) --- src/main/java/io/ebean/bean/CallOrigin.java | 22 +++++ src/main/java/io/ebean/bean/CallStack.java | 81 +++++-------------- .../java/io/ebean/bean/ObjectGraphOrigin.java | 22 ++--- .../java/io/ebean/config/ServerConfig.java | 1 + src/main/java/io/ebean/util/EncodeB64.java | 32 ++++++++ .../io/ebeaninternal/api/SpiEbeanServer.java | 4 +- .../java/io/ebeaninternal/api/SpiQuery.java | 4 +- .../service/AutoTuneDiffCollection.java | 2 +- .../autotune/service/BaseQueryTuner.java | 12 +-- .../server/core/CallOriginFactory.java | 14 ++++ .../server/core/CallStackFactory.java | 14 ---- ...ory.java => DefaultCallOriginFactory.java} | 9 ++- .../server/core/DefaultServer.java | 16 ++-- .../server/core/DefaultSlowQueryListener.java | 2 +- .../server/core/NoopCallOriginFactory.java | 17 ++++ .../server/core/NoopCallStackFactory.java | 16 ---- .../server/loadcontext/DLoadContext.java | 6 +- .../server/querydefn/DefaultOrmQuery.java | 6 +- .../ebeaninternal/api/TDSpiEbeanServer.java | 4 +- .../query/autotune/TestAutoTuneProfiling.java | 4 +- .../org/tests/unitinternal/TestEncodeB64.java | 29 +++++++ .../unitinternal/TestOriginIntEncoding.java | 30 ------- src/test/resources/ebean.properties | 1 + 23 files changed, 184 insertions(+), 164 deletions(-) create mode 100644 src/main/java/io/ebean/bean/CallOrigin.java create mode 100644 src/main/java/io/ebean/util/EncodeB64.java create mode 100644 src/main/java/io/ebeaninternal/server/core/CallOriginFactory.java delete mode 100644 src/main/java/io/ebeaninternal/server/core/CallStackFactory.java rename src/main/java/io/ebeaninternal/server/core/{DefaultCallStackFactory.java => DefaultCallOriginFactory.java} (88%) create mode 100644 src/main/java/io/ebeaninternal/server/core/NoopCallOriginFactory.java delete mode 100644 src/main/java/io/ebeaninternal/server/core/NoopCallStackFactory.java create mode 100644 src/test/java/org/tests/unitinternal/TestEncodeB64.java delete mode 100644 src/test/java/org/tests/unitinternal/TestOriginIntEncoding.java diff --git a/src/main/java/io/ebean/bean/CallOrigin.java b/src/main/java/io/ebean/bean/CallOrigin.java new file mode 100644 index 000000000..4ef531944 --- /dev/null +++ b/src/main/java/io/ebean/bean/CallOrigin.java @@ -0,0 +1,22 @@ +package io.ebean.bean; + +/** + * A call origin for query execution profiling to collect graph use (for query tuning). + */ +public interface CallOrigin { + + /** + * Return the top element. Typically the top stack element with class and line. + */ + String getTopElement(); + + /** + * Return the full description of the call origin. + */ + String getFullDescription(); + + /** + * Compute and return an origin key based on the query hash. + */ + String getOriginKey(int queryHash); +} diff --git a/src/main/java/io/ebean/bean/CallStack.java b/src/main/java/io/ebean/bean/CallStack.java index d9006a026..2d2a5ffe5 100644 --- a/src/main/java/io/ebean/bean/CallStack.java +++ b/src/main/java/io/ebean/bean/CallStack.java @@ -3,6 +3,8 @@ package io.ebean.bean; import java.io.Serializable; import java.util.Arrays; +import static io.ebean.util.EncodeB64.enc; + /** * Represent the call stack (stack trace elements). *

@@ -17,15 +19,15 @@ import java.util.Arrays; * Note the call stack is trimmed to remove the common ebean internal elements. *

*/ -public final class CallStack implements Serializable { +public final class CallStack implements Serializable, CallOrigin { private static final long serialVersionUID = -8590644046907438579L; + private static final String NEWLINE = "\n"; + private final String zeroHash; private final String pathHash; - private final StackTraceElement[] callStack; - private final int hc; public CallStack(StackTraceElement[] callStack, int zeroHash, int pathHash) { @@ -37,12 +39,17 @@ public final class CallStack implements Serializable { private int computeHashCode() { int hc = 0; - for (StackTraceElement aCallStack : callStack) { - hc = 92821 * hc + aCallStack.hashCode(); + for (StackTraceElement element : callStack) { + hc = 92821 * hc + element.hashCode(); } return hc; } + @Override + public String toString() { + return zeroHash + ":" + pathHash + ":" + callStack[0]; + } + @Override public int hashCode() { return hc; @@ -63,73 +70,29 @@ public final class CallStack implements Serializable { /** * Return the first element of the call stack. */ - public StackTraceElement getFirstStackTraceElement() { - return callStack[0]; - } - - /** - * Return the call stack. - */ - public StackTraceElement[] getCallStack() { - return callStack; - } - - /** - * Return the hash for the first stack element. - */ - public String getZeroHash() { - return zeroHash; - } - - /** - * Return the hash for the stack elements (excluding first stack element). - */ - public String getPathHash() { - return pathHash; - } - @Override - public String toString() { - return zeroHash + ":" + pathHash + ":" + callStack[0]; + public String getTopElement() { + return callStack[0].toString(); } /** * Return the call stack lines appended with the given newLine string. */ - public String description(String newLine) { + @Override + public String getFullDescription() { StringBuilder sb = new StringBuilder(400); - for (StackTraceElement aCallStack : callStack) { - sb.append(aCallStack.toString()).append(newLine); + for (int i = 0; i < callStack.length; i++) { + if (i > 0) { + sb.append(NEWLINE); + } + sb.append(callStack[i].toString()); } return sb.toString(); } + @Override public String getOriginKey(int queryHash) { return enc(queryHash) + "." + zeroHash + "." + pathHash; } - private static final int radix = 1 << 6; - private static final int mask = radix - 1; - - /** - * Convert the integer to unsigned base 64. - */ - public static String enc(int i) { - char[] buf = new char[32]; - int charPos = 32; - do { - buf[--charPos] = intToBase64[i & mask]; - i >>>= 6; - } while (i != 0); - - return new String(buf, charPos, (32 - charPos)); - } - - private static final char intToBase64[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' - }; } diff --git a/src/main/java/io/ebean/bean/ObjectGraphOrigin.java b/src/main/java/io/ebean/bean/ObjectGraphOrigin.java index 5f32f44ef..07d636a01 100644 --- a/src/main/java/io/ebean/bean/ObjectGraphOrigin.java +++ b/src/main/java/io/ebean/bean/ObjectGraphOrigin.java @@ -16,7 +16,7 @@ public final class ObjectGraphOrigin implements Serializable { private static final long serialVersionUID = 410937765287968708L; - private final CallStack callStack; + private final CallOrigin callOrigin; private final String beanType; @@ -24,11 +24,11 @@ public final class ObjectGraphOrigin implements Serializable { private final String key; - public ObjectGraphOrigin(int queryHash, CallStack callStack, String beanType) { - this.callStack = callStack; + public ObjectGraphOrigin(int queryHash, CallOrigin callOrigin, String beanType) { + this.callOrigin = callOrigin; this.beanType = beanType; this.queryHash = queryHash; - this.key = callStack.getOriginKey(queryHash); + this.key = callOrigin.getOriginKey(queryHash); } /** @@ -49,22 +49,22 @@ public final class ObjectGraphOrigin implements Serializable { /** * The call stack involved. */ - public CallStack getCallStack() { - return callStack; + public CallOrigin getCallOrigin() { + return callOrigin; } - public String getFirstStackElement() { - return callStack.getFirstStackTraceElement().toString(); + public String getTopElement() { + return callOrigin.getTopElement(); } @Override public String toString() { - return "key[" + key + "] type[" + beanType + "] " + callStack.getFirstStackTraceElement() + " "; + return "key[" + key + "] type[" + beanType + "] " + callOrigin.getTopElement(); } @Override public int hashCode() { - int hc = 92821 * callStack.hashCode(); + int hc = 92821 * callOrigin.hashCode(); hc = 92821 * hc + beanType.hashCode(); hc = 92821 * hc + queryHash; return hc; @@ -82,6 +82,6 @@ public final class ObjectGraphOrigin implements Serializable { ObjectGraphOrigin e = (ObjectGraphOrigin) obj; return e.queryHash == queryHash && e.beanType.equals(beanType) - && e.callStack.equals(callStack); + && e.callOrigin.equals(callOrigin); } } diff --git a/src/main/java/io/ebean/config/ServerConfig.java b/src/main/java/io/ebean/config/ServerConfig.java index 76cb0654c..3603fa9d2 100644 --- a/src/main/java/io/ebean/config/ServerConfig.java +++ b/src/main/java/io/ebean/config/ServerConfig.java @@ -2929,6 +2929,7 @@ public class ServerConfig { } loadDocStoreSettings(p); + maxCallStack = p.getInt("maxCallStack", maxCallStack); dumpMetricsOnShutdown = p.getBoolean("dumpMetricsOnShutdown", dumpMetricsOnShutdown); dumpMetricsOptions = p.get("dumpMetricsOptions", dumpMetricsOptions); queryPlanTTLSeconds = p.getInt("queryPlanTTLSeconds", queryPlanTTLSeconds); diff --git a/src/main/java/io/ebean/util/EncodeB64.java b/src/main/java/io/ebean/util/EncodeB64.java new file mode 100644 index 000000000..9eedf9c02 --- /dev/null +++ b/src/main/java/io/ebean/util/EncodeB64.java @@ -0,0 +1,32 @@ +package io.ebean.util; + +/** + * Integer to base64 encoder. + */ +public final class EncodeB64 { + + private static final int radix = 1 << 6; + private static final int mask = radix - 1; + + /** + * Convert the integer to unsigned base 64. + */ + public static String enc(int i) { + char[] buf = new char[32]; + int charPos = 32; + do { + buf[--charPos] = intToBase64[i & mask]; + i >>>= 6; + } while (i != 0); + + return new String(buf, charPos, (32 - charPos)); + } + + private static final char intToBase64[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' + }; +} diff --git a/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java b/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java index b8e4e9b7c..e594395d2 100644 --- a/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java +++ b/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java @@ -11,7 +11,7 @@ import io.ebean.Transaction; import io.ebean.TxScope; import io.ebean.bean.BeanCollectionLoader; import io.ebean.bean.BeanLoader; -import io.ebean.bean.CallStack; +import io.ebean.bean.CallOrigin; import io.ebean.bean.ObjectGraphNode; import io.ebean.config.ServerConfig; import io.ebean.config.dbplatform.DatabasePlatform; @@ -81,7 +81,7 @@ public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanLoader, * graph costing. *

*/ - CallStack createCallStack(); + CallOrigin createCallOrigin(); /** * Return the PersistenceContextScope to use defined at query or server level. diff --git a/src/main/java/io/ebeaninternal/api/SpiQuery.java b/src/main/java/io/ebeaninternal/api/SpiQuery.java index 112c0c7b8..7f3f5596f 100644 --- a/src/main/java/io/ebeaninternal/api/SpiQuery.java +++ b/src/main/java/io/ebeaninternal/api/SpiQuery.java @@ -7,7 +7,7 @@ import io.ebean.OrderBy; import io.ebean.PersistenceContextScope; import io.ebean.ProfileLocation; import io.ebean.Query; -import io.ebean.bean.CallStack; +import io.ebean.bean.CallOrigin; import io.ebean.bean.ObjectGraphNode; import io.ebean.bean.PersistenceContext; import io.ebean.event.readaudit.ReadEvent; @@ -558,7 +558,7 @@ public interface SpiQuery extends Query, TxnProfileEventCodes { * because the queryPlanHash is used to identify the query point. *

*/ - ObjectGraphNode setOrigin(CallStack callStack); + ObjectGraphNode setOrigin(CallOrigin callOrigin); /** * Set the profile point of the bean or collection that is lazy loading. diff --git a/src/main/java/io/ebeaninternal/server/autotune/service/AutoTuneDiffCollection.java b/src/main/java/io/ebeaninternal/server/autotune/service/AutoTuneDiffCollection.java index 4f8213388..2d3d3e04c 100644 --- a/src/main/java/io/ebeaninternal/server/autotune/service/AutoTuneDiffCollection.java +++ b/src/main/java/io/ebeaninternal/server/autotune/service/AutoTuneDiffCollection.java @@ -149,7 +149,7 @@ public class AutoTuneDiffCollection { origin.setKey(point.getKey()); origin.setBeanType(point.getBeanType()); origin.setDetail(entry.getDetail().toString()); - origin.setCallStack(point.getCallStack().description("\n")); + origin.setCallStack(point.getCallOrigin().getFullDescription()); origin.setOriginal(query); if (updateTuning) { diff --git a/src/main/java/io/ebeaninternal/server/autotune/service/BaseQueryTuner.java b/src/main/java/io/ebeaninternal/server/autotune/service/BaseQueryTuner.java index 8219b179c..5a9a99130 100644 --- a/src/main/java/io/ebeaninternal/server/autotune/service/BaseQueryTuner.java +++ b/src/main/java/io/ebeaninternal/server/autotune/service/BaseQueryTuner.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.autotune.service; -import io.ebean.bean.CallStack; +import io.ebean.bean.CallOrigin; import io.ebean.bean.ObjectGraphNode; import io.ebean.config.AutoTuneConfig; import io.ebean.config.AutoTuneMode; @@ -97,7 +97,7 @@ public class BaseQueryTuner { if (!useTuning(query)) { if (profiling) { - profiling(query, server.createCallStack()); + profiling(query, server.createCallOrigin()); } return false; } @@ -110,8 +110,8 @@ public class BaseQueryTuner { } // create a query point to identify the query - CallStack stack = server.createCallStack(); - ObjectGraphNode origin = query.setOrigin(stack); + CallOrigin callOrigin = server.createCallOrigin(); + ObjectGraphNode origin = query.setOrigin(callOrigin); if (profiling) { if (profilingListener.isProfileRequest(origin, query)) { @@ -154,10 +154,10 @@ public class BaseQueryTuner { } } - private void profiling(SpiQuery query, CallStack stack) { + private void profiling(SpiQuery query, CallOrigin call) { // create a query point to identify the query - ObjectGraphNode origin = query.setOrigin(stack); + ObjectGraphNode origin = query.setOrigin(call); if (profilingListener.isProfileRequest(origin, query)) { // collect more profiling based on profiling rate etc query.setProfilingListener(profilingListener); diff --git a/src/main/java/io/ebeaninternal/server/core/CallOriginFactory.java b/src/main/java/io/ebeaninternal/server/core/CallOriginFactory.java new file mode 100644 index 000000000..5de09a508 --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/core/CallOriginFactory.java @@ -0,0 +1,14 @@ +package io.ebeaninternal.server.core; + +import io.ebean.bean.CallOrigin; + +/** + * Creates CallOrigin based on the stack trace. + */ +public interface CallOriginFactory { + + /** + * Create and return the CallStack given the stack trace elements. + */ + CallOrigin createCallOrigin(); +} diff --git a/src/main/java/io/ebeaninternal/server/core/CallStackFactory.java b/src/main/java/io/ebeaninternal/server/core/CallStackFactory.java deleted file mode 100644 index b61c40370..000000000 --- a/src/main/java/io/ebeaninternal/server/core/CallStackFactory.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.ebeaninternal.server.core; - -import io.ebean.bean.CallStack; - -/** - * Creates CallStack based on the stack trace. - */ -public interface CallStackFactory { - - /** - * Create and return the CallStack given the stack trace elements. - */ - CallStack createCallStack(); -} diff --git a/src/main/java/io/ebeaninternal/server/core/DefaultCallStackFactory.java b/src/main/java/io/ebeaninternal/server/core/DefaultCallOriginFactory.java similarity index 88% rename from src/main/java/io/ebeaninternal/server/core/DefaultCallStackFactory.java rename to src/main/java/io/ebeaninternal/server/core/DefaultCallOriginFactory.java index 169faa93d..249f4dbdb 100644 --- a/src/main/java/io/ebeaninternal/server/core/DefaultCallStackFactory.java +++ b/src/main/java/io/ebeaninternal/server/core/DefaultCallOriginFactory.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.core; +import io.ebean.bean.CallOrigin; import io.ebean.bean.CallStack; import java.util.Arrays; @@ -7,7 +8,7 @@ import java.util.Arrays; /** * Default CallStackFactory where the Hash function for StackTraceElement includes the line number. */ -public class DefaultCallStackFactory implements CallStackFactory { +public class DefaultCallOriginFactory implements CallOriginFactory { private static final int IGNORE_LEADING_ELEMENTS = 5; @@ -15,12 +16,12 @@ public class DefaultCallStackFactory implements CallStackFactory { private final int maxCallStack; - DefaultCallStackFactory(int maxCallStack) { + DefaultCallOriginFactory(int maxCallStack) { this.maxCallStack = maxCallStack; } @Override - public CallStack createCallStack() { + public CallOrigin createCallOrigin() { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); // ignore the first 6 as they are always avaje stack elements @@ -58,7 +59,7 @@ public class DefaultCallStackFactory implements CallStackFactory { return element.getMethodName().startsWith("_ebean_"); } - private CallStack createCallStack(StackTraceElement[] finalTrace) { + private CallOrigin createCallStack(StackTraceElement[] finalTrace) { return new CallStack(finalTrace, finalTrace[0].hashCode(), pathHash(finalTrace)); } diff --git a/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index 708a379d7..7f141146a 100644 --- a/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -35,7 +35,7 @@ import io.ebean.ValuePair; import io.ebean.Version; import io.ebean.annotation.TxIsolation; import io.ebean.bean.BeanCollection; -import io.ebean.bean.CallStack; +import io.ebean.bean.CallOrigin; import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; import io.ebean.bean.ObjectGraphNode; @@ -164,7 +164,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { */ private final ClockService clockService; - private final CallStackFactory callStackFactory; + private final CallOriginFactory callStackFactory; /** * Handles the save, delete, updateSql CallableSql. @@ -312,12 +312,12 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { /** * Create the CallStackFactory depending if AutoTune is being used. */ - private CallStackFactory initCallStackFactory(ServerConfig serverConfig) { + private CallOriginFactory initCallStackFactory(ServerConfig serverConfig) { if (!serverConfig.getAutoTuneConfig().isActive()) { // use a common CallStack for performance as we don't care with no AutoTune - return new NoopCallStackFactory(); + return new NoopCallOriginFactory(); } - return new DefaultCallStackFactory(serverConfig.getMaxCallStack()); + return new DefaultCallOriginFactory(serverConfig.getMaxCallStack()); } private void configureServerPlugins() { @@ -1135,7 +1135,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { } // if determine cost and no origin for AutoTune if (query.getParentNode() == null) { - query.setOrigin(createCallStack()); + query.setOrigin(createCallOrigin()); } return new OrmQueryRequest<>(this, queryEngine, query, (SpiTransaction) t); @@ -2309,8 +2309,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { *

*/ @Override - public CallStack createCallStack() { - return callStackFactory.createCallStack(); + public CallOrigin createCallOrigin() { + return callStackFactory.createCallOrigin(); } @Override diff --git a/src/main/java/io/ebeaninternal/server/core/DefaultSlowQueryListener.java b/src/main/java/io/ebeaninternal/server/core/DefaultSlowQueryListener.java index e6e02833e..b271a513e 100644 --- a/src/main/java/io/ebeaninternal/server/core/DefaultSlowQueryListener.java +++ b/src/main/java/io/ebeaninternal/server/core/DefaultSlowQueryListener.java @@ -19,7 +19,7 @@ class DefaultSlowQueryListener implements SlowQueryListener { String firstStack = ""; ObjectGraphNode node = event.getOriginNode(); if (node != null) { - firstStack = node.getOriginQueryPoint().getFirstStackElement(); + firstStack = node.getOriginQueryPoint().getTopElement(); } log.warn("Slow query warning - millis:{} rows:{} caller[{}] sql[{}]", event.getTimeMillis(), event.getRowCount(), firstStack, event.getSql()); } diff --git a/src/main/java/io/ebeaninternal/server/core/NoopCallOriginFactory.java b/src/main/java/io/ebeaninternal/server/core/NoopCallOriginFactory.java new file mode 100644 index 000000000..314b32c68 --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/core/NoopCallOriginFactory.java @@ -0,0 +1,17 @@ +package io.ebeaninternal.server.core; + +import io.ebean.bean.CallOrigin; +import io.ebean.bean.CallStack; + +/** + * A CallOriginFactory we can use when we don't use AutoTune. + */ +class NoopCallOriginFactory implements CallOriginFactory { + + private final CallOrigin COMMON = new CallStack(Thread.currentThread().getStackTrace(), 0, 0); + + @Override + public CallOrigin createCallOrigin() { + return COMMON; + } +} diff --git a/src/main/java/io/ebeaninternal/server/core/NoopCallStackFactory.java b/src/main/java/io/ebeaninternal/server/core/NoopCallStackFactory.java deleted file mode 100644 index 8e04cd414..000000000 --- a/src/main/java/io/ebeaninternal/server/core/NoopCallStackFactory.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.ebeaninternal.server.core; - -import io.ebean.bean.CallStack; - -/** - * A CallStackFactory we can use when we don't use AutoTune. - */ -class NoopCallStackFactory implements CallStackFactory { - - private final CallStack COMMON = new CallStack(Thread.currentThread().getStackTrace(), 0, 0); - - @Override - public CallStack createCallStack() { - return COMMON; - } -} diff --git a/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java b/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java index 1f2e2e297..bac4528e8 100644 --- a/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java +++ b/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.loadcontext; import io.ebean.CacheMode; import io.ebean.ProfileLocation; import io.ebean.bean.BeanCollection; -import io.ebean.bean.CallStack; +import io.ebean.bean.CallOrigin; import io.ebean.bean.EntityBeanIntercept; import io.ebean.bean.ObjectGraphNode; import io.ebean.bean.ObjectGraphOrigin; @@ -94,8 +94,8 @@ public class DLoadContext implements LoadContext { } private ObjectGraphOrigin initOrigin() { - CallStack callStack = ebeanServer.createCallStack(); - return new ObjectGraphOrigin(0, callStack, rootDescriptor.getFullName()); + CallOrigin callOrigin = ebeanServer.createCallOrigin(); + return new ObjectGraphOrigin(0, callOrigin, rootDescriptor.getFullName()); } public DLoadContext(OrmQueryRequest request, SpiQuerySecondary secondaryQueries) { diff --git a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index a63e9380b..b03596175 100644 --- a/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -24,7 +24,7 @@ import io.ebean.RawSql; import io.ebean.Transaction; import io.ebean.UpdateQuery; import io.ebean.Version; -import io.ebean.bean.CallStack; +import io.ebean.bean.CallOrigin; import io.ebean.bean.ObjectGraphNode; import io.ebean.bean.ObjectGraphOrigin; import io.ebean.bean.PersistenceContext; @@ -1073,10 +1073,10 @@ public class DefaultOrmQuery implements SpiQuery { } @Override - public ObjectGraphNode setOrigin(CallStack callStack) { + public ObjectGraphNode setOrigin(CallOrigin callOrigin) { // create a 'origin' which links this query to the profiling information - ObjectGraphOrigin o = new ObjectGraphOrigin(calculateOriginQueryHash(), callStack, beanType.getName()); + ObjectGraphOrigin o = new ObjectGraphOrigin(calculateOriginQueryHash(), callOrigin, beanType.getName()); parentNode = new ObjectGraphNode(o, null); return parentNode; } diff --git a/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java b/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java index e52dda337..5da3fdabf 100644 --- a/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java +++ b/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java @@ -32,7 +32,7 @@ import io.ebean.ValuePair; import io.ebean.Version; import io.ebean.annotation.TxIsolation; import io.ebean.bean.BeanCollection; -import io.ebean.bean.CallStack; +import io.ebean.bean.CallOrigin; import io.ebean.bean.EntityBeanIntercept; import io.ebean.bean.ObjectGraphNode; import io.ebean.cache.ServerCacheManager; @@ -168,7 +168,7 @@ public class TDSpiEbeanServer implements SpiEbeanServer { } @Override - public CallStack createCallStack() { + public CallOrigin createCallOrigin() { return null; } diff --git a/src/test/java/org/tests/query/autotune/TestAutoTuneProfiling.java b/src/test/java/org/tests/query/autotune/TestAutoTuneProfiling.java index 6f1a020fd..e12491f64 100644 --- a/src/test/java/org/tests/query/autotune/TestAutoTuneProfiling.java +++ b/src/test/java/org/tests/query/autotune/TestAutoTuneProfiling.java @@ -21,7 +21,7 @@ public class TestAutoTuneProfiling extends BaseTestCase { ResetBasicData.reset(); - for (int i = 0; i < 1; i++) { + for (int i = 0; i < 10; i++) { execute(); } collectUsage(); @@ -35,7 +35,7 @@ public class TestAutoTuneProfiling extends BaseTestCase { sortOfBusy(); - for (int i = 0; i < 1; i++) { + for (int i = 0; i < 10; i++) { execute(); } } diff --git a/src/test/java/org/tests/unitinternal/TestEncodeB64.java b/src/test/java/org/tests/unitinternal/TestEncodeB64.java new file mode 100644 index 000000000..95124fcad --- /dev/null +++ b/src/test/java/org/tests/unitinternal/TestEncodeB64.java @@ -0,0 +1,29 @@ +package org.tests.unitinternal; + +import org.junit.Test; + +import static io.ebean.util.EncodeB64.enc; +import static org.junit.Assert.assertEquals; + +public class TestEncodeB64 { + + @Test + public void test() { + + assertEquals("A", enc(0)); + assertEquals("B", enc(1)); + assertEquals("Z", enc(25)); + assertEquals("a", enc(26)); + assertEquals("z", enc(51)); + assertEquals("0", enc(52)); + assertEquals("9", enc(61)); + assertEquals("-", enc(62)); + assertEquals("_", enc(63)); + assertEquals("BA", enc(64)); + assertEquals("Bk", enc(100)); + assertEquals("B9", enc(125)); + assertEquals("B-", enc(126)); + assertEquals("B_", enc(127)); + assertEquals("CA", enc(128)); + } +} diff --git a/src/test/java/org/tests/unitinternal/TestOriginIntEncoding.java b/src/test/java/org/tests/unitinternal/TestOriginIntEncoding.java deleted file mode 100644 index 78a6267be..000000000 --- a/src/test/java/org/tests/unitinternal/TestOriginIntEncoding.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.tests.unitinternal; - -import io.ebean.BaseTestCase; -import io.ebean.bean.CallStack; -import org.junit.Assert; -import org.junit.Test; - -public class TestOriginIntEncoding extends BaseTestCase { - - @Test - public void test() { - - Assert.assertEquals("A", CallStack.enc(0)); - Assert.assertEquals("B", CallStack.enc(1)); - Assert.assertEquals("Z", CallStack.enc(25)); - Assert.assertEquals("a", CallStack.enc(26)); - Assert.assertEquals("z", CallStack.enc(51)); - Assert.assertEquals("0", CallStack.enc(52)); - Assert.assertEquals("9", CallStack.enc(61)); - Assert.assertEquals("-", CallStack.enc(62)); - Assert.assertEquals("_", CallStack.enc(63)); - Assert.assertEquals("BA", CallStack.enc(64)); - Assert.assertEquals("Bk", CallStack.enc(100)); - Assert.assertEquals("B9", CallStack.enc(125)); - Assert.assertEquals("B-", CallStack.enc(126)); - Assert.assertEquals("B_", CallStack.enc(127)); - Assert.assertEquals("CA", CallStack.enc(128)); - - } -} diff --git a/src/test/resources/ebean.properties b/src/test/resources/ebean.properties index ccca26091..e1c4edbc6 100644 --- a/src/test/resources/ebean.properties +++ b/src/test/resources/ebean.properties @@ -12,6 +12,7 @@ ebean.encryptKeyManager=org.tests.basic.encrypt.BasicEncyptKeyManager #ebean.disableL2Cache=true +#ebean.maxCallStack=1 #ebean.autoTune.queryTuning=true #ebean.autoTune.mode=DEFAULT_ON #ebean.autoTune.profiling=true