IGNITE-5458: Added CacheConfiguration.keyConfiguration property and fixed affinity...
authordevozerov <vozerov@gridgain.com>
Wed, 14 Jun 2017 15:29:17 +0000 (18:29 +0300)
committerdevozerov <vozerov@gridgain.com>
Wed, 14 Jun 2017 15:29:17 +0000 (18:29 +0300)
19 files changed:
modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheDefaultBinaryAffinityKeyMapper.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheDefaultBinaryAffinityKeyMapper.java [deleted file]
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryContext.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java
modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
modules/core/src/main/java/org/apache/ignite/internal/processors/query/DynamicTableAffinityKeyMapper.java [deleted file]
modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
modules/core/src/main/resources/META-INF/classnames.properties
modules/core/src/test/java/org/apache/ignite/internal/binary/GridDefaultBinaryMappersBinaryMetaDataSelfTest.java
modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCache150ClientsTest.java
modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java

index 6e0836e..670046f 100644 (file)
@@ -47,6 +47,7 @@ import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheEntryProcessor;
 import org.apache.ignite.cache.CacheInterceptor;
+import org.apache.ignite.cache.CacheKeyConfiguration;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.CacheRebalanceMode;
 import org.apache.ignite.cache.CacheWriteSynchronizationMode;
@@ -65,6 +66,7 @@ import org.apache.ignite.cache.query.annotations.QueryTextField;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.CacheStoreSessionListener;
 import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.binary.BinaryContext;
 import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
 import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -369,6 +371,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
     /** */
     private int qryParallelism = DFLT_QUERY_PARALLELISM;
 
+    /** Cache key configuration. */
+    private CacheKeyConfiguration[] keyCfg;
+
     /** Empty constructor (all values are initialized to their defaults). */
     public CacheConfiguration() {
         /* No-op. */
@@ -416,23 +421,22 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         interceptor = cc.getInterceptor();
         invalidate = cc.isInvalidate();
         isReadThrough = cc.isReadThrough();
-        qryParallelism = cc.getQueryParallelism();
         isWriteThrough = cc.isWriteThrough();
-        storeKeepBinary = cc.isStoreKeepBinary() != null ? cc.isStoreKeepBinary() : DFLT_STORE_KEEP_BINARY;
+        keyCfg = cc.getKeyConfiguration();
         listenerConfigurations = cc.listenerConfigurations;
         loadPrevVal = cc.isLoadPreviousValue();
         longQryWarnTimeout = cc.getLongQueryWarningTimeout();
         maxConcurrentAsyncOps = cc.getMaxConcurrentAsyncOperations();
         memPlcName = cc.getMemoryPolicyName();
-        sqlIdxMaxInlineSize = cc.getSqlIndexMaxInlineSize();
         name = cc.getName();
         nearCfg = cc.getNearConfiguration();
         nodeFilter = cc.getNodeFilter();
         onheapCache = cc.isOnheapCacheEnabled();
         partLossPlc = cc.getPartitionLossPolicy();
         pluginCfgs = cc.getPluginConfigurations();
-        qryEntities = cc.getQueryEntities() == Collections.<QueryEntity>emptyList() ? null : cc.getQueryEntities();
         qryDetailMetricsSz = cc.getQueryDetailMetricsSize();
+        qryEntities = cc.getQueryEntities() == Collections.<QueryEntity>emptyList() ? null : cc.getQueryEntities();
+        qryParallelism = cc.getQueryParallelism();
         readFromBackup = cc.isReadFromBackup();
         rebalanceBatchSize = cc.getRebalanceBatchSize();
         rebalanceBatchesPrefetchCnt = cc.getRebalanceBatchesPrefetchCount();
@@ -445,7 +449,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         sqlSchema = cc.getSqlSchema();
         sqlEscapeAll = cc.isSqlEscapeAll();
         sqlFuncCls = cc.getSqlFunctionClasses();
+        sqlIdxMaxInlineSize = cc.getSqlIndexMaxInlineSize();
         storeFactory = cc.getCacheStoreFactory();
+        storeKeepBinary = cc.isStoreKeepBinary() != null ? cc.isStoreKeepBinary() : DFLT_STORE_KEEP_BINARY;
         storeSesLsnrs = cc.getCacheStoreSessionListenerFactories();
         tmLookupClsName = cc.getTransactionManagerLookupClassName();
         topValidator = cc.getTopologyValidator();
@@ -1778,6 +1784,37 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
 
             if (!dup)
                 qryEntities.add(converted);
+
+            // Set key configuration if needed.
+            String affFieldName = desc.affinityFieldName();
+
+            if (affFieldName != null) {
+                CacheKeyConfiguration newKeyCfg = new CacheKeyConfiguration(converted.getKeyType(), affFieldName);
+
+                if (F.isEmpty(keyCfg))
+                    keyCfg = new CacheKeyConfiguration[] { newKeyCfg };
+                else {
+                    boolean keyCfgDup = false;
+
+                    for (CacheKeyConfiguration oldKeyCfg : keyCfg) {
+                        if (F.eq(oldKeyCfg.getTypeName(), newKeyCfg.getTypeName())) {
+                            keyCfgDup = true;
+
+                            break;
+                        }
+                    }
+
+                    if (!keyCfgDup) {
+                        CacheKeyConfiguration[] keyCfg0 = new CacheKeyConfiguration[keyCfg.length + 1];
+
+                        System.arraycopy(keyCfg, 0, keyCfg0, 0, keyCfg.length);
+
+                        keyCfg0[keyCfg0.length - 1] = newKeyCfg;
+
+                        keyCfg = keyCfg0;
+                    }
+                }
+            }
         }
 
         return this;
