/*
* 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.platform.cache.affinity;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.affinity.Affinity;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
import org.apache.ignite.internal.binary.BinaryRawReaderEx;
import org.apache.ignite.internal.binary.BinaryRawWriterEx;
import org.apache.ignite.internal.processors.platform.PlatformAbstractTarget;
import org.apache.ignite.internal.processors.platform.PlatformContext;
import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;
/**
* Native cache wrapper implementation.
*/
@SuppressWarnings({"unchecked", "UnusedDeclaration", "TryFinallyCanBeTryWithResources"})
public class PlatformAffinity extends PlatformAbstractTarget {
/** */
public static final int OP_AFFINITY_KEY = 1;
/** */
public static final int OP_ALL_PARTITIONS = 2;
/** */
public static final int OP_BACKUP_PARTITIONS = 3;
/** */
public static final int OP_IS_BACKUP = 4;
/** */
public static final int OP_IS_PRIMARY = 5;
/** */
public static final int OP_IS_PRIMARY_OR_BACKUP = 6;
/** */
public static final int OP_MAP_KEY_TO_NODE = 7;
/** */
public static final int OP_MAP_KEY_TO_PRIMARY_AND_BACKUPS = 8;
/** */
public static final int OP_MAP_KEYS_TO_NODES = 9;
/** */
public static final int OP_MAP_PARTITION_TO_NODE = 10;
/** */
public static final int OP_MAP_PARTITION_TO_PRIMARY_AND_BACKUPS = 11;
/** */
public static final int OP_MAP_PARTITIONS_TO_NODES = 12;
/** */
public static final int OP_PARTITION = 13;
/** */
public static final int OP_PRIMARY_PARTITIONS = 14;
/** */
public static final int OP_PARTITIONS = 15;
/** */
private static final C1<ClusterNode, UUID> TO_NODE_ID = new C1<ClusterNode, UUID>() {
@Nullable @Override public UUID apply(ClusterNode node) {
return node != null ? node.id() : null;
}
};
/** Underlying cache affinity. */
private final Affinity<Object> aff;
/** Discovery manager */
private final GridDiscoveryManager discovery;
/**
* Constructor.
*
* @param platformCtx Context.
* @param igniteCtx Ignite context.
* @param name Cache name.
*/
public PlatformAffinity(PlatformContext platformCtx, GridKernalContext igniteCtx, @Nullable String name)
throws IgniteCheckedException {
super(platformCtx);
this.aff = igniteCtx.grid().affinity(name);
if (aff == null)
throw new IgniteCheckedException("Cache with the given name doesn't exist: " + name);
discovery = igniteCtx.discovery();
}
/** {@inheritDoc} */
@Override public long processInStreamOutLong(int type, BinaryRawReaderEx reader) throws IgniteCheckedException {
switch (type) {
case OP_PARTITION:
return aff.partition(reader.readObjectDetached());
case OP_IS_PRIMARY: {
UUID nodeId = reader.readUuid();
Object key = reader.readObjectDetached();
ClusterNode node = discovery.node(nodeId);
if (node == null)
return FALSE;
return aff.isPrimary(node, key) ? TRUE : FALSE;
}
case OP_IS_BACKUP: {
UUID nodeId = reader.readUuid();
Object key = reader.readObjectDetached();
ClusterNode node = discovery.node(nodeId);
if (node == null)
return FALSE;
return aff.isBackup(node, key) ? TRUE : FALSE;
}
case OP_IS_PRIMARY_OR_BACKUP: {
UUID nodeId = reader.readUuid();
Object key = reader.readObjectDetached();
ClusterNode node = discovery.node(nodeId);
if (node == null)
return FALSE;
return aff.isPrimaryOrBackup(node, key) ? TRUE : FALSE;
}
default:
return super.processInStreamOutLong(type, reader);
}
}
/** {@inheritDoc} */
@SuppressWarnings({"IfMayBeConditional", "ConstantConditions"})
@Override public void processInStreamOutStream(int type, BinaryRawReaderEx reader, BinaryRawWriterEx writer)
throws IgniteCheckedException {
switch (type) {
case OP_PRIMARY_PARTITIONS: {
UUID nodeId = reader.readObject();
ClusterNode node = discovery.node(nodeId);
int[] parts = node != null ? aff.primaryPartitions(node) : U.EMPTY_INTS;
writer.writeIntArray(parts);
break;
}
case OP_BACKUP_PARTITIONS: {
UUID nodeId = reader.readObject();
ClusterNode node = discovery.node(nodeId);
int[] parts = node != null ? aff.backupPartitions(node) : U.EMPTY_INTS;
writer.writeIntArray(parts);
break;
}
case OP_ALL_PARTITIONS: {
UUID nodeId = reader.readObject();
ClusterNode node = discovery.node(nodeId);
int[] parts = node != null ? aff.allPartitions(node) : U.EMPTY_INTS;
writer.writeIntArray(parts);
break;
}
case OP_AFFINITY_KEY: {
Object key = reader.readObjectDetached();
writer.writeObject(aff.affinityKey(key));
break;
}
case OP_MAP_KEY_TO_NODE: {
Object key = reader.readObjectDetached();
ClusterNode node = aff.mapKeyToNode(key);
platformCtx.writeNode(writer, node);
break;
}
case OP_MAP_PARTITION_TO_NODE: {
int part = reader.readObject();
ClusterNode node = aff.mapPartitionToNode(part);
platformCtx.writeNode(writer, node);
break;
}
case OP_MAP_KEY_TO_PRIMARY_AND_BACKUPS: {
Object key = reader.readObjectDetached();
platformCtx.writeNodes(writer, aff.mapKeyToPrimaryAndBackups(key));
break;
}
case OP_MAP_PARTITION_TO_PRIMARY_AND_BACKUPS: {
int part = reader.readObject();
platformCtx.writeNodes(writer, aff.mapPartitionToPrimaryAndBackups(part));
break;
}
case OP_MAP_KEYS_TO_NODES: {
Collection<Object> keys = PlatformUtils.readCollection(reader);
Map<ClusterNode, Collection<Object>> map = aff.mapKeysToNodes(keys);
writer.writeInt(map.size());
for (Map.Entry<ClusterNode, Collection<Object>> e : map.entrySet()) {
platformCtx.addNode(e.getKey());
writer.writeUuid(e.getKey().id());
writer.writeObject(e.getValue());
}
break;
}
case OP_MAP_PARTITIONS_TO_NODES: {
Collection<Integer> parts = PlatformUtils.readCollection(reader);
Map<Integer, ClusterNode> map = aff.mapPartitionsToNodes(parts);
writer.writeInt(map.size());
for (Map.Entry<Integer, ClusterNode> e : map.entrySet()) {
platformCtx.addNode(e.getValue());
writer.writeInt(e.getKey());
writer.writeUuid(e.getValue().id());
}
break;
}
default:
super.processInStreamOutStream(type, reader, writer);
}
}
/** {@inheritDoc} */
@Override public long processInLongOutLong(int type, long val) throws IgniteCheckedException {
if (type == OP_PARTITIONS)
return aff.partitions();
return super.processInLongOutLong(type, val);
}
}