diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2017-04-27 12:42:13 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2017-04-27 12:42:13 +0200 |
commit | 8314348966188fb7838baabd4ffaf5f2db8ec8ca (patch) | |
tree | 590cd2c5fd80f4ac70ce1d4f78f90ecdb66d808a /processing/src/main/java/com/yahoo | |
parent | a383bca19847662fe361c1e416d720556813338f (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.java | 60 |
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. */ |