@@ -2105,6 +2142,8 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         d.keyClass(keyCls);
         d.valueClass(valCls);
 
+        d.affinityFieldName(BinaryContext.affinityFieldName(keyCls));
+
         processAnnotationsInClass(true, d.keyCls, d, null);
         processAnnotationsInClass(false, d.valCls, d, null);
 
@@ -2289,6 +2328,26 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         return this;
     }
 
+    /**
+     * Gets cache key configuration.
+     *
+     * @return Cache key configuration.
+     */
+    public CacheKeyConfiguration[] getKeyConfiguration() {
+        return keyCfg;
+    }
+
+    /**
+     * Sets cache key configuration.
+     *
+     * @param cacheKeyCfg Cache key configuration.
+     */
+    public CacheConfiguration<K, V> setKeyConfiguration(CacheKeyConfiguration... cacheKeyCfg) {
+        this.keyCfg = cacheKeyCfg;
+
+        return this;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(CacheConfiguration.class, this);
@@ -2349,6 +2408,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         /** */
         private boolean valTextIdx;
 
+        /** Affinity field name. */
+        private String affFieldName;
+
         /**
          * @return Indexes.
          */
@@ -2450,6 +2512,20 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         }
 
         /**
+         * @return Affinity field name.
+         */
+        @Nullable public String affinityFieldName() {
+            return affFieldName;
+        }
+
+        /**
+         * @param affFieldName Affinity field name.
+         */
+        private void affinityFieldName(@Nullable String affFieldName) {
+            this.affFieldName = affFieldName;
+        }
+
+        /**
          * Adds property to the type descriptor.
          *
          * @param prop Property.
index 27cccaa..26dc4c4 100644 (file)
@@ -70,7 +70,9 @@ public class BinaryCachingMetadataHandler implements BinaryMetadataHandler {
 
     /** {@inheritDoc} */
     @Override public synchronized BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
-        return ((BinaryTypeImpl)metas.get(typeId)).metadata();
+        BinaryTypeImpl type = (BinaryTypeImpl)metas.get(typeId);
+
+        return type != null ? type.metadata() : null;
     }
 
     /** {@inheritDoc} */
