http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a50fccdd/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedClassDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedClassDescriptor.java b/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedClassDescriptor.java deleted file mode 100644 index af15ab8..0000000 --- a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedClassDescriptor.java +++ /dev/null @@ -1,1035 +0,0 @@ -/* @java.file.header */ - -/* _________ _____ __________________ _____ - * __ ____/___________(_)______ /__ ____/______ ____(_)_______ - * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ - * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / - * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ - */ - -package org.gridgain.grid.marshaller.optimized; - -import org.apache.ignite.lang.*; -import org.apache.ignite.marshaller.*; -import org.gridgain.grid.util.*; -import org.gridgain.grid.util.typedef.*; -import sun.misc.*; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -import static java.lang.reflect.Modifier.*; -import static org.gridgain.grid.marshaller.optimized.GridOptimizedClassResolver.*; -import static org.gridgain.grid.marshaller.optimized.GridOptimizedFieldType.*; -import static org.gridgain.grid.marshaller.optimized.GridOptimizedMarshallerUtils.*; - -/** - * Class descriptor. - */ -class GridOptimizedClassDescriptor { - /** Unsafe. */ - private static final Unsafe UNSAFE = GridUnsafe.unsafe(); - - /** */ - private static final int TYPE_BYTE = 1; - - /** */ - private static final int TYPE_SHORT = 2; - - /** */ - private static final int TYPE_INT = 3; - - /** */ - private static final int TYPE_LONG = 4; - - /** */ - private static final int TYPE_FLOAT = 5; - - /** */ - private static final int TYPE_DOUBLE = 6; - - /** */ - private static final int TYPE_CHAR = 7; - - /** */ - private static final int TYPE_BOOLEAN = 8; - - /** */ - private static final int TYPE_BYTE_ARR = 9; - - /** */ - private static final int TYPE_SHORT_ARR = 10; - - /** */ - private static final int TYPE_INT_ARR = 11; - - /** */ - private static final int TYPE_LONG_ARR = 12; - - /** */ - private static final int TYPE_FLOAT_ARR = 13; - - /** */ - private static final int TYPE_DOUBLE_ARR = 14; - - /** */ - private static final int TYPE_CHAR_ARR = 15; - - /** */ - private static final int TYPE_BOOLEAN_ARR = 16; - - /** */ - private static final int TYPE_OBJ_ARR = 17; - - /** */ - private static final int TYPE_STR = 18; - - /** */ - private static final int TYPE_ENUM = 19; - - /** */ - private static final int TYPE_UUID = 20; - - /** */ - private static final int TYPE_PROPS = 21; - - /** */ - private static final int TYPE_ARRAY_LIST = 22; - - /** */ - private static final int TYPE_HASH_MAP = 23; - - /** */ - private static final int TYPE_HASH_SET = 24; - - /** */ - private static final int TYPE_LINKED_LIST = 25; - - /** */ - private static final int TYPE_LINKED_HASH_MAP = 26; - - /** */ - private static final int TYPE_LINKED_HASH_SET = 27; - - /** */ - private static final int TYPE_DATE = 28; - - /** */ - private static final int TYPE_CLS = 29; - - /** */ - private static final int TYPE_EXTERNALIZABLE = 50; - - /** */ - private static final int TYPE_SERIALIZABLE = 51; - - /** Class. */ - private Class<?> cls; - - /** Header. */ - private Integer hdr; - - /** ID. */ - private Integer id; - - /** Short ID. */ - private Short shortId; - - /** Class name. */ - private String name; - - /** Class type. */ - private int type; - - /** Primitive flag. */ - private boolean isPrimitive; - - /** Enum flag. */ - private boolean isEnum; - - /** Serializable flag. */ - private boolean isSerial; - - /** Excluded flag. */ - private final boolean excluded; - - /** {@code True} if descriptor is for {@link Class}. */ - private boolean isCls; - - /** Array component type. */ - private Class<?> arrCompType; - - /** Enumeration values. */ - private Object[] enumVals; - - /** Constructor. */ - private Constructor<?> constructor; - - /** Fields. */ - private Fields fields; - - /** {@code writeObject} methods. */ - private List<Method> writeObjMtds; - - /** {@code writeReplace} method. */ - private Method writeReplaceMtd; - - /** {@code readObject} methods. */ - private List<Method> readObjMtds; - - /** {@code readResolve} method. */ - private Method readResolveMtd; - - /** Defaults field offset. */ - private long dfltsFieldOff; - - /** Load factor field offset. */ - private long loadFactorFieldOff; - - /** Map field offset. */ - private long mapFieldOff; - - /** Access order field offset. */ - private long accessOrderFieldOff; - - /** - * Creates descriptor for class. - * - * @param cls Class. - * @throws IOException In case of error. - */ - @SuppressWarnings({"ForLoopReplaceableByForEach", "MapReplaceableByEnumMap"}) - GridOptimizedClassDescriptor(Class<?> cls) throws IOException { - this.cls = cls; - - excluded = GridMarshallerExclusions.isExcluded(cls); - - T2<Integer, Integer> t = GridOptimizedClassResolver.writeClassData(cls); - - hdr = t.get1(); - id = t.get2(); - name = cls.getName(); - - if (!excluded) { - Class<?> parent; - - if (cls == byte.class || cls == Byte.class) { - type = TYPE_BYTE; - - isPrimitive = true; - } - else if (cls == short.class || cls == Short.class) { - type = TYPE_SHORT; - - isPrimitive = true; - } - else if (cls == int.class || cls == Integer.class) { - type = TYPE_INT; - - isPrimitive = true; - } - else if (cls == long.class || cls == Long.class) { - type = TYPE_LONG; - - isPrimitive = true; - } - else if (cls == float.class || cls == Float.class) { - type = TYPE_FLOAT; - - isPrimitive = true; - } - else if (cls == double.class || cls == Double.class) { - type = TYPE_DOUBLE; - - isPrimitive = true; - } - else if (cls == char.class || cls == Character.class) { - type = TYPE_CHAR; - - isPrimitive = true; - } - else if (cls == boolean.class || cls == Boolean.class) { - type = TYPE_BOOLEAN; - - isPrimitive = true; - } - else if (cls == byte[].class) - type = TYPE_BYTE_ARR; - else if (cls == short[].class) - type = TYPE_SHORT_ARR; - else if (cls == int[].class) - type = TYPE_INT_ARR; - else if (cls == long[].class) - type = TYPE_LONG_ARR; - else if (cls == float[].class) - type = TYPE_FLOAT_ARR; - else if (cls == double[].class) - type = TYPE_DOUBLE_ARR; - else if (cls == char[].class) - type = TYPE_CHAR_ARR; - else if (cls == boolean[].class) - type = TYPE_BOOLEAN_ARR; - else if (cls.isArray()) { - type = TYPE_OBJ_ARR; - - arrCompType = cls.getComponentType(); - } - else if (cls == String.class) - type = TYPE_STR; - else if (cls.isEnum()) { - type = TYPE_ENUM; - - isEnum = true; - enumVals = cls.getEnumConstants(); - } - // Support for enum constants, based on anonymous children classes. - else if ((parent = cls.getSuperclass()) != null && parent.isEnum()) { - type = TYPE_ENUM; - - isEnum = true; - enumVals = parent.getEnumConstants(); - } - else if (cls == UUID.class) - type = TYPE_UUID; - else if (cls == Properties.class) { - type = TYPE_PROPS; - - try { - dfltsFieldOff = UNSAFE.objectFieldOffset(Properties.class.getDeclaredField("defaults")); - } - catch (NoSuchFieldException e) { - throw new IOException(e); - } - } - else if (cls == ArrayList.class) - type = TYPE_ARRAY_LIST; - else if (cls == HashMap.class) { - type = TYPE_HASH_MAP; - - try { - loadFactorFieldOff = UNSAFE.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor")); - } - catch (NoSuchFieldException e) { - throw new IOException(e); - } - } - else if (cls == HashSet.class) { - type = TYPE_HASH_SET; - - try { - loadFactorFieldOff = UNSAFE.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor")); - mapFieldOff = UNSAFE.objectFieldOffset(HashSet.class.getDeclaredField("map")); - } - catch (NoSuchFieldException e) { - throw new IOException(e); - } - } - else if (cls == LinkedList.class) - type = TYPE_LINKED_LIST; - else if (cls == LinkedHashMap.class) { - type = TYPE_LINKED_HASH_MAP; - - try { - loadFactorFieldOff = UNSAFE.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor")); - accessOrderFieldOff = UNSAFE.objectFieldOffset(LinkedHashMap.class.getDeclaredField("accessOrder")); - } - catch (NoSuchFieldException e) { - throw new IOException(e); - } - } - else if (cls == LinkedHashSet.class) { - type = TYPE_LINKED_HASH_SET; - - try { - loadFactorFieldOff = UNSAFE.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor")); - mapFieldOff = UNSAFE.objectFieldOffset(HashSet.class.getDeclaredField("map")); - } - catch (NoSuchFieldException e) { - throw new IOException(e); - } - } - else if (cls == Date.class) - type = TYPE_DATE; - else if (cls == Class.class) { - type = TYPE_CLS; - - isCls = true; - } - else { - Class<?> c = cls; - - while ((writeReplaceMtd == null || readResolveMtd == null) && c != null && !c.equals(Object.class)) { - if (writeReplaceMtd == null) { - try { - writeReplaceMtd = c.getDeclaredMethod("writeReplace"); - - if (!isStatic(writeReplaceMtd.getModifiers()) && - !(isPrivate(writeReplaceMtd.getModifiers()) && c != cls) && - writeReplaceMtd.getReturnType().equals(Object.class)) - writeReplaceMtd.setAccessible(true); - else - // Set method back to null if it has incorrect signature. - writeReplaceMtd = null; - } - catch (NoSuchMethodException ignored) { - // No-op. - } - } - - if (readResolveMtd == null) { - try { - readResolveMtd = c.getDeclaredMethod("readResolve"); - - if (!isStatic(readResolveMtd.getModifiers()) && - !(isPrivate(readResolveMtd.getModifiers()) && c != cls) && - readResolveMtd.getReturnType().equals(Object.class)) - readResolveMtd.setAccessible(true); - else - // Set method back to null if it has incorrect signature. - readResolveMtd = null; - } - catch (NoSuchMethodException ignored) { - // No-op. - } - } - - c = c.getSuperclass(); - } - - if (Externalizable.class.isAssignableFrom(cls)) { - type = TYPE_EXTERNALIZABLE; - - try { - constructor = cls.getDeclaredConstructor(); - - constructor.setAccessible(true); - } - catch (NoSuchMethodException e) { - throw new IOException("Externalizable class doesn't have default constructor: " + cls, e); - } - } - else { - type = TYPE_SERIALIZABLE; - - isSerial = Serializable.class.isAssignableFrom(cls); - - writeObjMtds = new ArrayList<>(); - readObjMtds = new ArrayList<>(); - List<List<Field>> fields = new ArrayList<>(); - List<List<T2<GridOptimizedFieldType, Long>>> fieldOffs = new ArrayList<>(); - List<Map<String, IgniteBiTuple<Integer, GridOptimizedFieldType>>> fieldInfoMaps = new ArrayList<>(); - List<List<IgniteBiTuple<Integer, GridOptimizedFieldType>>> fieldInfoLists = new ArrayList<>(); - - for (c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) { - Method mtd; - - try { - mtd = c.getDeclaredMethod("writeObject", ObjectOutputStream.class); - - int mod = mtd.getModifiers(); - - if (!isStatic(mod) && isPrivate(mod) && mtd.getReturnType() == Void.TYPE) - mtd.setAccessible(true); - else - // Set method back to null if it has incorrect signature. - mtd = null; - } - catch (NoSuchMethodException ignored) { - mtd = null; - } - - writeObjMtds.add(mtd); - - try { - mtd = c.getDeclaredMethod("readObject", ObjectInputStream.class); - - int mod = mtd.getModifiers(); - - if (!isStatic(mod) && isPrivate(mod) && mtd.getReturnType() == Void.TYPE) - mtd.setAccessible(true); - else - // Set method back to null if it has incorrect signature. - mtd = null; - } - catch (NoSuchMethodException ignored) { - mtd = null; - } - - readObjMtds.add(mtd); - - Field[] clsFields0 = c.getDeclaredFields(); - - Arrays.sort(clsFields0, new Comparator<Field>() { - @Override public int compare(Field f1, Field f2) { - return f1.getName().compareTo(f2.getName()); - } - }); - - List<Field> clsFields = new ArrayList<>(clsFields0.length); - List<T2<GridOptimizedFieldType, Long>> clsFieldOffs = - new ArrayList<>(clsFields0.length); - - for (int i = 0; i < clsFields0.length; i++) { - Field f = clsFields0[i]; - - int mod = f.getModifiers(); - - if (!isStatic(mod) && !isTransient(mod)) { - GridOptimizedFieldType type = fieldType(f.getType()); - - clsFields.add(f); - clsFieldOffs.add(new T2<>(type, UNSAFE.objectFieldOffset(f))); - } - } - - fields.add(clsFields); - fieldOffs.add(clsFieldOffs); - - Map<String, IgniteBiTuple<Integer, GridOptimizedFieldType>> fieldInfoMap = null; - - try { - Field serFieldsDesc = c.getDeclaredField("serialPersistentFields"); - - int mod = serFieldsDesc.getModifiers(); - - if (serFieldsDesc.getType() == ObjectStreamField[].class && - isPrivate(mod) && isStatic(mod) && isFinal(mod)) { - serFieldsDesc.setAccessible(true); - - ObjectStreamField[] serFields = (ObjectStreamField[])serFieldsDesc.get(null); - - fieldInfoMap = new HashMap<>(); - - for (int i = 0; i < serFields.length; i++) { - ObjectStreamField serField = serFields[i]; - - fieldInfoMap.put(serField.getName(), F.t(i, fieldType(serField.getType()))); - } - } - } - catch (NoSuchFieldException ignored) { - // No-op. - } - catch (IllegalAccessException e) { - throw new IOException("Failed to get value of 'serialPersistentFields' field in class: " + - cls.getName(), e); - } - - if (fieldInfoMap == null) { - fieldInfoMap = new HashMap<>(); - - for (int i = 0; i < clsFields.size(); i++) { - Field f = clsFields.get(i); - - fieldInfoMap.put(f.getName(), F.t(i, fieldType(f.getType()))); - } - } - - fieldInfoMaps.add(fieldInfoMap); - - List<IgniteBiTuple<Integer, GridOptimizedFieldType>> fieldInfoList = - new ArrayList<>(fieldInfoMap.values()); - - Collections.sort(fieldInfoList, new Comparator<IgniteBiTuple<Integer, GridOptimizedFieldType>>() { - @Override public int compare(IgniteBiTuple<Integer, GridOptimizedFieldType> t1, - IgniteBiTuple<Integer, GridOptimizedFieldType> t2) { - return t1.get1().compareTo(t2.get1()); - } - }); - - fieldInfoLists.add(fieldInfoList); - } - - Collections.reverse(writeObjMtds); - Collections.reverse(readObjMtds); - Collections.reverse(fields); - Collections.reverse(fieldOffs); - Collections.reverse(fieldInfoMaps); - Collections.reverse(fieldInfoLists); - - this.fields = new Fields(fields, fieldOffs, fieldInfoLists, fieldInfoMaps); - } - } - } - - shortId = computeSerialVersionUid(cls, fields != null ? fields.ownFields() : null).shortValue(); - } - - /** - * @return Excluded flag. - */ - boolean excluded() { - return excluded; - } - - /** - * @return Class. - */ - Class<?> describedClass() { - return cls; - } - - /** - * @return Header. - */ - Integer header() { - return hdr; - } - - /** - * @return ID. - */ - Integer id() { - return id; - } - - /** - * @return Short ID. - */ - Short shortId() { - return shortId; - } - - /** - * @return Class name. - */ - String name() { - return name; - } - - /** - * @return Array component type. - */ - Class<?> componentType() { - return arrCompType; - } - - /** - * @return Primitive flag. - */ - boolean isPrimitive() { - return isPrimitive; - } - - /** - * @return Enum flag. - */ - boolean isEnum() { - return isEnum; - } - - /** - * @return {@code True} if descriptor is for {@link Class}. - */ - boolean isClass() { - return isCls; - } - - /** - * Replaces object. - * - * @param obj Object. - * @return Replaced object or {@code null} if there is no {@code writeReplace} method. - * @throws IOException In case of error. - */ - Object replace(Object obj) throws IOException { - if (writeReplaceMtd != null) { - try { - return writeReplaceMtd.invoke(obj); - } - catch (IllegalAccessException | InvocationTargetException e) { - throw new IOException(e); - } - } - - return obj; - } - - /** - * Writes object to stream. - * - * @param out Output stream. - * @param obj Object. - * @throws IOException In case of error. - */ - @SuppressWarnings("ForLoopReplaceableByForEach") - void write(GridOptimizedObjectOutputStream out, Object obj) throws IOException { - switch (type) { - case TYPE_BYTE: - out.writeByte((Byte)obj); - - break; - - case TYPE_SHORT: - out.writeShort((Short)obj); - - break; - - case TYPE_INT: - out.writeInt((Integer)obj); - - break; - - case TYPE_LONG: - out.writeLong((Long)obj); - - break; - - case TYPE_FLOAT: - out.writeFloat((Float)obj); - - break; - - case TYPE_DOUBLE: - out.writeDouble((Double)obj); - - break; - - case TYPE_CHAR: - out.writeChar((Character)obj); - - break; - - case TYPE_BOOLEAN: - out.writeBoolean((Boolean)obj); - - break; - - case TYPE_BYTE_ARR: - out.writeByteArray((byte[])obj); - - break; - - case TYPE_SHORT_ARR: - out.writeShortArray((short[])obj); - - break; - - case TYPE_INT_ARR: - out.writeIntArray((int[])obj); - - break; - - case TYPE_LONG_ARR: - out.writeLongArray((long[])obj); - - break; - - case TYPE_FLOAT_ARR: - out.writeFloatArray((float[])obj); - - break; - - case TYPE_DOUBLE_ARR: - out.writeDoubleArray((double[])obj); - - break; - - case TYPE_CHAR_ARR: - out.writeCharArray((char[])obj); - - break; - - case TYPE_BOOLEAN_ARR: - out.writeBooleanArray((boolean[])obj); - - break; - - case TYPE_OBJ_ARR: - out.writeArray((Object[])obj); - - break; - - case TYPE_STR: - out.writeString((String)obj); - - break; - - case TYPE_ENUM: - out.writeInt(((Enum)obj).ordinal()); - - break; - - case TYPE_UUID: - out.writeUuid((UUID)obj); - - break; - - case TYPE_PROPS: - out.writeProperties((Properties)obj, dfltsFieldOff); - - break; - - case TYPE_ARRAY_LIST: - out.writeArrayList((ArrayList<?>)obj); - - break; - - case TYPE_HASH_MAP: - out.writeHashMap((HashMap<?, ?>)obj, loadFactorFieldOff, false); - - break; - - case TYPE_HASH_SET: - out.writeHashSet((HashSet<?>)obj, mapFieldOff, loadFactorFieldOff); - - break; - - case TYPE_LINKED_LIST: - out.writeLinkedList((LinkedList<?>)obj); - - break; - - case TYPE_LINKED_HASH_MAP: - out.writeLinkedHashMap((LinkedHashMap<?, ?>)obj, loadFactorFieldOff, accessOrderFieldOff, false); - - break; - - case TYPE_LINKED_HASH_SET: - out.writeLinkedHashSet((LinkedHashSet<?>)obj, mapFieldOff, loadFactorFieldOff); - - break; - - case TYPE_DATE: - out.writeDate((Date)obj); - - break; - - case TYPE_CLS: - writeClass(out, classDescriptor((Class<?>)obj, obj)); - - break; - - case TYPE_EXTERNALIZABLE: - out.writeExternalizable(obj); - - break; - - case TYPE_SERIALIZABLE: - if (out.requireSerializable() && !isSerial) - throw new NotSerializableException("Must implement java.io.Serializable or " + - "set GridOptimizedMarshaller.setRequireSerializable() to false " + - "(note that performance may degrade if object is not Serializable): " + name); - - out.writeSerializable(obj, writeObjMtds, fields); - - break; - - default: - throw new IllegalStateException("Invalid class type: " + type); - } - } - - /** - * Reads object from stream. - * - * @param in Input stream. - * @return Object. - * @throws ClassNotFoundException If class not found. - * @throws IOException In case of error. - */ - Object read(GridOptimizedObjectInputStream in) throws ClassNotFoundException, IOException { - switch (type) { - case TYPE_BYTE: - return in.readByte(); - - case TYPE_SHORT: - return in.readShort(); - - case TYPE_INT: - return in.readInt(); - - case TYPE_LONG: - return in.readLong(); - - case TYPE_FLOAT: - return in.readFloat(); - - case TYPE_DOUBLE: - return in.readDouble(); - - case TYPE_CHAR: - return in.readChar(); - - case TYPE_BOOLEAN: - return in.readBoolean(); - - case TYPE_BYTE_ARR: - return in.readByteArray(); - - case TYPE_SHORT_ARR: - return in.readShortArray(); - - case TYPE_INT_ARR: - return in.readIntArray(); - - case TYPE_LONG_ARR: - return in.readLongArray(); - - case TYPE_FLOAT_ARR: - return in.readFloatArray(); - - case TYPE_DOUBLE_ARR: - return in.readDoubleArray(); - - case TYPE_CHAR_ARR: - return in.readCharArray(); - - case TYPE_BOOLEAN_ARR: - return in.readBooleanArray(); - - case TYPE_OBJ_ARR: - return in.readArray(arrCompType); - - case TYPE_STR: - return in.readString(); - - case TYPE_ENUM: - return enumVals[in.readInt()]; - - case TYPE_UUID: - return in.readUuid(); - - case TYPE_PROPS: - return in.readProperties(); - - case TYPE_ARRAY_LIST: - return in.readArrayList(); - - case TYPE_HASH_MAP: - return in.readHashMap(false); - - case TYPE_HASH_SET: - return in.readHashSet(mapFieldOff); - - case TYPE_LINKED_LIST: - return in.readLinkedList(); - - case TYPE_LINKED_HASH_MAP: - return in.readLinkedHashMap(false); - - case TYPE_LINKED_HASH_SET: - return in.readLinkedHashSet(mapFieldOff); - - case TYPE_DATE: - return in.readDate(); - - case TYPE_CLS: - return readClass(in, in.classLoader()).describedClass(); - - case TYPE_EXTERNALIZABLE: - return in.readExternalizable(constructor, readResolveMtd); - - case TYPE_SERIALIZABLE: - return in.readSerializable(cls, readObjMtds, readResolveMtd, fields); - - default: - throw new IllegalStateException("Invalid class type: " + type); - } - } - - /** - * @param cls Class. - * @return Type. - */ - @SuppressWarnings("IfMayBeConditional") - private GridOptimizedFieldType fieldType(Class<?> cls) { - GridOptimizedFieldType type; - - if (cls == byte.class) - type = BYTE; - else if (cls == short.class) - type = SHORT; - else if (cls == int.class) - type = INT; - else if (cls == long.class) - type = LONG; - else if (cls == float.class) - type = FLOAT; - else if (cls == double.class) - type = DOUBLE; - else if (cls == char.class) - type = CHAR; - else if (cls == boolean.class) - type = BOOLEAN; - else - type = OTHER; - - return type; - } - - /** - * Encapsulates data about class fields. - */ - @SuppressWarnings("PackageVisibleInnerClass") - static class Fields { - /** Fields. */ - private final List<List<Field>> fields; - - /** Fields offsets. */ - private final List<List<T2<GridOptimizedFieldType, Long>>> fieldOffs; - - /** Fields details lists. */ - private final List<List<IgniteBiTuple<Integer, GridOptimizedFieldType>>> fieldInfoLists; - - /** Fields details maps. */ - private final List<Map<String, IgniteBiTuple<Integer, GridOptimizedFieldType>>> fieldInfoMaps; - - /** - * Creates new instance. - * - * @param fields Fields. - * @param fieldOffs Field offsets. - * @param fieldInfoLists List of field details sequences for each type in the object's class hierarchy. - * @param fieldInfoMaps List of field details maps for each type in the object's class hierarchy. - */ - Fields(List<List<Field>> fields, List<List<T2<GridOptimizedFieldType, Long>>> fieldOffs, - List<List<IgniteBiTuple<Integer, GridOptimizedFieldType>>> fieldInfoLists, - List<Map<String, IgniteBiTuple<Integer, GridOptimizedFieldType>>> fieldInfoMaps) { - this.fields = fields; - this.fieldOffs = fieldOffs; - this.fieldInfoLists = fieldInfoLists; - this.fieldInfoMaps = fieldInfoMaps; - } - - /** - * Returns class's own fields (excluding inherited). - * - * @return List of fields or {@code null} if fields list is empty. - */ - List<Field> ownFields() { - return fields.isEmpty() ? null : fields.get(fields.size() - 1); - } - - /** - * Returns field types and their offsets. - * - * @param i hierarchy level where 0 corresponds to top level. - * @return list of pairs where first value is field type and second value is its offset. - */ - List<T2<GridOptimizedFieldType, Long>> fieldOffs(int i) { - return fieldOffs.get(i); - } - - /** - * Returns field sequence numbers and their types as list. - * - * @param i hierarchy level where 0 corresponds to top level. - * @return list of pairs (field number, field type) for the given hierarchy level. - */ - List<IgniteBiTuple<Integer, GridOptimizedFieldType>> fieldInfoList(int i) { - return fieldInfoLists.get(i); - } - - /** - * Returns field sequence numbers and their types as map where key is a field name, - * - * @param i hierarchy level where 0 corresponds to top level. - * @return map of field names and their details. - */ - Map<String, IgniteBiTuple<Integer, GridOptimizedFieldType>> fieldInfoMap(int i) { - return fieldInfoMaps.get(i); - } - } -}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a50fccdd/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedClassResolver.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedClassResolver.java b/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedClassResolver.java deleted file mode 100644 index 17540da..0000000 --- a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedClassResolver.java +++ /dev/null @@ -1,471 +0,0 @@ -/* @java.file.header */ - -/* _________ _____ __________________ _____ - * __ ____/___________(_)______ /__ ____/______ ____(_)_______ - * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ - * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / - * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ - */ - -package org.gridgain.grid.marshaller.optimized; - -import org.apache.ignite.lang.*; -import org.gridgain.grid.util.*; -import org.gridgain.grid.util.typedef.*; -import org.gridgain.grid.util.typedef.internal.*; -import org.jdk8.backport.*; -import org.jetbrains.annotations.*; - -import java.io.*; -import java.math.*; -import java.sql.*; -import java.util.*; -import java.util.Date; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.concurrent.locks.*; - -import static org.gridgain.grid.marshaller.optimized.GridOptimizedMarshallerUtils.*; - -/** - * Resolves class names by serialVersionUID. - */ -@SuppressWarnings({"UnnecessaryFullyQualifiedName", "unchecked"}) -class GridOptimizedClassResolver { - /** File name to generate. */ - private static final String FILE_NAME = "optimized-classnames.properties"; - - /** */ - private static final Map<String, Integer> ggxName2id = new HashMap<>(); - - /** */ - private static final T2<Class<?>, GridOptimizedClassDescriptor>[] ggxId2name; - - /** */ - private static final Map<String, Integer> ggName2id = new HashMap<>(); - - /** */ - private static final T3<String, Class<?>, GridOptimizedClassDescriptor>[] ggId2name; - - /** */ - private static Map<String, Integer> usrName2Id; - - /** */ - private static T3<String, Class<?>, GridOptimizedClassDescriptor>[] usrId2Name; - - /** */ - private static final int HEADER_NAME = 255; - - /** */ - private static final int HEADER_GG_NAME = 254; - - /** */ - private static final int HEADER_USER_NAME = 253; - - /** */ - private static final int HEADER_ARRAY = 252; - - /** - * Initialize predefined classes to optimize. - */ - static { - Class[] superOptCls = new Class[] { - // Array types. - byte[].class, - short[].class, - int[].class, - long[].class, - float[].class, - double[].class, - boolean[].class, - char[].class, - - // Boxed types. - Byte.class, - Short.class, - Integer.class, - Long.class, - Float.class, - Double.class, - Boolean.class, - Character.class, - String.class, - - // Atomic. - AtomicBoolean.class,AtomicInteger.class, - AtomicLong.class,AtomicReference.class, - AtomicMarkableReference.class, - AtomicStampedReference.class, - AtomicIntegerArray.class, - AtomicReferenceArray.class, - - // Concurrent types. - ConcurrentHashMap.class, - ConcurrentLinkedQueue.class, - ConcurrentSkipListMap.class, - ConcurrentSkipListSet.class, - LinkedBlockingDeque.class, - LinkedBlockingQueue.class, - PriorityBlockingQueue.class, - CopyOnWriteArrayList.class, - CopyOnWriteArraySet.class, - - // Locks. - ReentrantLock.class, - ReentrantReadWriteLock.class, - ReentrantReadWriteLock.ReadLock.class, - ReentrantReadWriteLock.WriteLock.class, - - // Util types. - Date.class, - UUID.class, - Calendar.class, - Random.class, - Calendar.class, - Currency.class, - ArrayList.class, - LinkedList.class, - Stack.class, - Vector.class, - HashMap.class, - HashSet.class, - Hashtable.class, - TreeMap.class, - TreeSet.class, - IdentityHashMap.class, - LinkedHashMap.class, - LinkedHashSet.class, - ArrayDeque.class, - BitSet.class, - EnumMap.class, - EnumSet.class, - - // SQL types. - java.sql.Date.class, - Time.class, - Timestamp.class, - - // Math types. - BigDecimal.class, - BigInteger.class, - - // GridGain types. - IgniteUuid.class, - GridBoundedConcurrentOrderedSet.class, - GridBoundedLinkedHashSet.class, - GridConcurrentHashSet.class, - ConcurrentLinkedDeque8.class, - GridConcurrentPhantomHashSet.class, - GridConcurrentSkipListSet.class, - GridConcurrentWeakHashSet.class, - GridIdentityHashSet.class, - GridLeanSet.class, - GridSetWrapper.class - }; - - // Have to leave a range for special purposes. - assert superOptCls.length < 230; - - ggxId2name = new T2[superOptCls.length]; - - for (int i = 0; i < superOptCls.length; i++) { - Class cls = superOptCls[i]; - - ggxName2id.put(cls.getName(), i); - ggxId2name[i] = new T2<Class<?>, GridOptimizedClassDescriptor>(cls, null); - } - - BufferedReader reader = new BufferedReader(new InputStreamReader( - GridOptimizedClassResolver.class.getResourceAsStream(FILE_NAME), - GridOptimizedMarshallerUtils.UTF_8)); - - List<T3<String, Class<?>, GridOptimizedClassDescriptor>> ggId2name0 = - new LinkedList<>(); - - try { - for (int i = 0; ; i++) { - String clsName = reader.readLine(); - - if (clsName == null) - break; - - ggName2id.put(clsName, i); - ggId2name0.add(new T3<String, Class<?>, GridOptimizedClassDescriptor>(clsName, null, null)); - } - - ggId2name = ggId2name0.toArray(new T3[ggId2name0.size()]); - } - catch (IOException e) { - throw new AssertionError(e); - } - finally { - U.close(reader, null); - } - } - - /** - * Ensure singleton. - */ - private GridOptimizedClassResolver() { - // No-op. - } - - /** - * @param usrName2id0 From name to ID. - * @param usrId2Name0 From ID to name. - */ - static void userClasses(@Nullable Map<String, Integer> usrName2id0, - @Nullable T3<String, Class<?>, GridOptimizedClassDescriptor>[] usrId2Name0) { - usrName2Id = usrName2id0; - usrId2Name = usrId2Name0; - } - - /** - * @param in DataInput to read from. - * @param clsLdr ClassLoader. - * @return Class descriptor. - * @throws IOException If serial version UID failed. - * @throws ClassNotFoundException If the class cannot be located by the specified class loader. - */ - static GridOptimizedClassDescriptor readClass(DataInput in, ClassLoader clsLdr) - throws IOException, ClassNotFoundException { - assert in != null; - assert clsLdr != null; - - int hdr = in.readByte() & 0xff; - - if (hdr < ggxId2name.length) { - T2<Class<?>, GridOptimizedClassDescriptor> ggxT = ggxId2name[hdr]; - - GridOptimizedClassDescriptor desc = ggxT.get2(); - - if (desc == null) { - desc = classDescriptor(ggxT.get1(), null); - - ggxT.set2(desc); - } - - return desc; - } - - String name; - Class<?> cls; - GridOptimizedClassDescriptor desc; - - switch (hdr) { - case HEADER_GG_NAME: - int ggId = in.readInt(); - - T3<String, Class<?>, GridOptimizedClassDescriptor> ggT; - - try { - ggT = ggId2name[ggId]; - } - catch (ArrayIndexOutOfBoundsException e) { - throw new ClassNotFoundException("Failed to find optimized class ID " + - "(is same GridGain version running on all nodes?): " + ggId, e); - } - - name = ggT.get1(); - cls = ggT.get2(); - desc = ggT.get3(); - - if (desc == null) { - if (clsLdr == U.gridClassLoader()) { - if (cls == null) { - cls = forName(name, clsLdr); - - ggT.set2(cls); - } - - desc = classDescriptor(cls, null); - - ggT.set3(desc); - } - else { - cls = forName(name, clsLdr); - - desc = classDescriptor(cls, null); - } - } - - break; - - case HEADER_USER_NAME: - int usrId = in.readInt(); - - T3<String, Class<?>, GridOptimizedClassDescriptor> usrT; - - try { - if (usrId2Name != null) - usrT = usrId2Name[usrId]; - else - throw new ClassNotFoundException("Failed to find user defined class ID " + - "(make sure to register identical classes on all nodes for optimization): " + usrId); - } - catch (ArrayIndexOutOfBoundsException e) { - throw new ClassNotFoundException("Failed to find user defined class ID " + - "(make sure to register identical classes on all nodes for optimization): " + usrId, e); - } - - name = usrT.get1(); - cls = usrT.get2(); - desc = usrT.get3(); - - if (desc == null) { - if (cls == null) { - cls = forName(name, clsLdr); - - usrT.set2(cls); - } - - desc = classDescriptor(cls, null); - - usrT.set3(desc); - } - - break; - - case HEADER_ARRAY: - name = readClass(in, clsLdr).name(); - - name = name.charAt(0) == '[' ? "[" + name : "[L" + name + ';'; - - cls = forName(name, clsLdr); - - return classDescriptor(cls, null); - - case HEADER_NAME: - name = in.readUTF(); - - cls = forName(name, clsLdr); - - desc = classDescriptor(cls, null); - - break; - - default: - throw new IOException("Unexpected optimized stream header: " + hdr); - } - - short actual = desc.shortId(); - - short exp = in.readShort(); - - if (actual != exp) - throw new ClassNotFoundException("Optimized stream class checksum mismatch " + - "(is same version of marshalled class present on all nodes?) " + - "[expected=" + exp + ", actual=" + actual + ", cls=" + cls + ']'); - - return desc; - } - - /** - * @param out Output. - * @param desc Class descriptor. - * @throws IOException In case of error. - */ - static void writeClass(DataOutput out, GridOptimizedClassDescriptor desc) throws IOException { - assert out != null; - assert desc != null; - - int hdr = desc.header(); - - out.writeByte(hdr); - - switch (hdr) { - case HEADER_GG_NAME: - case HEADER_USER_NAME: - out.writeInt(desc.id()); - out.writeShort(desc.shortId()); - - return; - - case HEADER_ARRAY: - writeClass(out, classDescriptor(desc.componentType(), null)); - - return; - - case HEADER_NAME: - out.writeUTF(desc.name()); - out.writeShort(desc.shortId()); - } - } - - /** - * @param cls Class to write. - * @return Data for {@code writeClass} method. - */ - static T2<Integer, Integer> writeClassData(Class<?> cls) { - assert cls != null; - - String name = cls.getName(); - - Integer superHdr = ggxName2id.get(name); - - if (superHdr != null) - return new T2<>(superHdr, null); - - Integer id; - - if ((id = ggName2id.get(name)) != null) - return new T2<>(HEADER_GG_NAME, id); - - if (usrName2Id != null && (id = usrName2Id.get(name)) != null) - return new T2<>(HEADER_USER_NAME, id); - - if (cls.isArray()) - return new T2<>(HEADER_ARRAY, null); - - return new T2<>(HEADER_NAME, null); - } - - /** - * @param name Class name. - * @param ldr Class loader. - * @return Class. - * @throws ClassNotFoundException If class not found. - */ - private static Class<?> forName(String name, ClassLoader ldr) throws ClassNotFoundException { - Class<?> cls = primitive(name); - - if (cls == null) - cls = GridOptimizedMarshallerUtils.forName(name, ldr); - - return cls; - } - - /** - * @param name Name of primitive class. - * @return Primitive type class or null. - */ - @SuppressWarnings("TypeMayBeWeakened") - @Nullable private static Class<?> primitive(String name) { - if (name.length() > 7) - return null; - - switch (name.charAt(0)) { - case 'b': - if ("boolean".equals(name)) - return boolean.class; - - return "byte".equals(name) ? byte.class : null; - case 's': - return "short".equals(name) ? short.class : null; - case 'i': - return "int".equals(name) ? int.class : null; - case 'l': - return "long".equals(name) ? long.class : null; - case 'c': - return "char".equals(name) ? char.class : null; - case 'f': - return "float".equals(name) ? float.class : null; - case 'd': - return "double".equals(name) ? double.class : null; - case 'v': - return "void".equals(name) ? void.class : null; - } - - return null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a50fccdd/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedFieldType.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedFieldType.java b/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedFieldType.java deleted file mode 100644 index 7ba8550..0000000 --- a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedFieldType.java +++ /dev/null @@ -1,42 +0,0 @@ -/* @java.file.header */ - -/* _________ _____ __________________ _____ - * __ ____/___________(_)______ /__ ____/______ ____(_)_______ - * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ - * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / - * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ - */ - -package org.gridgain.grid.marshaller.optimized; - -/** - * Field type used to calculate {@code Unsafe} offsets into objects. - */ -enum GridOptimizedFieldType { - /** */ - BYTE, - - /** */ - SHORT, - - /** */ - INT, - - /** */ - LONG, - - /** */ - FLOAT, - - /** */ - DOUBLE, - - /** */ - CHAR, - - /** */ - BOOLEAN, - - /** */ - OTHER -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a50fccdd/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshallable.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshallable.java b/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshallable.java deleted file mode 100644 index 3137830..0000000 --- a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshallable.java +++ /dev/null @@ -1,57 +0,0 @@ -/* @java.file.header */ - -/* _________ _____ __________________ _____ - * __ ____/___________(_)______ /__ ____/______ ____(_)_______ - * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ - * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / - * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ - */ - -package org.gridgain.grid.marshaller.optimized; - -import java.util.*; - -/** - * Optional interface which helps make serialization even faster by removing internal - * look-ups for classes. - * <p> - * All implementation must have the following: - * <ul> - * <li> - * Must have static filed (private or public) declared of type {@link Object} - * with name {@code GG_CLASS_ID}. GridGain will reflectively initialize this field with - * proper class ID during system startup. - * </li> - * <li> - * Must return the value of {@code GG_CLASS_ID} field from {@link #ggClassId} method. - * </li> - * </ul> - * Here is a sample implementation: - * <pre name="code" class="java"> - * // For better performance consider implementing java.io.Externalizable interface. - * class ExampleMarshallable implements GridOptimizedMarshallable, Serializable { - * // Class ID field required by 'GridOptimizedMarshallable'. - * private static Object GG_CLASS_ID; - * - * ... - * - * @ public Object ggClassId() { - * return GG_CLASS_ID; - * } - * } - * </pre> - * <p> - * Note that for better performance you should also specify list of classes you - * plan to serialize via {@link GridOptimizedMarshaller#setClassNames(List)} method. - */ -public interface GridOptimizedMarshallable { - /** */ - public static final String CLS_ID_FIELD_NAME = "GG_CLASS_ID"; - - /** - * Implementation of this method should simply return value of {@code GG_CLASS_ID} field. - * - * @return Class ID for optimized marshalling. - */ - public Object ggClassId(); -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a50fccdd/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshaller.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshaller.java b/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshaller.java deleted file mode 100644 index d3ae173..0000000 --- a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshaller.java +++ /dev/null @@ -1,410 +0,0 @@ -/* @java.file.header */ - -/* _________ _____ __________________ _____ - * __ ____/___________(_)______ /__ ____/______ ____(_)_______ - * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ - * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / - * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ - */ - -package org.gridgain.grid.marshaller.optimized; - -import org.apache.ignite.marshaller.*; -import org.gridgain.grid.*; -import org.gridgain.grid.util.*; -import org.gridgain.grid.util.typedef.*; -import org.gridgain.grid.util.typedef.internal.*; -import org.jetbrains.annotations.*; -import sun.misc.*; - -import java.io.*; -import java.net.*; -import java.util.*; - -import static org.gridgain.grid.marshaller.optimized.GridOptimizedMarshallerUtils.*; - -/** - * Optimized implementation of {@link GridMarshaller}. Unlike {@link org.apache.ignite.marshaller.jdk.GridJdkMarshaller}, - * which is based on standard {@link ObjectOutputStream}, this marshaller does not - * enforce that all serialized objects implement {@link Serializable} interface. It is also - * about 20 times faster as it removes lots of serialization overhead that exists in - * default JDK implementation. - * <p> - * {@code GridOptimizedMarshaller} is tested only on Java HotSpot VM on other VMs - * it could yield unexpected results. It is the default marshaller on Java HotSpot VMs - * and will be used if no other marshaller was explicitly configured. - * <p> - * <h1 class="header">Configuration</h1> - * <h2 class="header">Mandatory</h2> - * This marshaller has no mandatory configuration parameters. - * <h2 class="header">Java Example</h2> - * <pre name="code" class="java"> - * GridOptimizedMarshaller marshaller = new GridOptimizedMarshaller(); - * - * // Enforce Serializable interface. - * marshaller.setRequireSerializable(true); - * - * GridConfiguration cfg = new GridConfiguration(); - * - * // Override marshaller. - * cfg.setMarshaller(marshaller); - * - * // Starts grid. - * G.start(cfg); - * </pre> - * <h2 class="header">Spring Example</h2> - * GridOptimizedMarshaller can be configured from Spring XML configuration file: - * <pre name="code" class="xml"> - * <bean id="grid.custom.cfg" class="org.gridgain.grid.GridConfiguration" singleton="true"> - * ... - * <property name="marshaller"> - * <bean class="org.gridgain.grid.marshaller.optimized.GridOptimizedMarshaller"> - * <property name="requireSerializable">true</property> - * </bean> - * </property> - * ... - * </bean> - * </pre> - * <p> - * <img src="http://www.gridgain.com/images/spring-small.png"> - * <br> - * For information about Spring framework visit <a href="http://www.springframework.org/">www.springframework.org</a> - * <h2 class="header">Injection Example</h2> - * GridMarshaller can be injected in users task, job or SPI as following: - * <pre name="code" class="java"> - * public class MyGridJob implements GridComputeJob { - * ... - * @GridMarshallerResource - * private GridMarshaller marshaller; - * ... - * } - * </pre> - * or - * <pre name="code" class="java"> - * public class MyGridJob implements GridComputeJob { - * ... - * private GridMarshaller marshaller; - * ... - * @GridMarshallerResource - * public void setMarshaller(GridMarshaller marshaller) { - * this.marshaller = marshaller; - * } - * ... - * } - * </pre> - */ -public class GridOptimizedMarshaller extends GridAbstractMarshaller { - /** Whether or not to require an object to be serializable in order to be marshalled. */ - private boolean requireSer = true; - - /** Default class loader. */ - private final ClassLoader dfltClsLdr = getClass().getClassLoader(); - - /** - * Initializes marshaller not to enforce {@link Serializable} interface. - * - * @throws GridRuntimeException If this marshaller is not supported on the current JVM. - */ - public GridOptimizedMarshaller() { - if (!available()) - throw new GridRuntimeException("Using GridOptimizedMarshaller on unsupported JVM version (some of " + - "JVM-private APIs required for the marshaller to work are missing)."); - } - - /** - * Initializes marshaller with given serialization flag. If {@code true}, - * then objects will be required to implement {@link Serializable} in order - * to be serialize. - * - * @param requireSer Flag to enforce {@link Serializable} interface or not. If {@code true}, - * then objects will be required to implement {@link Serializable} in order to be - * marshalled, if {@code false}, then such requirement will be relaxed. - * @throws GridRuntimeException If this marshaller is not supported on the current JVM. - */ - public GridOptimizedMarshaller(boolean requireSer) { - this(); - - this.requireSer = requireSer; - } - - /** - * Initializes marshaller with given serialization flag. If {@code true}, - * then objects will be required to implement {@link Serializable} in order - * to be serialize. - * - * @param requireSer Flag to enforce {@link Serializable} interface or not. If {@code true}, - * then objects will be required to implement {@link Serializable} in order to be - * marshalled, if {@code false}, then such requirement will be relaxed. - * @param clsNames User preregistered class names. - * @param clsNamesPath Path to a file with user preregistered class names. - * @param poolSize Object streams pool size. - * @throws GridException If an I/O error occurs while writing stream header. - * @throws GridRuntimeException If this marshaller is not supported on the current JVM. - */ - public GridOptimizedMarshaller(boolean requireSer, @Nullable List<String> clsNames, - @Nullable String clsNamesPath, int poolSize) throws GridException { - this(requireSer); - - setClassNames(clsNames); - setClassNamesPath(clsNamesPath); - setPoolSize(poolSize); - } - - /** - * Adds provided class names for marshalling optimization. - * <p> - * <b>NOTE</b>: these collections of classes must be identical on all nodes and in the same order. - * - * @param clsNames User preregistered class names to add. - */ - @SuppressWarnings("unchecked") - public void setClassNames(@Nullable List<String> clsNames) { - if (clsNames != null && !clsNames.isEmpty()) { - String[] clsNamesArr = clsNames.toArray(new String[clsNames.size()]); - - Arrays.sort(clsNamesArr); - - Map<String, Integer> name2id = U.newHashMap(clsNamesArr.length); - T3<String, Class<?>, GridOptimizedClassDescriptor>[] id2name = new T3[clsNamesArr.length]; - - int i = 0; - - for (String name : clsNamesArr) { - name2id.put(name, i); - id2name[i++] = new T3<>(name, null, null); - } - - GridOptimizedClassResolver.userClasses(name2id, id2name); - } - } - - /** - * Specifies a name of the file which lists all class names to be optimized. - * The file path can either be absolute path, relative to {@code GRIDGAIN_HOME}, - * or specify a resource file on the class path. - * <p> - * The format of the file is class name per line, like this: - * <pre> - * ... - * com.example.Class1 - * com.example.Class2 - * ... - * </pre> - * <p> - * <b>NOTE</b>: this class list must be identical on all nodes and in the same order. - * - * @param path Path to a file with user preregistered class names. - * @throws GridException If an error occurs while writing stream header. - */ - public void setClassNamesPath(@Nullable String path) throws GridException { - if (path == null) - return; - - URL url = GridUtils.resolveGridGainUrl(path, false); - - if (url == null) - throw new GridException("Failed to find resource for name: " + path); - - List<String> clsNames; - - try { - clsNames = new LinkedList<>(); - - try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { - String clsName; - - while ((clsName = reader.readLine()) != null) - clsNames.add(clsName); - } - } - catch (IOException e) { - throw new GridException("Failed to read class names from path: " + path, e); - } - - setClassNames(clsNames); - } - - /** - * Specifies size of cached object streams used by marshaller. Object streams are cached for - * performance reason to avoid costly recreation for every serialization routine. If {@code 0} (default), - * pool is not used and each thread has its own cached object stream which it keeps reusing. - * <p> - * Since each stream has an internal buffer, creating a stream for each thread can lead to - * high memory consumption if many large messages are marshalled or unmarshalled concurrently. - * Consider using pool in this case. This will limit number of streams that can be created and, - * therefore, decrease memory consumption. - * <p> - * NOTE: Using streams pool can decrease performance since streams will be shared between - * different threads which will lead to more frequent context switching. - * - * @param poolSize Streams pool size. If {@code 0}, pool is not used. - */ - public void setPoolSize(int poolSize) { - GridOptimizedObjectStreamRegistry.poolSize(poolSize); - } - - /** - * @return Whether to enforce {@link Serializable} interface. - */ - public boolean isRequireSerializable() { - return requireSer; - } - - /** - * Sets flag to enforce {@link Serializable} interface or not. - * - * @param requireSer Flag to enforce {@link Serializable} interface or not. If {@code true}, - * then objects will be required to implement {@link Serializable} in order to be - * marshalled, if {@code false}, then such requirement will be relaxed. - */ - public void setRequireSerializable(boolean requireSer) { - this.requireSer = requireSer; - } - - /** {@inheritDoc} */ - @Override public void marshal(@Nullable Object obj, OutputStream out) throws GridException { - assert out != null; - - GridOptimizedObjectOutputStream objOut = null; - - try { - objOut = GridOptimizedObjectStreamRegistry.out(); - - objOut.requireSerializable(requireSer); - - objOut.out().outputStream(out); - - objOut.writeObject(obj); - } - catch (IOException e) { - throw new GridException("Failed to serialize object: " + obj, e); - } - finally { - GridOptimizedObjectStreamRegistry.closeOut(objOut); - } - } - - /** {@inheritDoc} */ - @Override public byte[] marshal(@Nullable Object obj) throws GridException { - GridOptimizedObjectOutputStream objOut = null; - - try { - objOut = GridOptimizedObjectStreamRegistry.out(); - - objOut.requireSerializable(requireSer); - - objOut.writeObject(obj); - - return objOut.out().array(); - } - catch (IOException e) { - throw new GridException("Failed to serialize object: " + obj, e); - } - finally { - GridOptimizedObjectStreamRegistry.closeOut(objOut); - } - } - - /** {@inheritDoc} */ - @Override public <T> T unmarshal(InputStream in, @Nullable ClassLoader clsLdr) throws GridException { - assert in != null; - - GridOptimizedObjectInputStream objIn = null; - - try { - objIn = GridOptimizedObjectStreamRegistry.in(); - - objIn.classLoader(clsLdr != null ? clsLdr : dfltClsLdr); - - objIn.in().inputStream(in); - - return (T)objIn.readObject(); - } - catch (IOException e) { - throw new GridException("Failed to deserialize object with given class loader: " + clsLdr, e); - } - catch (ClassNotFoundException e) { - throw new GridException("Failed to find class with given class loader for unmarshalling " + - "(make sure same versions of all classes are available on all nodes or enable peer-class-loading): " + - clsLdr, e); - } - finally { - GridOptimizedObjectStreamRegistry.closeIn(objIn); - } - } - - /** {@inheritDoc} */ - @Override public <T> T unmarshal(byte[] arr, @Nullable ClassLoader clsLdr) throws GridException { - assert arr != null; - - GridOptimizedObjectInputStream objIn = null; - - try { - objIn = GridOptimizedObjectStreamRegistry.in(); - - objIn.classLoader(clsLdr != null ? clsLdr : dfltClsLdr); - - objIn.in().bytes(arr, arr.length); - - return (T)objIn.readObject(); - } - catch (IOException e) { - throw new GridException("Failed to deserialize object with given class loader: " + clsLdr, e); - } - catch (ClassNotFoundException e) { - throw new GridException("Failed to find class with given class loader for unmarshalling " + - "(make sure same version of all classes are available on all nodes or enable peer-class-loading): " + - clsLdr, e); - } - finally { - GridOptimizedObjectStreamRegistry.closeIn(objIn); - } - } - - /** - * Checks whether {@code GridOptimizedMarshaller} is able to work on the current JVM. - * <p> - * As long as {@code GridOptimizedMarshaller} uses JVM-private API, which is not guaranteed - * to be available on all JVM, this method should be called to ensure marshaller could work properly. - * <p> - * Result of this method is automatically checked in constructor. - * - * @return {@code true} if {@code GridOptimizedMarshaller} can work on the current JVM or - * {@code false} if it can't. - */ - @SuppressWarnings({"TypeParameterExtendsFinalClass", "ErrorNotRethrown"}) - public static boolean available() { - try { - Unsafe unsafe = GridUnsafe.unsafe(); - - Class<? extends Unsafe> unsafeCls = unsafe.getClass(); - - unsafeCls.getMethod("allocateInstance", Class.class); - unsafeCls.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class); - - return true; - } - catch (Exception ignored) { - return false; - } - catch (NoClassDefFoundError ignored) { - return false; - } - } - - /** - * Undeployment callback invoked when class loader is being undeployed. - * - * @param ldr Class loader being undeployed. - */ - public static void onUndeploy(ClassLoader ldr) { - GridOptimizedMarshallerUtils.onUndeploy(ldr); - } - - /** - * Clears internal caches and frees memory. Usually called on system stop. - */ - public static void clearCache() { - GridOptimizedMarshallerUtils.clearCache(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a50fccdd/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshallerUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshallerUtils.java b/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshallerUtils.java deleted file mode 100644 index 885a546..0000000 --- a/modules/core/src/main/java/org/gridgain/grid/marshaller/optimized/GridOptimizedMarshallerUtils.java +++ /dev/null @@ -1,450 +0,0 @@ -/* @java.file.header */ - -/* _________ _____ __________________ _____ - * __ ____/___________(_)______ /__ ____/______ ____(_)_______ - * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ - * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / - * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ - */ - -package org.gridgain.grid.marshaller.optimized; - -import org.gridgain.grid.util.*; -import org.gridgain.grid.util.typedef.*; -import org.jdk8.backport.*; -import org.jetbrains.annotations.*; -import sun.misc.*; - -import java.io.*; -import java.lang.reflect.*; -import java.nio.charset.*; -import java.security.*; -import java.util.*; -import java.util.concurrent.*; - -import static org.gridgain.grid.marshaller.optimized.GridOptimizedMarshallable.*; - -/** - * Miscellaneous utility methods to facilitate {@link GridOptimizedMarshaller}. - */ -class GridOptimizedMarshallerUtils { - /** Unsafe. */ - private static final Unsafe UNSAFE = GridUnsafe.unsafe(); - - /** {@code Null} object reference. */ - static final byte NULL = (byte)0x70; - - /** Handle reference. */ - static final byte HANDLE = (byte)0x71; - - /** Object reference. */ - static final byte OBJECT = (byte)0x72; - - /** UTF-8 character name. */ - static final Charset UTF_8 = Charset.forName("UTF-8"); - - /** Class descriptors cache. */ - private static final ConcurrentMap<Class<?>, GridOptimizedClassDescriptor> CLS_DESC_CACHE = - new ConcurrentHashMap8<>(256); - - /** Classes cache by name. */ - private static final ConcurrentHashMap8<ClassLoader, ConcurrentHashMap8<String, Class<?>>> CLS_BY_NAME_CACHE = - new ConcurrentHashMap8<>(); - - /** - * Suppresses default constructor, ensuring non-instantiability. - */ - private GridOptimizedMarshallerUtils() { - // No-op. - } - - /** - * Gets class for given name and class loader. - * - * @param name Class name. - * @param ldr Class loader. - * @return Class. - * @throws ClassNotFoundException If class was not found. - */ - static Class<?> forName(String name, ClassLoader ldr) throws ClassNotFoundException { - assert ldr != null; - assert name != null; - - ConcurrentHashMap8<String, Class<?>> cache = CLS_BY_NAME_CACHE.get(ldr); - - Class<?> cls = null; - - if (cache == null) { - cache = new ConcurrentHashMap8<>(); - - ConcurrentHashMap8<String, Class<?>> old = CLS_BY_NAME_CACHE.putIfAbsent(ldr, cache); - - if (old != null) { - cache = old; - - cls = cache.get(name); - } - } - else - cls = cache.get(name); - - if (cls == null) { - cls = Class.forName(name, true, ldr); - - cache.put(name, cls); - } - - return cls; - } - - /** - * Gets descriptor for provided class. - * - * @param cls Class. - * @param obj Object. - * @return Descriptor. - * @throws IOException In case of error. - */ - static GridOptimizedClassDescriptor classDescriptor(Class<?> cls, @Nullable Object obj) throws IOException { - if (obj != null) { - if (obj instanceof GridOptimizedMarshallable) { - GridOptimizedMarshallable m = (GridOptimizedMarshallable)obj; - - Object clsId = m.ggClassId(); - - if (clsId != null && !(clsId instanceof GridOptimizedClassDescriptor)) - throw new IOException("Method '" + obj.getClass().getName() + ".ggClassId() must return " + - "the value of the field '" + CLS_ID_FIELD_NAME + "'."); - - GridOptimizedClassDescriptor desc = (GridOptimizedClassDescriptor)clsId; - - if (desc == null) { - desc = new GridOptimizedClassDescriptor(cls); - - try { - Field field = obj.getClass().getDeclaredField(CLS_ID_FIELD_NAME); - - field.setAccessible(true); - - Object o = field.get(null); - - if (o == null) { - if ((field.getModifiers() & Modifier.STATIC) == 0) - throw new IOException("Field '" + CLS_ID_FIELD_NAME + "' must be declared static: " + - obj.getClass().getName()); - - field.set(null, desc); - - if (m.ggClassId() == null) - throw new IOException( "Method '" + obj.getClass().getName() + ".ggClassId() must " + - "return the value of the field '" + CLS_ID_FIELD_NAME + "': " - + obj.getClass().getName()); - } - else if (!(o instanceof GridOptimizedClassDescriptor)) - throw new IOException("Field '" + CLS_ID_FIELD_NAME + "' must be declared with " + - "null value: " + obj.getClass().getName()); - } - catch (NoSuchFieldException e) { - throw new IOException("GridOptimizedMarshallable classes must have static field declared " + - "[fieldName=" + CLS_ID_FIELD_NAME + ", cls=" + obj.getClass().getName() + ']', e); - } - catch (IllegalAccessException e) { - throw new IOException("Failed to set field '" + CLS_ID_FIELD_NAME + "' on '" + - obj.getClass().getName() + "' class.", e); - } - } - - return desc; - } - } - - GridOptimizedClassDescriptor desc = CLS_DESC_CACHE.get(cls); - - if (desc == null) { - GridOptimizedClassDescriptor existing = CLS_DESC_CACHE.putIfAbsent(cls, - desc = new GridOptimizedClassDescriptor(cls)); - - if (existing != null) - desc = existing; - } - - return desc; - } - - /** - * Undeployment callback. - * - * @param ldr Undeployed class loader. - */ - public static void onUndeploy(ClassLoader ldr) { - CLS_BY_NAME_CACHE.remove(ldr); - - for (Class<?> cls : CLS_DESC_CACHE.keySet()) { - if (ldr.equals(cls.getClassLoader())) - CLS_DESC_CACHE.remove(cls); - } - } - - /** - * Intended for test purposes only. - */ - public static void clearCache() { - CLS_BY_NAME_CACHE.clear(); - CLS_DESC_CACHE.clear(); - } - - /** - * - */ - public static void printMemoryStats() { - X.println(">>>"); - X.println(">>> GridOptimizedMarshallerUtils memory stats:"); - X.println(" Cache size: " + CLS_DESC_CACHE.size()); - - for (Map.Entry<Class<?>, GridOptimizedClassDescriptor> e : CLS_DESC_CACHE.entrySet()) - X.println(" " + e.getKey() + " : " + e.getValue()); - } - - /** - * Computes the serial version UID value for the given class. - * The code is taken from {@link ObjectStreamClass#computeDefaultSUID(Class)}. - * - * @param cls A class. - * @param fields Fields. - * @return A serial version UID. - * @throws IOException If failed. - */ - @SuppressWarnings("ForLoopReplaceableByForEach") - static Long computeSerialVersionUid(Class cls, List<Field> fields) throws IOException { - if (Serializable.class.isAssignableFrom(cls) && !Enum.class.isAssignableFrom(cls)) - return ObjectStreamClass.lookup(cls).getSerialVersionUID(); - - MessageDigest md; - - try { - md = MessageDigest.getInstance("SHA"); - } - catch (NoSuchAlgorithmException e) { - throw new IOException("Failed to get digest for SHA.", e); - } - - md.update(cls.getName().getBytes(UTF_8)); - - if (!F.isEmpty(fields)) { - for (int i = 0; i < fields.size(); i++) { - Field f = fields.get(i); - - md.update(f.getName().getBytes(UTF_8)); - md.update(f.getType().getName().getBytes(UTF_8)); - } - } - - byte[] hashBytes = md.digest(); - - long hash = 0; - - // Composes a single-long hash from the byte[] hash. - for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) - hash = (hash << 8) | (hashBytes[i] & 0xFF); - - return hash; - } - - /** - * Gets byte field value. - * - * @param obj Object. - * @param off Field offset. - * @return Byte value. - */ - static byte getByte(Object obj, long off) { - return UNSAFE.getByte(obj, off); - } - - /** - * Sets byte field value. - * - * @param obj Object. - * @param off Field offset. - * @param val Value. - */ - static void setByte(Object obj, long off, byte val) { - UNSAFE.putByte(obj, off, val); - } - - /** - * Gets short field value. - * - * @param obj Object. - * @param off Field offset. - * @return Short value. - */ - static short getShort(Object obj, long off) { - return UNSAFE.getShort(obj, off); - } - - /** - * Sets short field value. - * - * @param obj Object. - * @param off Field offset. - * @param val Value. - */ - static void setShort(Object obj, long off, short val) { - UNSAFE.putShort(obj, off, val); - } - - /** - * Gets integer field value. - * - * @param obj Object. - * @param off Field offset. - * @return Integer value. - */ - static int getInt(Object obj, long off) { - return UNSAFE.getInt(obj, off); - } - - /** - * Sets integer field value. - * - * @param obj Object. - * @param off Field offset. - * @param val Value. - */ - static void setInt(Object obj, long off, int val) { - UNSAFE.putInt(obj, off, val); - } - - /** - * Gets long field value. - * - * @param obj Object. - * @param off Field offset. - * @return Long value. - */ - static long getLong(Object obj, long off) { - return UNSAFE.getLong(obj, off); - } - - /** - * Sets long field value. - * - * @param obj Object. - * @param off Field offset. - * @param val Value. - */ - static void setLong(Object obj, long off, long val) { - UNSAFE.putLong(obj, off, val); - } - - /** - * Gets float field value. - * - * @param obj Object. - * @param off Field offset. - * @return Float value. - */ - static float getFloat(Object obj, long off) { - return UNSAFE.getFloat(obj, off); - } - - /** - * Sets float field value. - * - * @param obj Object. - * @param off Field offset. - * @param val Value. - */ - static void setFloat(Object obj, long off, float val) { - UNSAFE.putFloat(obj, off, val); - } - - /** - * Gets double field value. - * - * @param obj Object. - * @param off Field offset. - * @return Double value. - */ - static double getDouble(Object obj, long off) { - return UNSAFE.getDouble(obj, off); - } - - /** - * Sets double field value. - * - * @param obj Object. - * @param off Field offset. - * @param val Value. - */ - static void setDouble(Object obj, long off, double val) { - UNSAFE.putDouble(obj, off, val); - } - - /** - * Gets char field value. - * - * @param obj Object. - * @param off Field offset. - * @return Char value. - */ - static char getChar(Object obj, long off) { - return UNSAFE.getChar(obj, off); - } - - /** - * Sets char field value. - * - * @param obj Object. - * @param off Field offset. - * @param val Value. - */ - static void setChar(Object obj, long off, char val) { - UNSAFE.putChar(obj, off, val); - } - - /** - * Gets boolean field value. - * - * @param obj Object. - * @param off Field offset. - * @return Boolean value. - */ - static boolean getBoolean(Object obj, long off) { - return UNSAFE.getBoolean(obj, off); - } - - /** - * Sets boolean field value. - * - * @param obj Object. - * @param off Field offset. - * @param val Value. - */ - static void setBoolean(Object obj, long off, boolean val) { - UNSAFE.putBoolean(obj, off, val); - } - - /** - * Gets field value. - * - * @param obj Object. - * @param off Field offset. - * @return Value. - */ - static Object getObject(Object obj, long off) { - return UNSAFE.getObject(obj, off); - } - - /** - * Sets field value. - * - * @param obj Object. - * @param off Field offset. - * @param val Value. - */ - static void setObject(Object obj, long off, Object val) { - UNSAFE.putObject(obj, off, val); - } -}