You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/12/11 11:00:42 UTC
[37/50] [abbrv] ignite git commit: ignite-2065: rename "portable"
packages to "binary"
http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
deleted file mode 100644
index 9a65da1..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.math.BigDecimal;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.UUID;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.binary.BinaryIdMapper;
-import org.apache.ignite.binary.BinaryObjectException;
-import org.apache.ignite.binary.BinarySerializer;
-import org.apache.ignite.binary.Binarylizable;
-import org.apache.ignite.internal.processors.cache.CacheObjectImpl;
-import org.apache.ignite.internal.util.GridUnsafe;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.marshaller.MarshallerExclusions;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
-import org.jetbrains.annotations.Nullable;
-import sun.misc.Unsafe;
-
-import static java.lang.reflect.Modifier.isStatic;
-import static java.lang.reflect.Modifier.isTransient;
-
-/**
- * Portable class descriptor.
- */
-public class PortableClassDescriptor {
- /** */
- public static final Unsafe UNSAFE = GridUnsafe.unsafe();
-
- /** */
- private final PortableContext ctx;
-
- /** */
- private final Class<?> cls;
-
- /** */
- private final BinarySerializer serializer;
-
- /** ID mapper. */
- private final BinaryIdMapper idMapper;
-
- /** */
- private final BinaryWriteMode mode;
-
- /** */
- private final boolean userType;
-
- /** */
- private final int typeId;
-
- /** */
- private final String typeName;
-
- /** Affinity key field name. */
- private final String affKeyFieldName;
-
- /** */
- private final Constructor<?> ctor;
-
- /** */
- private final BinaryFieldAccessor[] fields;
-
- /** */
- private final Method writeReplaceMtd;
-
- /** */
- private final Method readResolveMtd;
-
- /** */
- private final Map<String, Integer> stableFieldsMeta;
-
- /** Object schemas. Initialized only for serializable classes and contains only 1 entry. */
- private final PortableSchema stableSchema;
-
- /** Schema registry. */
- private final PortableSchemaRegistry schemaReg;
-
- /** */
- private final boolean registered;
-
- /** */
- private final boolean useOptMarshaller;
-
- /** */
- private final boolean excluded;
-
- /**
- * @param ctx Context.
- * @param cls Class.
- * @param userType User type flag.
- * @param typeId Type ID.
- * @param typeName Type name.
- * @param affKeyFieldName Affinity key field name.
- * @param idMapper ID mapper.
- * @param serializer Serializer.
- * @param metaDataEnabled Metadata enabled flag.
- * @param registered Whether typeId has been successfully registered by MarshallerContext or not.
- * @param predefined Whether the class is predefined or not.
- * @throws BinaryObjectException In case of error.
- */
- PortableClassDescriptor(
- PortableContext ctx,
- Class<?> cls,
- boolean userType,
- int typeId,
- String typeName,
- @Nullable String affKeyFieldName,
- @Nullable BinaryIdMapper idMapper,
- @Nullable BinarySerializer serializer,
- boolean metaDataEnabled,
- boolean registered,
- boolean predefined
- ) throws BinaryObjectException {
- assert ctx != null;
- assert cls != null;
- assert idMapper != null;
-
- this.ctx = ctx;
- this.cls = cls;
- this.typeId = typeId;
- this.userType = userType;
- this.typeName = typeName;
- this.affKeyFieldName = affKeyFieldName;
- this.serializer = serializer;
- this.idMapper = idMapper;
- this.registered = registered;
-
- schemaReg = ctx.schemaRegistry(typeId);
-
- excluded = MarshallerExclusions.isExcluded(cls);
-
- useOptMarshaller = !predefined && initUseOptimizedMarshallerFlag();
-
- if (excluded)
- mode = BinaryWriteMode.EXCLUSION;
- else {
- if (cls == BinaryEnumObjectImpl.class)
- mode = BinaryWriteMode.PORTABLE_ENUM;
- else
- mode = serializer != null ? BinaryWriteMode.PORTABLE : PortableUtils.mode(cls);
- }
-
- switch (mode) {
- case P_BYTE:
- case P_BOOLEAN:
- case P_SHORT:
- case P_CHAR:
- case P_INT:
- case P_LONG:
- case P_FLOAT:
- case P_DOUBLE:
- case BYTE:
- case SHORT:
- case INT:
- case LONG:
- case FLOAT:
- case DOUBLE:
- case CHAR:
- case BOOLEAN:
- case DECIMAL:
- case STRING:
- case UUID:
- case DATE:
- case TIMESTAMP:
- case BYTE_ARR:
- case SHORT_ARR:
- case INT_ARR:
- case LONG_ARR:
- case FLOAT_ARR:
- case DOUBLE_ARR:
- case CHAR_ARR:
- case BOOLEAN_ARR:
- case DECIMAL_ARR:
- case STRING_ARR:
- case UUID_ARR:
- case DATE_ARR:
- case TIMESTAMP_ARR:
- case OBJECT_ARR:
- case COL:
- case MAP:
- case PORTABLE_OBJ:
- case ENUM:
- case PORTABLE_ENUM:
- case ENUM_ARR:
- case CLASS:
- case EXCLUSION:
- ctor = null;
- fields = null;
- stableFieldsMeta = null;
- stableSchema = null;
-
- break;
-
- case PORTABLE:
- case EXTERNALIZABLE:
- ctor = constructor(cls);
- fields = null;
- stableFieldsMeta = null;
- stableSchema = null;
-
- break;
-
- case OBJECT:
- // Must not use constructor to honor transient fields semantics.
- ctor = null;
- ArrayList<BinaryFieldAccessor> fields0 = new ArrayList<>();
- stableFieldsMeta = metaDataEnabled ? new HashMap<String, Integer>() : null;
-
- PortableSchema.Builder schemaBuilder = PortableSchema.Builder.newBuilder();
-
- Collection<String> names = new HashSet<>();
- Collection<Integer> ids = new HashSet<>();
-
- for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
- for (Field f : c.getDeclaredFields()) {
- int mod = f.getModifiers();
-
- if (!isStatic(mod) && !isTransient(mod)) {
- f.setAccessible(true);
-
- String name = f.getName();
-
- if (!names.add(name))
- throw new BinaryObjectException("Duplicate field name [fieldName=" + name +
- ", cls=" + cls.getName() + ']');
-
- int fieldId = idMapper.fieldId(typeId, name);
-
- if (!ids.add(fieldId))
- throw new BinaryObjectException("Duplicate field ID: " + name);
-
- BinaryFieldAccessor fieldInfo = BinaryFieldAccessor.create(f, fieldId);
-
- fields0.add(fieldInfo);
-
- schemaBuilder.addField(fieldId);
-
- if (metaDataEnabled)
- stableFieldsMeta.put(name, fieldInfo.mode().typeId());
- }
- }
- }
-
- fields = fields0.toArray(new BinaryFieldAccessor[fields0.size()]);
-
- stableSchema = schemaBuilder.build();
-
- break;
-
- default:
- // Should never happen.
- throw new BinaryObjectException("Invalid mode: " + mode);
- }
-
- if (mode == BinaryWriteMode.PORTABLE || mode == BinaryWriteMode.EXTERNALIZABLE ||
- mode == BinaryWriteMode.OBJECT) {
- readResolveMtd = U.findNonPublicMethod(cls, "readResolve");
- writeReplaceMtd = U.findNonPublicMethod(cls, "writeReplace");
- }
- else {
- readResolveMtd = null;
- writeReplaceMtd = null;
- }
- }
-
- /**
- * @return {@code True} if enum.
- */
- boolean isEnum() {
- return mode == BinaryWriteMode.ENUM;
- }
-
- /**
- * @return Described class.
- */
- Class<?> describedClass() {
- return cls;
- }
-
- /**
- * @return Type ID.
- */
- public int typeId() {
- return typeId;
- }
-
- /**
- * @return User type flag.
- */
- public boolean userType() {
- return userType;
- }
-
- /**
- * @return Fields meta data.
- */
- Map<String, Integer> fieldsMeta() {
- return stableFieldsMeta;
- }
-
- /**
- * @return Schema.
- */
- PortableSchema schema() {
- return stableSchema;
- }
-
- /**
- * @return Whether typeId has been successfully registered by MarshallerContext or not.
- */
- public boolean registered() {
- return registered;
- }
-
- /**
- * @return {@code true} if {@link OptimizedMarshaller} must be used instead of {@link BinaryMarshaller}
- * for object serialization and deserialization.
- */
- public boolean useOptimizedMarshaller() {
- return useOptMarshaller;
- }
-
- /**
- * Checks whether the class values are explicitly excluded from marshalling.
- *
- * @return {@code true} if excluded, {@code false} otherwise.
- */
- public boolean excluded() {
- return excluded;
- }
-
- /**
- * @return portableWriteReplace() method
- */
- @Nullable Method getWriteReplaceMethod() {
- return writeReplaceMtd;
- }
-
- /**
- * @return portableReadResolve() method
- */
- @SuppressWarnings("UnusedDeclaration")
- @Nullable Method getReadResolveMethod() {
- return readResolveMtd;
- }
-
- /**
- * @param obj Object.
- * @param writer Writer.
- * @throws BinaryObjectException In case of error.
- */
- void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
- assert obj != null;
- assert writer != null;
-
- writer.typeId(typeId);
-
- switch (mode) {
- case P_BYTE:
- case BYTE:
- writer.writeByteFieldPrimitive((byte) obj);
-
- break;
-
- case P_SHORT:
- case SHORT:
- writer.writeShortFieldPrimitive((short)obj);
-
- break;
-
- case P_INT:
- case INT:
- writer.writeIntFieldPrimitive((int) obj);
-
- break;
-
- case P_LONG:
- case LONG:
- writer.writeLongFieldPrimitive((long) obj);
-
- break;
-
- case P_FLOAT:
- case FLOAT:
- writer.writeFloatFieldPrimitive((float) obj);
-
- break;
-
- case P_DOUBLE:
- case DOUBLE:
- writer.writeDoubleFieldPrimitive((double) obj);
-
- break;
-
- case P_CHAR:
- case CHAR:
- writer.writeCharFieldPrimitive((char) obj);
-
- break;
-
- case P_BOOLEAN:
- case BOOLEAN:
- writer.writeBooleanFieldPrimitive((boolean) obj);
-
- break;
-
- case DECIMAL:
- writer.doWriteDecimal((BigDecimal)obj);
-
- break;
-
- case STRING:
- writer.doWriteString((String)obj);
-
- break;
-
- case UUID:
- writer.doWriteUuid((UUID)obj);
-
- break;
-
- case DATE:
- writer.doWriteDate((Date)obj);
-
- break;
-
- case TIMESTAMP:
- writer.doWriteTimestamp((Timestamp)obj);
-
- break;
-
- case BYTE_ARR:
- writer.doWriteByteArray((byte[])obj);
-
- break;
-
- case SHORT_ARR:
- writer.doWriteShortArray((short[]) obj);
-
- break;
-
- case INT_ARR:
- writer.doWriteIntArray((int[]) obj);
-
- break;
-
- case LONG_ARR:
- writer.doWriteLongArray((long[]) obj);
-
- break;
-
- case FLOAT_ARR:
- writer.doWriteFloatArray((float[]) obj);
-
- break;
-
- case DOUBLE_ARR:
- writer.doWriteDoubleArray((double[]) obj);
-
- break;
-
- case CHAR_ARR:
- writer.doWriteCharArray((char[]) obj);
-
- break;
-
- case BOOLEAN_ARR:
- writer.doWriteBooleanArray((boolean[]) obj);
-
- break;
-
- case DECIMAL_ARR:
- writer.doWriteDecimalArray((BigDecimal[]) obj);
-
- break;
-
- case STRING_ARR:
- writer.doWriteStringArray((String[]) obj);
-
- break;
-
- case UUID_ARR:
- writer.doWriteUuidArray((UUID[]) obj);
-
- break;
-
- case DATE_ARR:
- writer.doWriteDateArray((Date[]) obj);
-
- break;
-
- case TIMESTAMP_ARR:
- writer.doWriteTimestampArray((Timestamp[]) obj);
-
- break;
-
- case OBJECT_ARR:
- writer.doWriteObjectArray((Object[])obj);
-
- break;
-
- case COL:
- writer.doWriteCollection((Collection<?>)obj);
-
- break;
-
- case MAP:
- writer.doWriteMap((Map<?, ?>)obj);
-
- break;
-
- case ENUM:
- writer.doWriteEnum((Enum<?>)obj);
-
- break;
-
- case PORTABLE_ENUM:
- writer.doWritePortableEnum((BinaryEnumObjectImpl)obj);
-
- break;
-
- case ENUM_ARR:
- writer.doWriteEnumArray((Object[])obj);
-
- break;
-
- case CLASS:
- writer.doWriteClass((Class)obj);
-
- break;
-
- case PORTABLE_OBJ:
- writer.doWritePortableObject((BinaryObjectImpl)obj);
-
- break;
-
- case PORTABLE:
- if (preWrite(writer, obj)) {
- try {
- if (serializer != null)
- serializer.writeBinary(obj, writer);
- else
- ((Binarylizable)obj).writeBinary(writer);
-
- postWrite(writer, obj);
-
- // Check whether we need to update metadata.
- if (obj.getClass() != BinaryMetadata.class) {
- int schemaId = writer.schemaId();
-
- if (schemaReg.schema(schemaId) == null) {
- // This is new schema, let's update metadata.
- BinaryMetadataCollector collector =
- new BinaryMetadataCollector(typeId, typeName, idMapper);
-
- if (serializer != null)
- serializer.writeBinary(obj, collector);
- else
- ((Binarylizable)obj).writeBinary(collector);
-
- PortableSchema newSchema = collector.schema();
-
- BinaryMetadata meta = new BinaryMetadata(typeId, typeName, collector.meta(),
- affKeyFieldName, Collections.singleton(newSchema), false);
-
- ctx.updateMetadata(typeId, meta);
-
- schemaReg.addSchema(newSchema.schemaId(), newSchema);
- }
- }
- }
- finally {
- writer.popSchema();
- }
- }
-
- break;
-
- case EXTERNALIZABLE:
- if (preWrite(writer, obj)) {
- writer.rawWriter();
-
- try {
- ((Externalizable)obj).writeExternal(writer);
-
- postWrite(writer, obj);
- }
- catch (IOException e) {
- throw new BinaryObjectException("Failed to write Externalizable object: " + obj, e);
- }
- finally {
- writer.popSchema();
- }
- }
-
- break;
-
- case OBJECT:
- if (preWrite(writer, obj)) {
- try {
- for (BinaryFieldAccessor info : fields)
- info.write(obj, writer);
-
- writer.schemaId(stableSchema.schemaId());
-
- postWrite(writer, obj);
- }
- finally {
- writer.popSchema();
- }
- }
-
- break;
-
- default:
- assert false : "Invalid mode: " + mode;
- }
- }
-
- /**
- * @param reader Reader.
- * @return Object.
- * @throws BinaryObjectException If failed.
- */
- Object read(BinaryReaderExImpl reader) throws BinaryObjectException {
- assert reader != null;
-
- Object res;
-
- switch (mode) {
- case PORTABLE:
- res = newInstance();
-
- reader.setHandle(res);
-
- if (serializer != null)
- serializer.readBinary(res, reader);
- else
- ((Binarylizable)res).readBinary(reader);
-
- break;
-
- case EXTERNALIZABLE:
- res = newInstance();
-
- reader.setHandle(res);
-
- try {
- ((Externalizable)res).readExternal(reader);
- }
- catch (IOException | ClassNotFoundException e) {
- throw new BinaryObjectException("Failed to read Externalizable object: " +
- res.getClass().getName(), e);
- }
-
- break;
-
- case OBJECT:
- res = newInstance();
-
- reader.setHandle(res);
-
- for (BinaryFieldAccessor info : fields)
- info.read(res, reader);
-
- break;
-
- default:
- assert false : "Invalid mode: " + mode;
-
- return null;
- }
-
- if (readResolveMtd != null) {
- try {
- res = readResolveMtd.invoke(res);
-
- reader.setHandle(res);
- }
- catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- catch (InvocationTargetException e) {
- if (e.getTargetException() instanceof BinaryObjectException)
- throw (BinaryObjectException)e.getTargetException();
-
- throw new BinaryObjectException("Failed to execute readResolve() method on " + res, e);
- }
- }
-
- return res;
- }
-
- /**
- * Pre-write phase.
- *
- * @param writer Writer.
- * @param obj Object.
- * @return Whether further write is needed.
- */
- private boolean preWrite(BinaryWriterExImpl writer, Object obj) {
- if (writer.tryWriteAsHandle(obj))
- return false;
-
- writer.preWrite(registered ? null : cls.getName());
-
- return true;
- }
-
- /**
- * Post-write phase.
- *
- * @param writer Writer.
- * @param obj Object.
- */
- private void postWrite(BinaryWriterExImpl writer, Object obj) {
- writer.postWrite(userType, registered, obj instanceof CacheObjectImpl ? 0 : obj.hashCode());
- }
-
- /**
- * @return Instance.
- * @throws BinaryObjectException In case of error.
- */
- private Object newInstance() throws BinaryObjectException {
- try {
- return ctor != null ? ctor.newInstance() : UNSAFE.allocateInstance(cls);
- }
- catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
- throw new BinaryObjectException("Failed to instantiate instance: " + cls, e);
- }
- }
-
- /**
- * @param cls Class.
- * @return Constructor.
- * @throws BinaryObjectException If constructor doesn't exist.
- */
- @SuppressWarnings("ConstantConditions")
- @Nullable private static Constructor<?> constructor(Class<?> cls) throws BinaryObjectException {
- assert cls != null;
-
- try {
- Constructor<?> ctor = U.forceEmptyConstructor(cls);
-
- if (ctor == null)
- throw new BinaryObjectException("Failed to find empty constructor for class: " + cls.getName());
-
- ctor.setAccessible(true);
-
- return ctor;
- }
- catch (IgniteCheckedException e) {
- throw new BinaryObjectException("Failed to get constructor for class: " + cls.getName(), e);
- }
- }
-
- /**
- * Determines whether to use {@link OptimizedMarshaller} for serialization or
- * not.
- *
- * @return {@code true} if to use, {@code false} otherwise.
- */
- @SuppressWarnings("unchecked")
- private boolean initUseOptimizedMarshallerFlag() {
- for (Class c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
- try {
- Method writeObj = c.getDeclaredMethod("writeObject", ObjectOutputStream.class);
- Method readObj = c.getDeclaredMethod("readObject", ObjectInputStream.class);
-
- if (!Modifier.isStatic(writeObj.getModifiers()) && !Modifier.isStatic(readObj.getModifiers()) &&
- writeObj.getReturnType() == void.class && readObj.getReturnType() == void.class)
- return true;
- }
- catch (NoSuchMethodException ignored) {
- // No-op.
- }
- }
-
- return false;
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
deleted file mode 100644
index f02867b..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.binary.BinaryIdMapper;
-import org.apache.ignite.binary.BinaryInvalidTypeException;
-import org.apache.ignite.binary.BinaryObjectException;
-import org.apache.ignite.binary.BinarySerializer;
-import org.apache.ignite.binary.BinaryType;
-import org.apache.ignite.binary.BinaryTypeConfiguration;
-import org.apache.ignite.cache.CacheKeyConfiguration;
-import org.apache.ignite.cache.affinity.AffinityKeyMapped;
-import org.apache.ignite.configuration.BinaryConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteKernal;
-import org.apache.ignite.internal.IgnitionEx;
-import org.apache.ignite.internal.processors.cache.portable.CacheObjectBinaryProcessorImpl;
-import org.apache.ignite.internal.processors.datastructures.CollocatedQueueItemKey;
-import org.apache.ignite.internal.processors.datastructures.CollocatedSetItemKey;
-import org.apache.ignite.internal.util.IgniteUtils;
-import org.apache.ignite.internal.util.lang.GridMapEntry;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.marshaller.MarshallerContext;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
-import org.jetbrains.annotations.Nullable;
-import org.jsr166.ConcurrentHashMap8;
-
-import java.io.Externalizable;
-import java.io.File;
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.ObjectStreamException;
-import java.lang.reflect.Field;
-import java.math.BigDecimal;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentMap;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-/**
- * Portable context.
- */
-public class PortableContext implements Externalizable {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** */
- private static final ClassLoader dfltLdr = U.gridClassLoader();
-
- /** */
- private final ConcurrentMap<Class<?>, PortableClassDescriptor> descByCls = new ConcurrentHashMap8<>();
-
- /** Holds classes loaded by default class loader only. */
- private final ConcurrentMap<Integer, PortableClassDescriptor> userTypes = new ConcurrentHashMap8<>();
-
- /** */
- private final Map<Integer, PortableClassDescriptor> predefinedTypes = new HashMap<>();
-
- /** */
- private final Map<String, Integer> predefinedTypeNames = new HashMap<>();
-
- /** */
- private final Map<Class<? extends Collection>, Byte> colTypes = new HashMap<>();
-
- /** */
- private final Map<Class<? extends Map>, Byte> mapTypes = new HashMap<>();
-
- /** */
- private final ConcurrentMap<Integer, BinaryIdMapper> mappers = new ConcurrentHashMap8<>(0);
-
- /** Affinity key field names. */
- private final ConcurrentMap<Integer, String> affKeyFieldNames = new ConcurrentHashMap8<>(0);
-
- /** */
- private final Map<String, BinaryIdMapper> typeMappers = new ConcurrentHashMap8<>(0);
-
- /** */
- private BinaryMetadataHandler metaHnd;
-
- /** Actual marshaller. */
- private BinaryMarshaller marsh;
-
- /** */
- private MarshallerContext marshCtx;
-
- /** */
- private String gridName;
-
- /** */
- private IgniteConfiguration igniteCfg;
-
- /** */
- private final OptimizedMarshaller optmMarsh = new OptimizedMarshaller();
-
- /** Compact footer flag. */
- private boolean compactFooter;
-
- /** Object schemas. */
- private volatile Map<Integer, PortableSchemaRegistry> schemas;
-
- /**
- * For {@link Externalizable}.
- */
- public PortableContext() {
- // No-op.
- }
-
- /**
- * @param metaHnd Meta data handler.
- * @param igniteCfg Ignite configuration.
- */
- public PortableContext(BinaryMetadataHandler metaHnd, IgniteConfiguration igniteCfg) {
- assert metaHnd != null;
- assert igniteCfg != null;
-
- this.metaHnd = metaHnd;
- this.igniteCfg = igniteCfg;
-
- gridName = igniteCfg.getGridName();
-
- colTypes.put(ArrayList.class, GridPortableMarshaller.ARR_LIST);
- colTypes.put(LinkedList.class, GridPortableMarshaller.LINKED_LIST);
- colTypes.put(HashSet.class, GridPortableMarshaller.HASH_SET);
- colTypes.put(LinkedHashSet.class, GridPortableMarshaller.LINKED_HASH_SET);
-
- mapTypes.put(HashMap.class, GridPortableMarshaller.HASH_MAP);
- mapTypes.put(LinkedHashMap.class, GridPortableMarshaller.LINKED_HASH_MAP);
-
- // IDs range from [0..200] is used by Java SDK API and GridGain legacy API
-
- registerPredefinedType(Byte.class, GridPortableMarshaller.BYTE);
- registerPredefinedType(Boolean.class, GridPortableMarshaller.BOOLEAN);
- registerPredefinedType(Short.class, GridPortableMarshaller.SHORT);
- registerPredefinedType(Character.class, GridPortableMarshaller.CHAR);
- registerPredefinedType(Integer.class, GridPortableMarshaller.INT);
- registerPredefinedType(Long.class, GridPortableMarshaller.LONG);
- registerPredefinedType(Float.class, GridPortableMarshaller.FLOAT);
- registerPredefinedType(Double.class, GridPortableMarshaller.DOUBLE);
- registerPredefinedType(String.class, GridPortableMarshaller.STRING);
- registerPredefinedType(BigDecimal.class, GridPortableMarshaller.DECIMAL);
- registerPredefinedType(Date.class, GridPortableMarshaller.DATE);
- registerPredefinedType(Timestamp.class, GridPortableMarshaller.TIMESTAMP);
- registerPredefinedType(UUID.class, GridPortableMarshaller.UUID);
-
- registerPredefinedType(byte[].class, GridPortableMarshaller.BYTE_ARR);
- registerPredefinedType(short[].class, GridPortableMarshaller.SHORT_ARR);
- registerPredefinedType(int[].class, GridPortableMarshaller.INT_ARR);
- registerPredefinedType(long[].class, GridPortableMarshaller.LONG_ARR);
- registerPredefinedType(float[].class, GridPortableMarshaller.FLOAT_ARR);
- registerPredefinedType(double[].class, GridPortableMarshaller.DOUBLE_ARR);
- registerPredefinedType(char[].class, GridPortableMarshaller.CHAR_ARR);
- registerPredefinedType(boolean[].class, GridPortableMarshaller.BOOLEAN_ARR);
- registerPredefinedType(BigDecimal[].class, GridPortableMarshaller.DECIMAL_ARR);
- registerPredefinedType(String[].class, GridPortableMarshaller.STRING_ARR);
- registerPredefinedType(UUID[].class, GridPortableMarshaller.UUID_ARR);
- registerPredefinedType(Date[].class, GridPortableMarshaller.DATE_ARR);
- registerPredefinedType(Timestamp[].class, GridPortableMarshaller.TIMESTAMP_ARR);
- registerPredefinedType(Object[].class, GridPortableMarshaller.OBJ_ARR);
-
- registerPredefinedType(ArrayList.class, 0);
- registerPredefinedType(LinkedList.class, 0);
- registerPredefinedType(HashSet.class, 0);
- registerPredefinedType(LinkedHashSet.class, 0);
-
- registerPredefinedType(HashMap.class, 0);
- registerPredefinedType(LinkedHashMap.class, 0);
-
- registerPredefinedType(GridMapEntry.class, 60);
- registerPredefinedType(IgniteBiTuple.class, 61);
- registerPredefinedType(T2.class, 62);
-
- // IDs range [200..1000] is used by Ignite internal APIs.
- }
-
- /**
- * @return Marshaller.
- */
- public BinaryMarshaller marshaller() {
- return marsh;
- }
-
- /**
- * @return Ignite configuration.
- */
- public IgniteConfiguration configuration(){
- return igniteCfg;
- }
-
- /**
- * @param marsh Portable marshaller.
- * @param cfg Configuration.
- * @throws BinaryObjectException In case of error.
- */
- public void configure(BinaryMarshaller marsh, IgniteConfiguration cfg) throws BinaryObjectException {
- if (marsh == null)
- return;
-
- this.marsh = marsh;
-
- marshCtx = marsh.getContext();
-
- BinaryConfiguration binaryCfg = cfg.getBinaryConfiguration();
-
- if (binaryCfg == null)
- binaryCfg = new BinaryConfiguration();
-
- assert marshCtx != null;
-
- optmMarsh.setContext(marshCtx);
-
- configure(
- binaryCfg.getIdMapper(),
- binaryCfg.getSerializer(),
- binaryCfg.getTypeConfigurations()
- );
-
- compactFooter = binaryCfg.isCompactFooter();
- }
-
- /**
- * @param globalIdMapper ID mapper.
- * @param globalSerializer Serializer.
- * @param typeCfgs Type configurations.
- * @throws BinaryObjectException In case of error.
- */
- private void configure(
- BinaryIdMapper globalIdMapper,
- BinarySerializer globalSerializer,
- Collection<BinaryTypeConfiguration> typeCfgs
- ) throws BinaryObjectException {
- TypeDescriptors descs = new TypeDescriptors();
-
- Map<String, String> affFields = new HashMap<>();
-
- if (!F.isEmpty(igniteCfg.getCacheKeyConfiguration())) {
- for (CacheKeyConfiguration keyCfg : igniteCfg.getCacheKeyConfiguration())
- affFields.put(keyCfg.getTypeName(), keyCfg.getAffinityKeyFieldName());
- }
-
- if (typeCfgs != null) {
- for (BinaryTypeConfiguration typeCfg : typeCfgs) {
- String clsName = typeCfg.getTypeName();
-
- if (clsName == null)
- throw new BinaryObjectException("Class name is required for portable type configuration.");
-
- BinaryIdMapper idMapper = globalIdMapper;
-
- if (typeCfg.getIdMapper() != null)
- idMapper = typeCfg.getIdMapper();
-
- idMapper = BinaryInternalIdMapper.create(idMapper);
-
- BinarySerializer serializer = globalSerializer;
-
- if (typeCfg.getSerializer() != null)
- serializer = typeCfg.getSerializer();
-
- if (clsName.endsWith(".*")) {
- String pkgName = clsName.substring(0, clsName.length() - 2);
-
- for (String clsName0 : classesInPackage(pkgName))
- descs.add(clsName0, idMapper, serializer, affFields.get(clsName0),
- typeCfg.isEnum(), true);
- }
- else
- descs.add(clsName, idMapper, serializer, affFields.get(clsName),
- typeCfg.isEnum(), false);
- }
- }
-
- for (TypeDescriptor desc : descs.descriptors())
- registerUserType(desc.clsName, desc.idMapper, desc.serializer, desc.affKeyFieldName, desc.isEnum);
-
- BinaryInternalIdMapper dfltMapper = BinaryInternalIdMapper.create(globalIdMapper);
-
- // Put affinity field names for unconfigured types.
- for (Map.Entry<String, String> entry : affFields.entrySet()) {
- String typeName = entry.getKey();
-
- int typeId = dfltMapper.typeId(typeName);
-
- affKeyFieldNames.putIfAbsent(typeId, entry.getValue());
- }
-
- addSystemClassAffinityKey(CollocatedSetItemKey.class);
- addSystemClassAffinityKey(CollocatedQueueItemKey.class);
- }
-
- /**
- * @param cls Class.
- */
- private void addSystemClassAffinityKey(Class<?> cls) {
- String fieldName = affinityFieldName(cls);
-
- assert fieldName != null : cls;
-
- affKeyFieldNames.putIfAbsent(cls.getName().hashCode(), affinityFieldName(cls));
- }
-
- /**
- * @param pkgName Package name.
- * @return Class names.
- */
- @SuppressWarnings("ConstantConditions")
- private static Iterable<String> classesInPackage(String pkgName) {
- assert pkgName != null;
-
- Collection<String> clsNames = new ArrayList<>();
-
- ClassLoader ldr = U.gridClassLoader();
-
- if (ldr instanceof URLClassLoader) {
- String pkgPath = pkgName.replaceAll("\\.", "/");
-
- URL[] urls = ((URLClassLoader)ldr).getURLs();
-
- for (URL url : urls) {
- String proto = url.getProtocol().toLowerCase();
-
- if ("file".equals(proto)) {
- try {
- File cpElement = new File(url.toURI());
-
- if (cpElement.isDirectory()) {
- File pkgDir = new File(cpElement, pkgPath);
-
- if (pkgDir.isDirectory()) {
- for (File file : pkgDir.listFiles()) {
- String fileName = file.getName();
-
- if (file.isFile() && fileName.toLowerCase().endsWith(".class"))
- clsNames.add(pkgName + '.' + fileName.substring(0, fileName.length() - 6));
- }
- }
- }
- else if (cpElement.isFile()) {
- try {
- JarFile jar = new JarFile(cpElement);
-
- Enumeration<JarEntry> entries = jar.entries();
-
- while (entries.hasMoreElements()) {
- String entry = entries.nextElement().getName();
-
- if (entry.startsWith(pkgPath) && entry.endsWith(".class")) {
- String clsName = entry.substring(pkgPath.length() + 1, entry.length() - 6);
-
- if (!clsName.contains("/") && !clsName.contains("\\"))
- clsNames.add(pkgName + '.' + clsName);
- }
- }
- }
- catch (IOException ignored) {
- // No-op.
- }
- }
- }
- catch (URISyntaxException ignored) {
- // No-op.
- }
- }
- }
- }
-
- return clsNames;
- }
-
- /**
- * @param cls Class.
- * @return Class descriptor.
- * @throws BinaryObjectException In case of error.
- */
- public PortableClassDescriptor descriptorForClass(Class<?> cls, boolean deserialize)
- throws BinaryObjectException {
- assert cls != null;
-
- PortableClassDescriptor desc = descByCls.get(cls);
-
- if (desc == null || !desc.registered())
- desc = registerClassDescriptor(cls, deserialize);
-
- return desc;
- }
-
- /**
- * @param userType User type or not.
- * @param typeId Type ID.
- * @param ldr Class loader.
- * @return Class descriptor.
- */
- public PortableClassDescriptor descriptorForTypeId(
- boolean userType,
- int typeId,
- ClassLoader ldr,
- boolean deserialize
- ) {
- assert typeId != GridPortableMarshaller.UNREGISTERED_TYPE_ID;
-
- //TODO: As a workaround for IGNITE-1358 we always check the predefined map before without checking 'userType'
- PortableClassDescriptor desc = predefinedTypes.get(typeId);
-
- if (desc != null)
- return desc;
-
- if (ldr == null)
- ldr = dfltLdr;
-
- // If the type hasn't been loaded by default class loader then we mustn't return the descriptor from here
- // giving a chance to a custom class loader to reload type's class.
- if (userType && ldr.equals(dfltLdr)) {
- desc = userTypes.get(typeId);
-
- if (desc != null)
- return desc;
- }
-
- Class cls;
-
- try {
- cls = marshCtx.getClass(typeId, ldr);
-
- desc = descByCls.get(cls);
- }
- catch (ClassNotFoundException e) {
- // Class might have been loaded by default class loader.
- if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null)
- return desc;
-
- throw new BinaryInvalidTypeException(e);
- }
- catch (IgniteCheckedException e) {
- // Class might have been loaded by default class loader.
- if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null)
- return desc;
-
- throw new BinaryObjectException("Failed resolve class for ID: " + typeId, e);
- }
-
- if (desc == null) {
- desc = registerClassDescriptor(cls, deserialize);
-
- assert desc.typeId() == typeId;
- }
-
- return desc;
- }
-
- /**
- * Creates and registers {@link PortableClassDescriptor} for the given {@code class}.
- *
- * @param cls Class.
- * @return Class descriptor.
- */
- private PortableClassDescriptor registerClassDescriptor(Class<?> cls, boolean deserialize) {
- PortableClassDescriptor desc;
-
- String clsName = cls.getName();
-
- if (marshCtx.isSystemType(clsName)) {
- desc = new PortableClassDescriptor(this,
- cls,
- false,
- clsName.hashCode(),
- clsName,
- null,
- BinaryInternalIdMapper.defaultInstance(),
- null,
- false,
- true, /* registered */
- false /* predefined */
- );
-
- PortableClassDescriptor old = descByCls.putIfAbsent(cls, desc);
-
- if (old != null)
- desc = old;
- }
- else
- desc = registerUserClassDescriptor(cls, deserialize);
-
- return desc;
- }
-
- /**
- * Creates and registers {@link PortableClassDescriptor} for the given user {@code class}.
- *
- * @param cls Class.
- * @return Class descriptor.
- */
- private PortableClassDescriptor registerUserClassDescriptor(Class<?> cls, boolean deserialize) {
- boolean registered;
-
- String typeName = typeName(cls.getName());
-
- BinaryIdMapper idMapper = userTypeIdMapper(typeName);
-
- int typeId = idMapper.typeId(typeName);
-
- try {
- registered = marshCtx.registerClass(typeId, cls);
- }
- catch (IgniteCheckedException e) {
- throw new BinaryObjectException("Failed to register class.", e);
- }
-
- String affFieldName = affinityFieldName(cls);
-
- PortableClassDescriptor desc = new PortableClassDescriptor(this,
- cls,
- true,
- typeId,
- typeName,
- affFieldName,
- idMapper,
- null,
- true,
- registered,
- false /* predefined */
- );
-
- if (!deserialize) {
- Collection<PortableSchema> schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null;
-
- metaHnd.addMeta(typeId,
- new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, schemas, desc.isEnum()).wrap(this));
- }
-
- // perform put() instead of putIfAbsent() because "registered" flag might have been changed or class loader
- // might have reloaded described class.
- if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr))
- userTypes.put(typeId, desc);
-
- descByCls.put(cls, desc);
-
- mappers.putIfAbsent(typeId, idMapper);
-
- return desc;
- }
-
- /**
- * @param cls Collection class.
- * @return Collection type ID.
- */
- public byte collectionType(Class<? extends Collection> cls) {
- assert cls != null;
-
- Byte type = colTypes.get(cls);
-
- if (type != null)
- return type;
-
- return Set.class.isAssignableFrom(cls) ? GridPortableMarshaller.USER_SET : GridPortableMarshaller.USER_COL;
- }
-
- /**
- * @param cls Map class.
- * @return Map type ID.
- */
- public byte mapType(Class<? extends Map> cls) {
- assert cls != null;
-
- Byte type = mapTypes.get(cls);
-
- return type != null ? type : GridPortableMarshaller.USER_COL;
- }
-
- /**
- * @param typeName Type name.
- * @return Type ID.
- */
- public int typeId(String typeName) {
- String typeName0 = typeName(typeName);
-
- Integer id = predefinedTypeNames.get(typeName0);
-
- if (id != null)
- return id;
-
- if (marshCtx.isSystemType(typeName))
- return typeName.hashCode();
-
- return userTypeIdMapper(typeName0).typeId(typeName0);
- }
-
- /**
- * @param typeId Type ID.
- * @param fieldName Field name.
- * @return Field ID.
- */
- public int fieldId(int typeId, String fieldName) {
- return userTypeIdMapper(typeId).fieldId(typeId, fieldName);
- }
-
- /**
- * @param typeId Type ID.
- * @return Instance of ID mapper.
- */
- public BinaryIdMapper userTypeIdMapper(int typeId) {
- BinaryIdMapper idMapper = mappers.get(typeId);
-
- return idMapper != null ? idMapper : BinaryInternalIdMapper.defaultInstance();
- }
-
- /**
- * @param typeName Type name.
- * @return Instance of ID mapper.
- */
- private BinaryIdMapper userTypeIdMapper(String typeName) {
- BinaryIdMapper idMapper = typeMappers.get(typeName);
-
- return idMapper != null ? idMapper : BinaryInternalIdMapper.defaultInstance();
- }
-
- /**
- * @param cls Class to get affinity field for.
- * @return Affinity field name or {@code null} if field name was not found.
- */
- private String affinityFieldName(Class cls) {
- for (; cls != Object.class && cls != null; cls = cls.getSuperclass()) {
- for (Field f : cls.getDeclaredFields()) {
- if (f.getAnnotation(AffinityKeyMapped.class) != null)
- return f.getName();
- }
- }
-
- return null;
- }
-
- /** {@inheritDoc} */
- @Override public void writeExternal(ObjectOutput out) throws IOException {
- U.writeString(out, igniteCfg.getGridName());
- }
-
- /** {@inheritDoc} */
- @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- gridName = U.readString(in);
- }
-
- /**
- * @return Portable context.
- * @throws ObjectStreamException In case of error.
- */
- protected Object readResolve() throws ObjectStreamException {
- try {
- IgniteKernal g = IgnitionEx.gridx(gridName);
-
- if (g == null)
- throw new IllegalStateException("Failed to find grid for name: " + gridName);
-
- return ((CacheObjectBinaryProcessorImpl)g.context().cacheObjects()).portableContext();
- }
- catch (IllegalStateException e) {
- throw U.withCause(new InvalidObjectException(e.getMessage()), e);
- }
- }
-
- /**
- * @param cls Class.
- * @param id Type ID.
- * @return GridPortableClassDescriptor.
- */
- public PortableClassDescriptor registerPredefinedType(Class<?> cls, int id) {
- String typeName = typeName(cls.getName());
-
- PortableClassDescriptor desc = new PortableClassDescriptor(
- this,
- cls,
- false,
- id,
- typeName,
- null,
- BinaryInternalIdMapper.defaultInstance(),
- null,
- false,
- true, /* registered */
- true /* predefined */
- );
-
- predefinedTypeNames.put(typeName, id);
- predefinedTypes.put(id, desc);
-
- descByCls.put(cls, desc);
-
- return desc;
- }
-
- /**
- * @param clsName Class name.
- * @param idMapper ID mapper.
- * @param serializer Serializer.
- * @param affKeyFieldName Affinity key field name.
- * @param isEnum If enum.
- * @throws BinaryObjectException In case of error.
- */
- @SuppressWarnings("ErrorNotRethrown")
- public void registerUserType(String clsName,
- BinaryIdMapper idMapper,
- @Nullable BinarySerializer serializer,
- @Nullable String affKeyFieldName,
- boolean isEnum)
- throws BinaryObjectException {
- assert idMapper != null;
-
- Class<?> cls = null;
-
- try {
- cls = Class.forName(clsName);
- }
- catch (ClassNotFoundException | NoClassDefFoundError ignored) {
- // No-op.
- }
-
- String typeName = typeName(clsName);
-
- int id = idMapper.typeId(typeName);
-
- //Workaround for IGNITE-1358
- if (predefinedTypes.get(id) != null)
- throw new BinaryObjectException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']');
-
- if (mappers.put(id, idMapper) != null)
- throw new BinaryObjectException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']');
-
- if (affKeyFieldName != null) {
- if (affKeyFieldNames.put(id, affKeyFieldName) != null)
- throw new BinaryObjectException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']');
- }
-
- typeMappers.put(typeName, idMapper);
-
- Map<String, Integer> fieldsMeta = null;
- Collection<PortableSchema> schemas = null;
-
- if (cls != null) {
- PortableClassDescriptor desc = new PortableClassDescriptor(
- this,
- cls,
- true,
- id,
- typeName,
- affKeyFieldName,
- idMapper,
- serializer,
- true,
- true, /* registered */
- false /* predefined */
- );
-
- fieldsMeta = desc.fieldsMeta();
- schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null;
-
- if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr))
- userTypes.put(id, desc);
-
- descByCls.put(cls, desc);
- }
-
- metaHnd.addMeta(id, new BinaryMetadata(id, typeName, fieldsMeta, affKeyFieldName, schemas, isEnum).wrap(this));
- }
-
- /**
- * Create binary field.
- *
- * @param typeId Type ID.
- * @param fieldName Field name.
- * @return Binary field.
- */
- public BinaryFieldImpl createField(int typeId, String fieldName) {
- PortableSchemaRegistry schemaReg = schemaRegistry(typeId);
-
- int fieldId = userTypeIdMapper(typeId).fieldId(typeId, fieldName);
-
- return new BinaryFieldImpl(typeId, schemaReg, fieldName, fieldId);
- }
-
- /**
- * @param typeId Type ID.
- * @return Meta data.
- * @throws BinaryObjectException In case of error.
- */
- @Nullable public BinaryType metadata(int typeId) throws BinaryObjectException {
- return metaHnd != null ? metaHnd.metadata(typeId) : null;
- }
-
- /**
- * @param typeId Type ID.
- * @return Affinity key field name.
- */
- public String affinityKeyFieldName(int typeId) {
- return affKeyFieldNames.get(typeId);
- }
-
- /**
- * @param typeId Type ID.
- * @param meta Meta data.
- * @throws BinaryObjectException In case of error.
- */
- public void updateMetadata(int typeId, BinaryMetadata meta) throws BinaryObjectException {
- metaHnd.addMeta(typeId, meta.wrap(this));
- }
-
- /**
- * @return Whether field IDs should be skipped in footer or not.
- */
- public boolean isCompactFooter() {
- return compactFooter;
- }
-
- /**
- * Get schema registry for type ID.
- *
- * @param typeId Type ID.
- * @return Schema registry for type ID.
- */
- public PortableSchemaRegistry schemaRegistry(int typeId) {
- Map<Integer, PortableSchemaRegistry> schemas0 = schemas;
-
- if (schemas0 == null) {
- synchronized (this) {
- schemas0 = schemas;
-
- if (schemas0 == null) {
- schemas0 = new HashMap<>();
-
- PortableSchemaRegistry reg = new PortableSchemaRegistry();
-
- schemas0.put(typeId, reg);
-
- schemas = schemas0;
-
- return reg;
- }
- }
- }
-
- PortableSchemaRegistry reg = schemas0.get(typeId);
-
- if (reg == null) {
- synchronized (this) {
- reg = schemas.get(typeId);
-
- if (reg == null) {
- reg = new PortableSchemaRegistry();
-
- schemas0 = new HashMap<>(schemas);
-
- schemas0.put(typeId, reg);
-
- schemas = schemas0;
- }
- }
- }
-
- return reg;
- }
-
- /**
- * Returns instance of {@link OptimizedMarshaller}.
- *
- * @return Optimized marshaller.
- */
- OptimizedMarshaller optimizedMarsh() {
- return optmMarsh;
- }
-
- /**
- * @param clsName Class name.
- * @return Type name.
- */
- @SuppressWarnings("ResultOfMethodCallIgnored")
- public static String typeName(String clsName) {
- assert clsName != null;
-
- int idx = clsName.lastIndexOf('$');
-
- if (idx == clsName.length() - 1)
- // This is a regular (not inner) class name that ends with '$'. Common use case for Scala classes.
- idx = -1;
- else if (idx >= 0) {
- String typeName = clsName.substring(idx + 1);
-
- try {
- Integer.parseInt(typeName);
-
- // This is an anonymous class. Don't cut off enclosing class name for it.
- idx = -1;
- }
- catch (NumberFormatException ignore) {
- // This is a lambda class.
- if (clsName.indexOf("$$Lambda$") > 0)
- idx = -1;
- else
- return typeName;
- }
- }
-
- if (idx < 0)
- idx = clsName.lastIndexOf('.');
-
- return idx >= 0 ? clsName.substring(idx + 1) : clsName;
- }
-
- /**
- * Undeployment callback invoked when class loader is being undeployed.
- *
- * Some marshallers may want to clean their internal state that uses the undeployed class loader somehow.
- *
- * @param ldr Class loader being undeployed.
- */
- public void onUndeploy(ClassLoader ldr) {
- for (Class<?> cls : descByCls.keySet()) {
- if (ldr.equals(cls.getClassLoader()))
- descByCls.remove(cls);
- }
-
- U.clearClassCache(ldr);
- }
-
- /**
- * Type descriptors.
- */
- private static class TypeDescriptors {
- /** Descriptors map. */
- private final Map<String, TypeDescriptor> descs = new LinkedHashMap<>();
-
- /**
- * Add type descriptor.
- *
- * @param clsName Class name.
- * @param idMapper ID mapper.
- * @param serializer Serializer.
- * @param affKeyFieldName Affinity key field name.
- * @param isEnum Enum flag.
- * @param canOverride Whether this descriptor can be override.
- * @throws BinaryObjectException If failed.
- */
- private void add(String clsName,
- BinaryIdMapper idMapper,
- BinarySerializer serializer,
- String affKeyFieldName,
- boolean isEnum,
- boolean canOverride)
- throws BinaryObjectException {
- TypeDescriptor desc = new TypeDescriptor(clsName,
- idMapper,
- serializer,
- affKeyFieldName,
- isEnum,
- canOverride);
-
- TypeDescriptor oldDesc = descs.get(clsName);
-
- if (oldDesc == null)
- descs.put(clsName, desc);
- else
- oldDesc.override(desc);
- }
-
- /**
- * Get all collected descriptors.
- *
- * @return Descriptors.
- */
- private Iterable<TypeDescriptor> descriptors() {
- return descs.values();
- }
- }
-
- /**
- * Type descriptor.
- */
- private static class TypeDescriptor {
- /** Class name. */
- private final String clsName;
-
- /** ID mapper. */
- private BinaryIdMapper idMapper;
-
- /** Serializer. */
- private BinarySerializer serializer;
-
- /** Affinity key field name. */
- private String affKeyFieldName;
-
- /** Enum flag. */
- private boolean isEnum;
-
- /** Whether this descriptor can be override. */
- private boolean canOverride;
-
- /**
- * Constructor.
- *
- * @param clsName Class name.
- * @param idMapper ID mapper.
- * @param serializer Serializer.
- * @param affKeyFieldName Affinity key field name.
- * @param isEnum Enum type.
- * @param canOverride Whether this descriptor can be override.
- */
- private TypeDescriptor(String clsName, BinaryIdMapper idMapper, BinarySerializer serializer,
- String affKeyFieldName, boolean isEnum, boolean canOverride) {
- this.clsName = clsName;
- this.idMapper = idMapper;
- this.serializer = serializer;
- this.affKeyFieldName = affKeyFieldName;
- this.isEnum = isEnum;
- this.canOverride = canOverride;
- }
-
- /**
- * Override portable class descriptor.
- *
- * @param other Other descriptor.
- * @throws BinaryObjectException If failed.
- */
- private void override(TypeDescriptor other) throws BinaryObjectException {
- assert clsName.equals(other.clsName);
-
- if (canOverride) {
- idMapper = other.idMapper;
- serializer = other.serializer;
- affKeyFieldName = other.affKeyFieldName;
- canOverride = other.canOverride;
- }
- else if (!other.canOverride)
- throw new BinaryObjectException("Duplicate explicit class definition in configuration: " + clsName);
- }
- }
-
- /**
- * Type id wrapper.
- */
- static class Type {
- /** Type id */
- private final int id;
-
- /** Whether the following type is registered in a cache or not */
- private final boolean registered;
-
- /**
- * @param id Id.
- * @param registered Registered.
- */
- public Type(int id, boolean registered) {
- this.id = id;
- this.registered = registered;
- }
-
- /**
- * @return Type ID.
- */
- public int id() {
- return id;
- }
-
- /**
- * @return Registered flag value.
- */
- public boolean registered() {
- return registered;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePositionReadable.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePositionReadable.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePositionReadable.java
deleted file mode 100644
index c49c898..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePositionReadable.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-/**
- * Interface allowing for positioned read.
- */
-public interface PortablePositionReadable {
- /**
- * Read byte at the given position.
- *
- * @param pos Position.
- * @return Value.
- */
- public byte readBytePositioned(int pos);
-
- /**
- * Read short at the given position.
- *
- * @param pos Position.
- * @return Value.
- */
- public short readShortPositioned(int pos);
-
- /**
- * Read integer at the given position.
- *
- * @param pos Position.
- * @return Value.
- */
- public int readIntPositioned(int pos);
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java
deleted file mode 100644
index 02f552a..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-import org.apache.ignite.internal.util.GridUnsafe;
-import sun.misc.Unsafe;
-
-import java.nio.ByteOrder;
-
-/**
- * Primitives writer.
- */
-public abstract class PortablePrimitives {
- /** */
- private static final Unsafe UNSAFE = GridUnsafe.unsafe();
-
- /** */
- private static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class);
-
- /** */
- private static final long CHAR_ARR_OFF = UNSAFE.arrayBaseOffset(char[].class);
-
- /** Whether little endian is set. */
- private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param val Value.
- */
- public static void writeByte(byte[] arr, int off, byte val) {
- UNSAFE.putByte(arr, BYTE_ARR_OFF + off, val);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static byte readByte(byte[] arr, int off) {
- return UNSAFE.getByte(arr, BYTE_ARR_OFF + off);
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static byte readByte(long ptr, int off) {
- return UNSAFE.getByte(ptr + off);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static byte[] readByteArray(byte[] arr, int off, int len) {
- byte[] arr0 = new byte[len];
-
- UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, BYTE_ARR_OFF, len);
-
- return arr0;
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static byte[] readByteArray(long ptr, int off, int len) {
- byte[] arr0 = new byte[len];
-
- UNSAFE.copyMemory(null, ptr + off, arr0, BYTE_ARR_OFF, len);
-
- return arr0;
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param val Value.
- */
- public static void writeBoolean(byte[] arr, int off, boolean val) {
- writeByte(arr, off, val ? (byte)1 : (byte)0);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static boolean readBoolean(byte[] arr, int off) {
- return readByte(arr, off) == 1;
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static boolean readBoolean(long ptr, int off) {
- return readByte(ptr, off) == 1;
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param val Value.
- */
- public static void writeShort(byte[] arr, int off, short val) {
- if (BIG_ENDIAN)
- val = Short.reverseBytes(val);
-
- UNSAFE.putShort(arr, BYTE_ARR_OFF + off, val);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static short readShort(byte[] arr, int off) {
- short val = UNSAFE.getShort(arr, BYTE_ARR_OFF + off);
-
- if (BIG_ENDIAN)
- val = Short.reverseBytes(val);
-
- return val;
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static short readShort(long ptr, int off) {
- short val = UNSAFE.getShort(ptr + off);
-
- if (BIG_ENDIAN)
- val = Short.reverseBytes(val);
-
- return val;
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param val Value.
- */
- public static void writeChar(byte[] arr, int off, char val) {
- if (BIG_ENDIAN)
- val = Character.reverseBytes(val);
-
- UNSAFE.putChar(arr, BYTE_ARR_OFF + off, val);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static char readChar(byte[] arr, int off) {
- char val = UNSAFE.getChar(arr, BYTE_ARR_OFF + off);
-
- if (BIG_ENDIAN)
- val = Character.reverseBytes(val);
-
- return val;
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static char readChar(long ptr, int off) {
- char val = UNSAFE.getChar(ptr + off);
-
- if (BIG_ENDIAN)
- val = Character.reverseBytes(val);
-
- return val;
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static char[] readCharArray(byte[] arr, int off, int len) {
- char[] arr0 = new char[len];
-
- UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, CHAR_ARR_OFF, len << 1);
-
- if (BIG_ENDIAN) {
- for (int i = 0; i < len; i++)
- arr0[i] = Character.reverseBytes(arr0[i]);
- }
-
- return arr0;
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static char[] readCharArray(long ptr, int off, int len) {
- char[] arr0 = new char[len];
-
- UNSAFE.copyMemory(null, ptr + off, arr0, CHAR_ARR_OFF, len << 1);
-
- if (BIG_ENDIAN) {
- for (int i = 0; i < len; i++)
- arr0[i] = Character.reverseBytes(arr0[i]);
- }
-
- return arr0;
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param val Value.
- */
- public static void writeInt(byte[] arr, int off, int val) {
- if (BIG_ENDIAN)
- val = Integer.reverseBytes(val);
-
- UNSAFE.putInt(arr, BYTE_ARR_OFF + off, val);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static int readInt(byte[] arr, int off) {
- int val = UNSAFE.getInt(arr, BYTE_ARR_OFF + off);
-
- if (BIG_ENDIAN)
- val = Integer.reverseBytes(val);
-
- return val;
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static int readInt(long ptr, int off) {
- int val = UNSAFE.getInt(ptr + off);
-
- if (BIG_ENDIAN)
- val = Integer.reverseBytes(val);
-
- return val;
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param val Value.
- */
- public static void writeLong(byte[] arr, int off, long val) {
- if (BIG_ENDIAN)
- val = Long.reverseBytes(val);
-
- UNSAFE.putLong(arr, BYTE_ARR_OFF + off, val);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static long readLong(byte[] arr, int off) {
- long val = UNSAFE.getLong(arr, BYTE_ARR_OFF + off);
-
- if (BIG_ENDIAN)
- val = Long.reverseBytes(val);
-
- return val;
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static long readLong(long ptr, int off) {
- long val = UNSAFE.getLong(ptr + off);
-
- if (BIG_ENDIAN)
- val = Long.reverseBytes(val);
-
- return val;
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param val Value.
- */
- public static void writeFloat(byte[] arr, int off, float val) {
- int val0 = Float.floatToIntBits(val);
-
- writeInt(arr, off, val0);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static float readFloat(byte[] arr, int off) {
- int val = readInt(arr, off);
-
- return Float.intBitsToFloat(val);
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static float readFloat(long ptr, int off) {
- int val = readInt(ptr, off);
-
- return Float.intBitsToFloat(val);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param val Value.
- */
- public static void writeDouble(byte[] arr, int off, double val) {
- long val0 = Double.doubleToLongBits(val);
-
- writeLong(arr, off, val0);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @return Value.
- */
- public static double readDouble(byte[] arr, int off) {
- long val = readLong(arr, off);
-
- return Double.longBitsToDouble(val);
- }
-
- /**
- * @param ptr Pointer.
- * @param off Offset.
- * @return Value.
- */
- public static double readDouble(long ptr, int off) {
- long val = readLong(ptr, off);
-
- return Double.longBitsToDouble(val);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
deleted file mode 100644
index 72a96b9..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Schema describing portable object content. We rely on the following assumptions:
- * - When amount of fields in the object is low, it is better to inline these values into int fields thus allowing
- * for quick comparisons performed within already fetched L1 cache line.
- * - When there are more fields, we store them inside a hash map.
- */
-public class PortableSchema implements Externalizable {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** Order returned if field is not found. */
- public static final int ORDER_NOT_FOUND = -1;
-
- /** Minimum sensible size. */
- private static final int MAP_MIN_SIZE = 32;
-
- /** Empty cell. */
- private static final int MAP_EMPTY = 0;
-
- /** Schema ID. */
- private int schemaId;
-
- /** IDs depending on order. */
- private int[] ids;
-
- /** Interned names of associated fields. */
- private String[] names;
-
- /** ID-to-order data. */
- private int[] idToOrderData;
-
- /** ID-to-order mask. */
- private int idToOrderMask;
-
- /** ID 1. */
- private int id0;
-
- /** ID 2. */
- private int id1;
-
- /** ID 3. */
- private int id2;
-
- /** ID 4. */
- private int id3;
-
- /**
- * {@link Externalizable} support.
- */
- public PortableSchema() {
- // No-op.
- }
-
- /**
- * Constructor.
- *
- * @param schemaId Schema ID.
- * @param fieldIds Field IDs.
- */
- private PortableSchema(int schemaId, List<Integer> fieldIds) {
- assert fieldIds != null;
-
- this.schemaId = schemaId;
-
- initialize(fieldIds);
- }
-
- /**
- * @return Schema ID.
- */
- public int schemaId() {
- return schemaId;
- }
-
- /**
- * Try speculatively confirming order for the given field name.
- *
- * @param expOrder Expected order.
- * @param expName Expected name.
- * @return Field ID.
- */
- @SuppressWarnings("StringEquality")
- public Confirmation confirmOrder(int expOrder, String expName) {
- assert expName != null;
-
- if (expOrder < names.length) {
- String name = names[expOrder];
-
- // Note that we use only reference equality assuming that field names are interned literals.
- if (name == expName)
- return Confirmation.CONFIRMED;
-
- if (name == null)
- return Confirmation.CLARIFY;
- }
-
- return Confirmation.REJECTED;
- }
-
- /**
- * Add field name.
- *
- * @param order Order.
- * @param name Name.
- */
- public void clarifyFieldName(int order, String name) {
- assert name != null;
- assert order < names.length;
-
- names[order] = name.intern();
- }
-
- /**
- * Get field ID by order in footer.
- *
- * @param order Order.
- * @return Field ID.
- */
- public int fieldId(int order) {
- return order < ids.length ? ids[order] : 0;
- }
-
- /**
- * Get field order in footer by field ID.
- *
- * @param id Field ID.
- * @return Offset or {@code 0} if there is no such field.
- */
- public int order(int id) {
- if (idToOrderData == null) {
- if (id == id0)
- return 0;
-
- if (id == id1)
- return 1;
-
- if (id == id2)
- return 2;
-
- if (id == id3)
- return 3;
-
- return ORDER_NOT_FOUND;
- }
- else {
- int idx = (id & idToOrderMask) << 1;
-
- int curId = idToOrderData[idx];
-
- if (id == curId) // Hit!
- return idToOrderData[idx + 1];
- else if (curId == MAP_EMPTY) // No such ID!
- return ORDER_NOT_FOUND;
- else {
- // Unlikely collision scenario.
- for (int i = 2; i < idToOrderData.length; i += 2) {
- int newIdx = (idx + i) % idToOrderData.length;
-
- assert newIdx < idToOrderData.length - 1;
-
- curId = idToOrderData[newIdx];
-
- if (id == curId)
- return idToOrderData[newIdx + 1];
- else if (curId == MAP_EMPTY)
- return ORDER_NOT_FOUND;
- }
-
- return ORDER_NOT_FOUND;
- }
- }
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- return schemaId;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- return o != null && o instanceof PortableSchema && schemaId == ((PortableSchema)o).schemaId;
- }
-
- /** {@inheritDoc} */
- @Override public void writeExternal(ObjectOutput out) throws IOException {
- out.writeInt(schemaId);
-
- out.writeInt(ids.length);
-
- for (Integer id : ids)
- out.writeInt(id);
- }
-
- /** {@inheritDoc} */
- @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- schemaId = in.readInt();
-
- int idsCnt = in.readInt();
-
- List<Integer> fieldIds = new ArrayList<>(idsCnt);
-
- for (int i = 0; i < idsCnt; i++)
- fieldIds.add(in.readInt());
-
- initialize(fieldIds);
- }
-
- /**
- * Parse values.
- *
- * @param vals Values.
- * @param size Proposed result size.
- * @return Parse result.
- */
- private static ParseResult parse(int[] vals, int size) {
- int mask = maskForPowerOfTwo(size);
-
- int totalSize = size * 2;
-
- int[] data = new int[totalSize];
- int collisions = 0;
-
- for (int order = 0; order < vals.length; order++) {
- int id = vals[order];
-
- assert id != 0;
-
- int idIdx = (id & mask) << 1;
-
- if (data[idIdx] == 0) {
- // Found empty slot.
- data[idIdx] = id;
- data[idIdx + 1] = order;
- }
- else {
- // Collision!
- collisions++;
-
- boolean placeFound = false;
-
- for (int i = 2; i < totalSize; i += 2) {
- int newIdIdx = (idIdx + i) % totalSize;
-
- if (data[newIdIdx] == 0) {
- data[newIdIdx] = id;
- data[newIdIdx + 1] = order;
-
- placeFound = true;
-
- break;
- }
- }
-
- assert placeFound : "Should always have a place for entry!";
- }
- }
-
- return new ParseResult(data, collisions);
- }
-
- /**
- * Get next power of two which greater or equal to the given number.
- * This implementation is not meant to be very efficient, so it is expected to be used relatively rare.
- *
- * @param val Number
- * @return Nearest pow2.
- */
- private static int nextPowerOfTwo(int val) {
- int res = 1;
-
- while (res < val)
- res = res << 1;
-
- if (res < 0)
- throw new IllegalArgumentException("Value is too big to find positive pow2: " + val);
-
- return res;
- }
-
- /**
- * Calculate mask for the given value which is a power of two.
- *
- * @param val Value.
- * @return Mask.
- */
- private static int maskForPowerOfTwo(int val) {
- int mask = 0;
- int comparand = 1;
-
- while (comparand < val) {
- mask |= comparand;
-
- comparand <<= 1;
- }
-
- return mask;
- }
-
- /**
- * Initialization routine.
- *
- * @param fieldIds Field IDs.
- */
- private void initialize(List<Integer> fieldIds) {
- ids = new int[fieldIds.size()];
-
- for (int i = 0; i < fieldIds.size(); i++)
- ids[i] = fieldIds.get(i);
-
- names = new String[fieldIds.size()];
-
- if (fieldIds.size() <= 4) {
- Iterator<Integer> iter = fieldIds.iterator();
-
- id0 = iter.hasNext() ? iter.next() : 0;
- id1 = iter.hasNext() ? iter.next() : 0;
- id2 = iter.hasNext() ? iter.next() : 0;
- id3 = iter.hasNext() ? iter.next() : 0;
- }
- else {
- id0 = id1 = id2 = id3 = 0;
-
- initializeMap(ids);
- }
- }
-
- /**
- * Initialize the map.
- *
- * @param vals Values.
- */
- private void initializeMap(int[] vals) {
- int size = Math.max(nextPowerOfTwo(vals.length) << 2, MAP_MIN_SIZE);
-
- assert size > 0;
-
- ParseResult finalRes;
-
- ParseResult res1 = parse(vals, size);
-
- if (res1.collisions == 0)
- finalRes = res1;
- else {
- ParseResult res2 = parse(vals, size * 2);
-
- // Failed to decrease aom
- if (res2.collisions == 0)
- finalRes = res2;
- else
- finalRes = parse(vals, size * 4);
- }
-
- idToOrderData = finalRes.data;
- idToOrderMask = maskForPowerOfTwo(idToOrderData.length / 2);
- }
-
- /**
- * Schema builder.
- */
- public static class Builder {
- /** Schema ID. */
- private int schemaId = PortableUtils.schemaInitialId();
-
- /** Fields. */
- private final ArrayList<Integer> fields = new ArrayList<>();
-
- /**
- * Create new schema builder.
- *
- * @return Schema builder.
- */
- public static Builder newBuilder() {
- return new Builder();
- }
-
- /**
- * Private constructor.
- */
- private Builder() {
- // No-op.
- }
-
- /**
- * Add field.
- *
- * @param fieldId Field ID.
- */
- public void addField(int fieldId) {
- fields.add(fieldId);
-
- schemaId = PortableUtils.updateSchemaId(schemaId, fieldId);
- }
-
- /**
- * Build schema.
- *
- * @return Schema.
- */
- public PortableSchema build() {
- return new PortableSchema(schemaId, fields);
- }
- }
-
- /**
- * Order confirmation result.
- */
- public enum Confirmation {
- /** Confirmed. */
- CONFIRMED,
-
- /** Denied. */
- REJECTED,
-
- /** Field name clarification is needed. */
- CLARIFY
- }
-
- /**
- * Result of map parsing.
- */
- private static class ParseResult {
- /** Data. */
- private int[] data;
-
- /** Collisions. */
- private int collisions;
-
- /**
- * Constructor.
- *
- * @param data Data.
- * @param collisions Collisions.
- */
- private ParseResult(int[] data, int collisions) {
- this.data = data;
- this.collisions = collisions;
- }
- }
-}