optimization: skip conversion to then from TypeToken if we have a raw class as a type
this was a noticeable expense when doing profiling Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/98dfee22 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/98dfee22 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/98dfee22 Branch: refs/heads/master Commit: 98dfee22abb9f00464db77f3e86f40d4e9b4d61d Parents: 330f89e Author: Alex Heneveld <[email protected]> Authored: Mon Sep 11 15:43:18 2017 +0100 Committer: Alex Heneveld <[email protected]> Committed: Tue Sep 12 22:12:36 2017 +0100 ---------------------------------------------------------------------- .../brooklyn/core/config/BasicConfigKey.java | 41 +++++++++++++------- .../core/sensor/BasicAttributeSensor.java | 11 ++++-- .../brooklyn/core/sensor/BasicSensor.java | 19 ++++++--- .../apache/brooklyn/core/sensor/Sensors.java | 9 +++-- .../apache/brooklyn/util/guava/TypeTokens.java | 14 +++++++ 5 files changed, 66 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98dfee22/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigKey.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigKey.java b/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigKey.java index 8560361..8c6c25b 100644 --- a/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigKey.java +++ b/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigKey.java @@ -102,7 +102,8 @@ public class BasicConfigKey<T> implements ConfigKeySelfExtracting<T>, Serializab public abstract static class Builder<T, B extends Builder<T,B>> { protected String name; protected Collection<String> deprecatedNames = ImmutableList.of(); - protected TypeToken<T> type; + protected Class<T> type; + protected TypeToken<T> typeToken; protected String description; protected T defaultValue; protected boolean reconfigurable; @@ -115,17 +116,21 @@ public class BasicConfigKey<T> implements ConfigKeySelfExtracting<T>, Serializab public Builder() { } public Builder(TypeToken<T> type, String name) { - this.type = type; + this.typeToken = type; this.name = name; } public Builder(Class<T> type, String name) { - this(TypeToken.of(type), name); + this.type = type; + this.name = name; } public Builder(ConfigKey<T> key) { this(key.getName(), key); } + @SuppressWarnings("unchecked") public Builder(String newName, ConfigKey<T> key) { - this.type = checkNotNull(key.getTypeToken(), "type"); + TypeToken<T> tt = key.getTypeToken(); + this.type = (Class<T>) TypeTokens.getRawTypeIfRaw(tt); + this.typeToken = TypeTokens.getTypeTokenIfNotRaw(tt); this.name = checkNotNull(newName, "name"); this.deprecatedNames = checkNotNull(key.getDeprecatedNames(), "deprecatedNames"); description(key.getDescription()); @@ -145,10 +150,10 @@ public class BasicConfigKey<T> implements ConfigKeySelfExtracting<T>, Serializab return deprecatedNames(val == null ? ImmutableList.of() : ImmutableList.copyOf(val)); } public B type(Class<T> val) { - this.type = TypeToken.of(val); return self(); + this.type = val; return self(); } public B type(TypeToken<T> val) { - this.type = val; return self(); + this.typeToken = val; return self(); } public B description(String val) { this.description = val; return self(); @@ -225,32 +230,37 @@ public class BasicConfigKey<T> implements ConfigKeySelfExtracting<T>, Serializab public BasicConfigKey() { /* for gson */ } public BasicConfigKey(Class<T> type, String name) { - this(TypeToken.of(type), name); + this(type, null, name, null, null); } public BasicConfigKey(Class<T> type, String name, String description) { - this(TypeToken.of(type), name, description); + this(type, null, name, description, null); } public BasicConfigKey(Class<T> type, String name, String description, T defaultValue) { - this(TypeToken.of(type), name, description, defaultValue); + this(type, null, name, description, defaultValue); } public BasicConfigKey(TypeToken<T> type, String name) { - this(type, name, name, null); + this(null, type, name, name, null); } public BasicConfigKey(TypeToken<T> type, String name, String description) { - this(type, name, description, null); + this(null, type, name, description, null); } public BasicConfigKey(TypeToken<T> type, String name, String description, T defaultValue) { + this(null, type, name, description, defaultValue); + } + + // exactly one of typeC or typeT should be non-null + private BasicConfigKey(Class<T> typeC, TypeToken<T> typeT, String name, String description, T defaultValue) { this.description = description; this.name = checkNotNull(name, "name"); this.deprecatedNames = ImmutableList.of(); - this.type = TypeTokens.getRawTypeIfRaw(checkNotNull(type, "type")); - this.typeToken = TypeTokens.getTypeTokenIfNotRaw(type); + this.type = typeC; + this.typeToken = typeT; this.defaultValue = defaultValue; this.reconfigurable = false; @@ -260,8 +270,9 @@ public class BasicConfigKey<T> implements ConfigKeySelfExtracting<T>, Serializab public BasicConfigKey(Builder<T,?> builder) { this.name = checkNotNull(builder.name, "name"); this.deprecatedNames = checkNotNull(builder.deprecatedNames, "deprecatedNames"); - this.type = TypeTokens.getRawTypeIfRaw(checkNotNull(builder.type, "type")); - this.typeToken = TypeTokens.getTypeTokenIfNotRaw(builder.type); + TypeTokens.checkCompatibleOneNonNull(builder.type, builder.typeToken); + this.type = builder.type; + this.typeToken = builder.typeToken; this.description = builder.description; this.defaultValue = builder.defaultValue; this.reconfigurable = builder.reconfigurable; http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98dfee22/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensor.java index 978e4a4..e03c546 100644 --- a/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensor.java +++ b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensor.java @@ -38,19 +38,24 @@ public class BasicAttributeSensor<T> extends BasicSensor<T> implements Attribute } public BasicAttributeSensor(Class<T> type, String name, String description) { - this(TypeToken.of(type), name, description); + this(type, name, description, SensorPersistenceMode.REQUIRED); } public BasicAttributeSensor(TypeToken<T> typeToken, String name) { this(typeToken, name, name); } - public BasicAttributeSensor(TypeToken<T> typeToken, String name, String description) { this(typeToken, name, description, SensorPersistenceMode.REQUIRED); } + public BasicAttributeSensor(Class<T> type, String name, String description, SensorPersistenceMode persistence) { + this(type, null, name, description, persistence); + } public BasicAttributeSensor(TypeToken<T> typeToken, String name, String description, SensorPersistenceMode persistence) { - super(typeToken, name, description); + this(null, typeToken, name, description, persistence); + } + public BasicAttributeSensor(Class<T> type, TypeToken<T> typeToken, String name, String description, SensorPersistenceMode persistence) { + super(type, typeToken, name, description); this.persistence = checkNotNull(persistence, "persistence"); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98dfee22/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensor.java index f5589d4..a5a6a35 100644 --- a/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensor.java +++ b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensor.java @@ -46,21 +46,28 @@ public class BasicSensor<T> implements Sensor<T> { private String description; private transient List<String> nameParts; - // FIXME In groovy, fields were `public final` with a default constructor; do we need the gson? - public BasicSensor() { /* for gson */ } + // constructor for json/gson (can probably be private?) + public BasicSensor() {} /** name is typically a dot-separated identifier; description is optional */ public BasicSensor(Class<T> type, String name) { - this(type, name, name); + this(type, null, name, name); } public BasicSensor(Class<T> type, String name, String description) { - this(TypeToken.of(type), name, description); + this(type, null, name, description); } + @SuppressWarnings("unchecked") public BasicSensor(TypeToken<T> typeToken, String name, String description) { - this.typeToken = TypeTokens.getTypeTokenIfNotRaw(checkNotNull(typeToken, "typeToken")); - this.type = TypeTokens.getRawTypeIfRaw(typeToken); + this((Class<T>)TypeTokens.getRawTypeIfRaw(typeToken), TypeTokens.getTypeTokenIfNotRaw(checkNotNull(typeToken, "typeToken")), + checkNotNull(name, "name"), description); + } + + protected BasicSensor(Class<T> type, TypeToken<T> typeToken, String name, String description) { + TypeTokens.checkCompatibleOneNonNull(type, typeToken); + this.typeToken = typeToken; + this.type = type; this.name = checkNotNull(name, "name"); this.description = description; } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98dfee22/core/src/main/java/org/apache/brooklyn/core/sensor/Sensors.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/Sensors.java b/core/src/main/java/org/apache/brooklyn/core/sensor/Sensors.java index 13bf6f2..2d701b38 100644 --- a/core/src/main/java/org/apache/brooklyn/core/sensor/Sensors.java +++ b/core/src/main/java/org/apache/brooklyn/core/sensor/Sensors.java @@ -54,7 +54,8 @@ public class Sensors { @Beta public static class Builder<T> { private String name; - private TypeToken<T> type; + private Class<T> typeC; + private TypeToken<T> typeT; private String description; private SensorPersistenceMode persistence = SensorPersistenceMode.REQUIRED; @@ -64,10 +65,10 @@ public class Sensors { this.name = checkNotNull(val, "name"); return this; } public Builder<T> type(Class<T> val) { - return type(TypeToken.of(val)); + this.typeC = val; return this; } public Builder<T> type(TypeToken<T> val) { - this.type = checkNotNull(val, "type"); return this; + this.typeT = val; return this; } public Builder<T> description(String val) { this.description = val; return this; @@ -76,7 +77,7 @@ public class Sensors { this.persistence = val; return this; } public AttributeSensor<T> build() { - return new BasicAttributeSensor<T>(type, name, description, persistence); + return new BasicAttributeSensor<T>(typeC, typeT, name, description, persistence); } } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98dfee22/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java b/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java index b37ea33..188f328 100644 --- a/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java +++ b/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java @@ -68,5 +68,19 @@ public class TypeTokens { public static <T> Class<T> getRawRawType(TypeToken<T> token) { return (Class)token.getRawType(); } + + /** Checks that if both type and token are supplied, either exactly one is null, or + * they both refer to the same non-null type */ + public static <T> void checkCompatibleOneNonNull(Class<? super T> type, TypeToken<T> typeToken) { + if ((type==null && typeToken!=null) || (type!=null && typeToken==null)) { + return; + } + if (type==null && typeToken==null) { + throw new NullPointerException("Type not set (neither class or type token)"); + } + if (!type.equals(typeToken.getRawType())) { + throw new NullPointerException("Invalid types, token is "+typeToken+" (raw "+typeToken.getRawType()+") but class is "+type); + } + } }