index be02ba1..fa051f5 100644 (file)
@@ -324,7 +324,9 @@ public class BinaryContext {
         registerPredefinedType(LinkedHashMap.class, 0);
 
         // Classes with overriden default serialization flag.
-        registerPredefinedType(AffinityKey.class, 0, affinityFieldName(AffinityKey.class), false);
+        registerPredefinedType(AffinityKey.class, 0, affinityFieldName(AffinityKey.class), true);
+        registerPredefinedType(CollocatedSetItemKey.class, 0, affinityFieldName(CollocatedSetItemKey.class), true);
+        registerPredefinedType(CollocatedQueueItemKey.class, 0, affinityFieldName(CollocatedQueueItemKey.class), true);
 
         registerPredefinedType(GridMapEntry.class, 60);
         registerPredefinedType(IgniteBiTuple.class, 61);
@@ -458,13 +460,19 @@ public class BinaryContext {
                 if (clsName.endsWith(".*")) {
                     String pkgName = clsName.substring(0, clsName.length() - 2);
 
-                    for (String clsName0 : classesInPackage(pkgName))
-                        descs.add(clsName0, mapper, serializer, identity, affFields.get(clsName0),
+                    for (String clsName0 : classesInPackage(pkgName)) {
+                        String affField = affFields.remove(clsName0);
+
+                        descs.add(clsName0, mapper, serializer, identity, affField,
                             typeCfg.isEnum(), typeCfg.getEnumValues(), true);
+                    }
                 }
-                else
-                    descs.add(clsName, mapper, serializer, identity, affFields.get(clsName),
+                else {
+                    String affField = affFields.remove(clsName);
+
+                    descs.add(clsName, mapper, serializer, identity, affField,
                         typeCfg.isEnum(), typeCfg.getEnumValues(), false);
+                }
             }
         }
 
@@ -482,9 +490,6 @@ public class BinaryContext {
 
             affKeyFieldNames.putIfAbsent(typeId, entry.getValue());
         }
-
-        addSystemClassAffinityKey(CollocatedSetItemKey.class);
-        addSystemClassAffinityKey(CollocatedQueueItemKey.class);
     }
 
     /**
@@ -534,17 +539,6 @@ public class BinaryContext {
     }
 
     /**
-     * @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.
      */
@@ -1032,7 +1026,7 @@ public class BinaryContext {
      * @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) {
+    public static String affinityFieldName(Class cls) {
         for (; cls != Object.class && cls != null; cls = cls.getSuperclass()) {
             for (Field f : cls.getDeclaredFields()) {
                 if (f.getAnnotation(AffinityKeyMapped.class) != null)
@@ -1244,11 +1238,22 @@ public class BinaryContext {
     }
 
     /**
+     * Get affinity key field name for type. First consult to predefined configuration, then delegate to metadata.
+     *
      * @param typeId Type ID.
      * @return Affinity key field name.
      */
     public String affinityKeyFieldName(int typeId) {
-        return affKeyFieldNames.get(typeId);
+        String res = affKeyFieldNames.get(typeId);
+
+        if (res == null) {
+            BinaryMetadata meta = metaHnd.metadata0(typeId);
+
+            if (meta != null)
+                res = meta.affinityKeyFieldName();
+        }
+
+        return res;
     }
 
     /**
index d6cd5ca..fa9f1c3 100644 (file)
@@ -86,6 +86,9 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder {
     /** Context of BinaryObject reading process. Or {@code null} if object is not created from BinaryObject. */
     private final BinaryBuilderReader reader;
 
+    /** Affinity key field name. */
+    private String affFieldName;
+
     /**
      * @param clsName Class name.
      * @param ctx Binary context.
@@ -349,8 +352,13 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder {
 
                 BinarySchema curSchema = writer.currentSchema();
 
-                ctx.updateMetadata(typeId, new BinaryMetadata(typeId, typeName, fieldsMeta,
-                    ctx.affinityKeyFieldName(typeId), Collections.singleton(curSchema), false, null));
+                String affFieldName0 = affFieldName;
+
+                if (affFieldName0 == null)
+                    affFieldName0 = ctx.affinityKeyFieldName(typeId);
+
+                ctx.updateMetadata(typeId, new BinaryMetadata(typeId, typeName, fieldsMeta, affFieldName0,
+                    Collections.singleton(curSchema), false, null));
 
                 schemaReg.addSchema(curSchema.schemaId(), curSchema);
             }
@@ -618,4 +626,13 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder {
     public int typeId() {
         return typeId;
     }
+
+    /**
+     * Set known affinity key field name.
+     *
+     * @param affFieldName Affinity key field name.
+     */
+    public void affinityFieldName(String affFieldName) {
+        this.affFieldName = affFieldName;
+    }
 }
index 9b3dd15..4350687 100644 (file)
@@ -19,10 +19,18 @@ package org.apache.ignite.internal.processors.cache;
 
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.binary.BinaryField;
 import org.apache.ignite.binary.BinaryObject;
+import org.apache.ignite.cache.CacheKeyConfiguration;
 import org.apache.ignite.internal.IgniteKernal;
+import org.apache.ignite.internal.binary.BinaryObjectEx;
 import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  *
@@ -34,6 +42,24 @@ public class CacheDefaultBinaryAffinityKeyMapper extends GridCacheDefaultAffinit
     /** */
     private CacheObjectBinaryProcessorImpl proc;
 
+    /** Mapping from type name to affinity field name. */
+    private Map<String, String> typeNameAffFields = new HashMap<>();
+
+    /** Mapping from type ID to affinity field name. */
+    private volatile transient Map<Integer, BinaryField> typeIdAffFields;
+
+    /**
+     * Constructor.
+     *
+     * @param cacheKeyCfgs Cache key configurations.
+     */
+    public CacheDefaultBinaryAffinityKeyMapper(@Nullable CacheKeyConfiguration[] cacheKeyCfgs) {
+        if (!F.isEmpty(cacheKeyCfgs)) {
+            for (CacheKeyConfiguration cacheKeyCfg : cacheKeyCfgs)
+                typeNameAffFields.put(cacheKeyCfg.getTypeName(), cacheKeyCfg.getAffinityKeyFieldName());
+        }
+    }
+
     /** {@inheritDoc} */
     @Override public Object affinityKey(Object key) {
         try {
@@ -43,12 +69,73 @@ public class CacheDefaultBinaryAffinityKeyMapper extends GridCacheDefaultAffinit
             U.error(log, "Failed to marshal key to binary: " + key, e);
         }
 
-        if (key instanceof BinaryObject)
-            return proc.affinityKey((BinaryObject)key);
+        if (key instanceof BinaryObject) {
+            assert key instanceof BinaryObjectEx : "All BinaryObject implementations must implement " +
+                BinaryObjectEx.class.getName() + ": " + key.getClass().getName();
+
+            BinaryObjectEx key0 = (BinaryObjectEx)key;
+
+            BinaryField affField = affinityKeyField(key0.typeId());
+
+            if (affField != null) {
+                Object res = affField.value(key0);
+
+                if (res != null)
+                    return res;
+            }
+
+            return key;
+        }
         else
             return super.affinityKey(key);
     }
 
+    /**
+     * Get affinity field override for type.
+     *
+     * @param typeName Type name.
+     * @return Affinity field override if any.
+     */
+    @Nullable public BinaryField affinityKeyField(String typeName) {
+        int typeId = proc.typeId(typeName);
+
+        return affinityKeyField(typeId);
+    }
+
+    /**
+     * Get affinity field override for type.
+     *
+     * @param typeId Type ID.
+     * @return Affinity field override if any.
+     */
+    @Nullable public BinaryField affinityKeyField(int typeId) {
+        Map<Integer, BinaryField> typeIdAffFields0 = typeIdAffFields;
+
+        if (typeIdAffFields0 == null) {
+            typeIdAffFields0 = new HashMap<>();
+
+            for (Map.Entry<String, String> entry : typeNameAffFields.entrySet()) {
+                String typeName = entry.getKey();
+                String affFieldName = entry.getValue();
+
+                int curTypeId = proc.typeId(typeName);
+
+                BinaryField field = proc.binaryContext().createField(curTypeId, affFieldName);
+
+                typeIdAffFields0.put(curTypeId, field);
+            }
+
+            typeIdAffFields = typeIdAffFields0;
+        }
+
+        BinaryField res = typeIdAffFields0.get(typeId);
+
+        if (res == null)
+            res = proc.affinityKeyField(typeId);
+
+        return res;
+    }
+
     /** {@inheritDoc} */
     @Override public void ignite(Ignite ignite) {
         super.ignite(ignite);
index 83f7aa0..99db152 100644 (file)
@@ -39,6 +39,8 @@ import javax.cache.expiry.ExpiryPolicy;
 import javax.cache.processor.EntryProcessorResult;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.binary.BinaryField;
+import org.apache.ignite.binary.BinaryObjectBuilder;
 import org.apache.ignite.cache.CacheInterceptor;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.affinity.AffinityKeyMapper;
@@ -51,6 +53,7 @@ import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.IgnitionEx;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl;
 import org.apache.ignite.internal.managers.communication.GridIoManager;
 import org.apache.ignite.internal.managers.deployment.GridDeploymentManager;
 import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
@@ -2071,6 +2074,31 @@ public class GridCacheContext<K, V> implements Externalizable {
         return true;
     }
 
+    /**
+     * Prepare affinity field for builder (if possible).
+     *
+     * @param buider Builder.
+     */
+    public void prepareAffinityField(BinaryObjectBuilder buider) {
+        assert binaryMarshaller();
+        assert buider instanceof BinaryObjectBuilderImpl;
+
+        BinaryObjectBuilderImpl builder0 = (BinaryObjectBuilderImpl)buider;
+
+        if (!customAffinityMapper()) {
+            CacheDefaultBinaryAffinityKeyMapper mapper =
+                (CacheDefaultBinaryAffinityKeyMapper)cacheObjCtx.defaultAffMapper();
+
+            BinaryField field = mapper.affinityKeyField(builder0.typeId());
+
+            if (field != null) {
+                String fieldName = field.name();
+
+                builder0.affinityFieldName(fieldName);
+            }
+        }
+    }
+
     /** {@inheritDoc} */
     @Override public void writeExternal(ObjectOutput out) throws IOException {
         U.writeString(out, igniteInstanceName());
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheDefaultBinaryAffinityKeyMapper.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheDefaultBinaryAffinityKeyMapper.java
deleted file mode 100644 (file)
index 0ca06e3..0000000
+++ /dev/null
@@ -1,51 +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.processors.cache.binary;
-
-import org.apache.ignite.IgniteException;
-import org.apache.ignite.internal.IgniteKernal;
-import org.apache.ignite.internal.processors.cache.GridCacheDefaultAffinityKeyMapper;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.binary.BinaryObject;
-
-/**
- *
- */
-public class CacheDefaultBinaryAffinityKeyMapper extends GridCacheDefaultAffinityKeyMapper {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** {@inheritDoc} */
-    @Override public Object affinityKey(Object key) {
-        IgniteKernal kernal = (IgniteKernal)ignite;
-
-        CacheObjectBinaryProcessorImpl proc = (CacheObjectBinaryProcessorImpl)kernal.context().cacheObjects();
-
-        try {
-            key = proc.toBinary(key);
-        }
-        catch (IgniteException e) {
-            U.error(log, "Failed to marshal key to binary: " + key, e);
-        }
-
-        if (key instanceof BinaryObject)
-            return proc.affinityKey((BinaryObject)key);
-        else
-            return super.affinityKey(key);
-    }
-}
index 3b3cf67..7f7e26e 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.cache.binary;
 
+import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.processors.cache.CacheDefaultBinaryAffinityKeyMapper;
 import org.apache.ignite.internal.processors.cache.CacheObjectContext;
@@ -31,21 +32,22 @@ public class CacheObjectBinaryContext extends CacheObjectContext {
 
     /**
      * @param kernalCtx Kernal context.
-     * @param cacheName Cache name.
+     * @param ccfg Cache configuration.
      * @param binaryEnabled Binary enabled flag.
      * @param cpyOnGet Copy on get flag.
      * @param storeVal {@code True} if should store unmarshalled value in cache.
      * @param depEnabled {@code true} if deployment is enabled for the given cache.
      */
     public CacheObjectBinaryContext(GridKernalContext kernalCtx,
-        String cacheName,
+        CacheConfiguration ccfg,
         boolean cpyOnGet,
         boolean storeVal,
         boolean binaryEnabled,
         boolean depEnabled) {
         super(kernalCtx,
-            cacheName,
-            binaryEnabled ? new CacheDefaultBinaryAffinityKeyMapper() : new GridCacheDefaultAffinityKeyMapper(),
+            ccfg.getName(),
+            binaryEnabled ? new CacheDefaultBinaryAffinityKeyMapper(ccfg.getKeyConfiguration()) :
+                new GridCacheDefaultAffinityKeyMapper(),
             cpyOnGet,
             storeVal,
             depEnabled);
index f46b4bc..83e2997 100644 (file)
@@ -389,14 +389,6 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
     }
 
     /** {@inheritDoc} */
-    @Override public String affinityField(String keyType) {
-        if (binaryCtx == null)
-            return null;
-
-        return binaryCtx.affinityKeyFieldName(typeId(keyType));
-    }
-
-    /** {@inheritDoc} */
     @Override public BinaryObjectBuilder builder(String clsName) {
         return new BinaryObjectBuilderImpl(binaryCtx, clsName);
     }
@@ -636,54 +628,33 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
     }
 
     /**
-     * @param po Binary object.
+     * Get affinity key field.
+     *
+     * @param typeId Binary object type ID.
      * @return Affinity key.
      */
-    public Object affinityKey(BinaryObject po) {
+    public BinaryField affinityKeyField(int typeId) {
         // Fast path for already cached field.
-        if (po instanceof BinaryObjectEx) {
-            int typeId = ((BinaryObjectEx)po).typeId();
+        T1<BinaryField> fieldHolder = affKeyFields.get(typeId);
 
-            T1<BinaryField> fieldHolder = affKeyFields.get(typeId);
-
-            if (fieldHolder != null) {
-                BinaryField field = fieldHolder.get();
-
-                return field != null ? field.value(po) : po;
-            }
-        }
+        if (fieldHolder != null)
+            return fieldHolder.get();
 
         // Slow path if affinity field is not cached yet.
-        try {
-            BinaryType meta = po instanceof BinaryObjectEx ? ((BinaryObjectEx)po).rawType() : po.type();
+        String name = binaryCtx.affinityKeyFieldName(typeId);
 
-            if (meta != null) {
-                String name = meta.affinityKeyFieldName();
+        if (name != null) {
+            BinaryField field = binaryCtx.createField(typeId, name);
 
-                if (name != null) {
-                    BinaryField field = meta.field(name);
+            affKeyFields.putIfAbsent(typeId, new T1<>(field));
 
-                    affKeyFields.putIfAbsent(meta.typeId(), new T1<>(field));
-
-                    return field.value(po);
-                }
-                else
-                    affKeyFields.putIfAbsent(meta.typeId(), new T1<BinaryField>(null));
-            }
-            else if (po instanceof BinaryObjectEx) {
-                int typeId = ((BinaryObjectEx)po).typeId();
-
-                String name = binaryCtx.affinityKeyFieldName(typeId);
-
-                if (name != null)
-                    return po.field(name);
-            }
-        }
-        catch (BinaryObjectException e) {
-            U.error(log, "Failed to get affinity field from binary object: " + po, e);
+            return field;
         }
+        else {
+            affKeyFields.putIfAbsent(typeId, new T1<BinaryField>(null));
 
-        return po;
+            return null;
+        }
     }
 
     /** {@inheritDoc} */
@@ -724,7 +695,7 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
         CacheObjectContext ctx0 = super.contextForCache(cfg);
 
         CacheObjectContext res = new CacheObjectBinaryContext(ctx,
-            cfg.getName(),
+            cfg,
             ctx0.copyOnGet(),
             ctx0.storeValue(),
             binaryEnabled,
index ee2d1f2..ae6428e 100644 (file)
@@ -211,10 +211,4 @@ public interface IgniteCacheObjectProcessor extends GridProcessor {
      * @return Ignite binary interface.
      */
     public IgniteBinary binary();
-
-    /**
-     * @param keyType Key type name.
-     * @return Affinity filed name or {@code null}.
-     */
-    public String affinityField(String keyType);
 }
index de9256c..67e14dc 100644 (file)
@@ -82,11 +82,6 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
     }
 
     /** {@inheritDoc} */
-    @Override public String affinityField(String keyType) {
-        return null;
-    }
-
-    /** {@inheritDoc} */
     @Override public IgniteBinary binary() {
         return noOpBinary;
     }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/DynamicTableAffinityKeyMapper.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/DynamicTableAffinityKeyMapper.java
deleted file mode 100644 (file)
index e49341a..0000000
+++ /dev/null
@@ -1,92 +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.processors.query;
-
-import org.apache.ignite.binary.BinaryObject;
-import org.apache.ignite.binary.BinaryType;
-import org.apache.ignite.cache.affinity.AffinityKeyMapper;
-import org.apache.ignite.internal.binary.BinaryFieldEx;
-import org.apache.ignite.internal.binary.BinaryObjectEx;
-import org.apache.ignite.internal.util.typedef.F;
-
-/**
- * Trivial mapper to take extract field value from binary object of specific type as affinity key.
- */
-@SuppressWarnings("deprecation")
-public class DynamicTableAffinityKeyMapper implements AffinityKeyMapper {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Type name. */
-    private final String typeName;
-
-    /** Field name. */
-    private final String fieldName;
-
-    /** Type id for faster type checks. */
-    private transient volatile BinaryFieldEx field;
-
-    /**
-     * Constructor.
-     *
-     * @param typeName Type name.
-     * @param fieldName Field name.
-     */
-    DynamicTableAffinityKeyMapper(String typeName, String fieldName) {
-        this.typeName = typeName;
-        this.fieldName = fieldName;
-    }
-
-    /**
-     * @return Field name.
-     */
-    public String fieldName() {
-        return fieldName;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Object affinityKey(Object key) {
-        if (!(key instanceof BinaryObject))
-            return key;
-
-        assert key instanceof BinaryObjectEx;
-
-        BinaryObjectEx key0 = (BinaryObjectEx)key;
-
-        if (field == null) {
-            BinaryType type = key0.type();
-
-            if (!F.eq(type.typeName(), typeName))
-                return key;
-
-            field = (BinaryFieldEx)type.field(fieldName);
-        }
-
-        if (!F.eq(key0.typeId(), field.typeId()))
-            return key;
-
-        Object affKey = field.value(key0);
-
-        return affKey != null ? affKey : key;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void reset() {
-        // No-op.
-    }
-}
index 6079ae8..b9060ed 100644 (file)
@@ -41,6 +41,7 @@ import org.apache.ignite.IgniteDataStreamer;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.binary.Binarylizable;
 import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheKeyConfiguration;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.QueryIndex;
@@ -1341,11 +1342,8 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         ccfg.setSqlEscapeAll(true);
         ccfg.setQueryEntities(Collections.singleton(entity));
 
-        if (affinityKey != null) {
-            assert entity.getFields().containsKey(affinityKey) && entity.getKeyFields().contains(affinityKey);
-
-            ccfg.setAffinityMapper(new DynamicTableAffinityKeyMapper(entity.getKeyType(), affinityKey));
-        }
+        if (affinityKey != null)
+            ccfg.setKeyConfiguration(new CacheKeyConfiguration(entity.getKeyType(), affinityKey));
 
         boolean res;
 
index e0815fd..cb9a1e1 100644 (file)
@@ -32,6 +32,7 @@ import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.binary.BinaryField;
 import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.QueryIndex;
 import org.apache.ignite.cache.QueryIndexType;
@@ -39,6 +40,7 @@ import org.apache.ignite.cache.affinity.AffinityKeyMapper;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.internal.processors.cache.CacheDefaultBinaryAffinityKeyMapper;
 import org.apache.ignite.internal.processors.cache.CacheObjectContext;
 import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
@@ -430,10 +432,19 @@ public class QueryUtils {
             String affField = null;
 
             // Need to setup affinity key for distributed joins.
-            if (!cctx.customAffinityMapper() && qryEntity.findKeyType() != null)
-                affField = ctx.cacheObjects().affinityField(qryEntity.findKeyType());
-            else if (cctx.config().getAffinityMapper() instanceof DynamicTableAffinityKeyMapper)
-                affField = ((DynamicTableAffinityKeyMapper)cctx.config().getAffinityMapper()).fieldName();
+            String keyType = qryEntity.getKeyType();
+
+            if (!cctx.customAffinityMapper() && keyType != null) {
+                if (coCtx != null) {
+                    CacheDefaultBinaryAffinityKeyMapper mapper =
+                        (CacheDefaultBinaryAffinityKeyMapper)coCtx.defaultAffMapper();
+
+                    BinaryField field = mapper.affinityKeyField(keyType);
+
+                    if (field != null)
+                        affField = field.name();
+                }
+            }
 
             if (affField != null) {
                 if (!escape)
index ba2c649..b5d1261 100644 (file)
@@ -573,7 +573,6 @@ org.apache.ignite.internal.processors.cache.StoredCacheData
 org.apache.ignite.internal.processors.cache.affinity.GridCacheAffinityProxy
 org.apache.ignite.internal.processors.cache.binary.BinaryMetadataHolder
 org.apache.ignite.internal.processors.cache.binary.BinaryMetadataKey
-org.apache.ignite.internal.processors.cache.binary.CacheDefaultBinaryAffinityKeyMapper
 org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl$3
 org.apache.ignite.internal.processors.cache.binary.MetadataRequestMessage
 org.apache.ignite.internal.processors.cache.binary.MetadataResponseMessage
index 0e3f799..06fb3f4 100644 (file)
@@ -150,22 +150,6 @@ public class GridDefaultBinaryMappersBinaryMetaDataSelfTest extends GridCommonAb
             else
                 assert false : meta.typeName();
         }
-
-        grid().cache(DEFAULT_CACHE_NAME).put(new AffinityKey<>(1, 1), 1);
-
-        metas = binaries().types();
-
-        assertEquals(3, metas.size());
-
-        for (BinaryType meta : metas) {
-            if (AffinityKey.class.getSimpleName().equals(meta.typeName())) {
-                assertEquals("affKey", meta.affinityKeyFieldName());
-
-                return;
-            }
-        }
-
-        fail("Failed to find metadata for AffinityKey");
     }
 
     /**
index 3864fc5..181ddce 100644 (file)
@@ -26,6 +26,7 @@ import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.SqlConnectorConfiguration;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
@@ -71,6 +72,8 @@ public class IgniteCache150ClientsTest extends GridCommonAbstractTest {
         cfg.setClientFailureDetectionTimeout(200000);
         cfg.setClientMode(!igniteInstanceName.equals(getTestIgniteInstanceName(0)));
 
+        cfg.setSqlConnectorConfiguration(new SqlConnectorConfiguration().setPortRange(1000));
+
         CacheConfiguration[] ccfgs = new CacheConfiguration[CACHES];
 
         for (int i = 0 ; i < ccfgs.length; i++) {
index 22c3e33..b304109 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Set;
 import javax.cache.CacheException;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.binary.BinaryObject;
+import org.apache.ignite.binary.BinaryObjectBuilder;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.processors.query.GridQueryProperty;
@@ -343,7 +344,11 @@ public final class UpdatePlanBuilder {
 
                         BinaryObject bin = cctx.grid().binary().toBinary(obj);
 
-                        return cctx.grid().binary().builder(bin);
+                        BinaryObjectBuilder builder = cctx.grid().binary().builder(bin);
+
+                        cctx.prepareAffinityField(builder);
+
+                        return builder;
                     }
                 };
             }
@@ -352,7 +357,11 @@ public final class UpdatePlanBuilder {
                 return new KeyValueSupplier() {
                     /** {@inheritDoc} */
                     @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-                        return cctx.grid().binary().builder(typeName);
+                        BinaryObjectBuilder builder = cctx.grid().binary().builder(typeName);
+
+                        cctx.prepareAffinityField(builder);
+
+                        return builder;
                     }
                 };
             }
index 4f3ef01..d656cc3 100644 (file)
@@ -34,7 +34,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.KeyCacheObject;
 import org.apache.ignite.internal.processors.cache.query.QueryTable;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
-import org.apache.ignite.internal.processors.query.DynamicTableAffinityKeyMapper;
 import org.apache.ignite.internal.processors.query.h2.database.H2RowFactory;
 import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex;
 import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
@@ -131,9 +130,7 @@ public class GridH2Table extends TableBase {
         this.desc = desc;
         this.cctx = cctx;
 
-        if (desc != null && desc.context() != null &&
-            (!desc.context().customAffinityMapper() ||
-                desc.context().config().getAffinityMapper() instanceof DynamicTableAffinityKeyMapper)) {
+        if (desc != null && desc.context() != null && !desc.context().customAffinityMapper()) {
             boolean affinityColExists = true;
 
             String affKey = desc.type().affinityKey();