summaryrefslogtreecommitdiffstats
path: root/processing/src/main/java/com/yahoo
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2017-04-27 12:42:13 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2017-04-27 12:42:13 +0200
commit8314348966188fb7838baabd4ffaf5f2db8ec8ca (patch)
tree590cd2c5fd80f4ac70ce1d4f78f90ecdb66d808a /processing/src/main/java/com/yahoo
parenta383bca19847662fe361c1e416d720556813338f (diff)
Support cloning of primitive arrays
Diffstat (limited to 'processing/src/main/java/com/yahoo')
-rw-r--r--processing/src/main/java/com/yahoo/processing/request/CloneHelper.java60
1 files changed, 42 insertions, 18 deletions
diff --git a/processing/src/main/java/com/yahoo/processing/request/CloneHelper.java b/processing/src/main/java/com/yahoo/processing/request/CloneHelper.java
index 8b639855764..bc866c8a538 100644
--- a/processing/src/main/java/com/yahoo/processing/request/CloneHelper.java
+++ b/processing/src/main/java/com/yahoo/processing/request/CloneHelper.java
@@ -24,24 +24,50 @@ import java.util.HashMap;
* The rest has the slow path with reflection,
* though using a fast thread safe method cache for speedup.
*
- * @author : baldersheim
+ * @author bratseth
+ * @author baldersheim
*/
public class CloneHelper {
+
private static Logger log = Logger.getLogger(CloneHelper.class.getName());
private static final MethodCache cloneMethodCache = new MethodCache("clone");
+
/**
* Clones this object if it is clonable, and the clone is public. Returns null if not
*/
public final Object clone(Object object) {
if (object == null) return null;
- if (!(object instanceof Cloneable)) return null;
- if (object instanceof Object[])
- return arrayClone((Object[]) object);
+ if ( ! (object instanceof Cloneable)) return null;
+ if (object.getClass().isArray())
+ return arrayClone(object);
else
return objectClone(object);
}
- private final Object arrayClone(Object[] object) {
+ private Object arrayClone(Object array) {
+ if (array instanceof Object[])
+ return objectArrayClone((Object[]) array);
+ else if (array instanceof byte[])
+ return Arrays.copyOf((byte[])array, ((byte[])array).length);
+ else if (array instanceof char[])
+ return Arrays.copyOf((char[])array, ((char[])array).length);
+ else if (array instanceof short[])
+ return Arrays.copyOf((short[])array, ((short[])array).length);
+ else if (array instanceof int[])
+ return Arrays.copyOf((int[])array, ((int[])array).length);
+ else if (array instanceof long[])
+ return Arrays.copyOf((long[])array, ((long[])array).length);
+ else if (array instanceof float[])
+ return Arrays.copyOf((float[])array, ((float[])array).length);
+ else if (array instanceof double[])
+ return Arrays.copyOf((double[])array, ((double[])array).length);
+ else if (array instanceof boolean[])
+ return Arrays.copyOf((boolean[])array, ((boolean[])array).length);
+ else
+ return new IllegalArgumentException("Unexpected primitive arrat type " + array.getClass());
+ }
+
+ private Object objectArrayClone(Object[] object) {
Object[] arrayClone = Arrays.copyOf(object, object.length);
// deep clone
for (int i = 0; i < arrayClone.length; i++) {
@@ -53,35 +79,33 @@ public class CloneHelper {
}
protected Object objectClone(Object object) {
- // Fastpath for our own commonly used classes
- if (object instanceof FreezableClass) {
- // List common superclass of 'com.yahoo.search.result.Hit'
- return ((FreezableClass) object).clone();
- }
- else if (object instanceof PublicCloneable) {
+ // Fastpath for our commonly used classes
+ if (object instanceof FreezableClass)
+ return ((FreezableClass)object).clone();
+ else if (object instanceof PublicCloneable)
return ((PublicCloneable)object).clone();
- }
- else if (object instanceof LinkedList) { // TODO: Why? Somebody's infatuation with LinkedList knows no limits
+ else if (object instanceof LinkedList)
return ((LinkedList) object).clone();
- }
- else if (object instanceof ArrayList) { // TODO: Why? Likewise
+ else if (object instanceof ArrayList)
return ((ArrayList) object).clone();
- }
try {
Method cloneMethod = cloneMethodCache.get(object);
if (cloneMethod == null) {
- log.warning("'" + object + "' is Cloneable, but has no clone method - will use the same instance in all requests");
+ log.warning("'" + object + "' of class " + object.getClass() +
+ " is Cloneable, but has no clone method - will use the same instance in all requests");
return null;
}
return cloneMethod.invoke(object);
} catch (IllegalAccessException e) {
- log.warning("'" + object + "' is Cloneable, but clone method cannot be accessed - will use the same instance in all requests");
+ log.warning("'" + object + "' of class " + object.getClass() +
+ " is Cloneable, but clone method cannot be accessed - will use the same instance in all requests");
return null;
} catch (InvocationTargetException e) {
throw new RuntimeException("Exception cloning '" + object + "'", e);
}
}
+
/**
* Clones a map by deep cloning each value which is cloneable and shallow copying all other values.
*/