| /* |
| * 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.cache.affinity; |
| |
| import java.io.Externalizable; |
| import java.io.IOException; |
| import java.io.ObjectInput; |
| import java.io.ObjectOutput; |
| import org.apache.ignite.internal.processors.cache.GridCacheDefaultAffinityKeyMapper; |
| import org.apache.ignite.internal.util.tostring.GridToStringInclude; |
| import org.apache.ignite.internal.util.typedef.internal.A; |
| import org.apache.ignite.internal.util.typedef.internal.S; |
| |
| /** |
| * Optional wrapper for cache keys to provide support |
| * for custom affinity mapping. The value returned by |
| * {@link #affinityKey(Object)} method will be used for key-to-node |
| * affinity. |
| * <p> |
| * Note that the {@link #equals(Object)} and {@link #hashCode()} methods |
| * delegate directly to the wrapped cache key provided by {@link #key()} |
| * method. |
| * <p> |
| * This class is optional and does not have to be used. It only provides |
| * extra convenience whenever custom affinity mapping is required. Here is |
| * an example of how {@code Person} objects can be collocated with |
| * {@code Company} objects they belong to: |
| * <pre name="code" class="java"> |
| * Object personKey = new AffinityKey(myPersonId, myCompanyId); |
| * |
| * // Both, the company and the person objects will be cached on the same node. |
| * cache.put(myCompanyId, new Company(..)); |
| * cache.put(personKey, new Person(..)); |
| * </pre> |
| * <p> |
| * For more information and examples of cache affinity refer to |
| * {@link AffinityKeyMapper} and {@link AffinityKeyMapped @AffinityKeyMapped} |
| * documentation. |
| * @see AffinityKeyMapped |
| * @see AffinityKeyMapper |
| * @see AffinityFunction |
| */ |
| public class AffinityKey<K> implements Externalizable { |
| /** */ |
| private static final long serialVersionUID = 0L; |
| |
| /** Key. */ |
| @GridToStringInclude(sensitive = true) |
| private K key; |
| |
| /** Affinity key. */ |
| @AffinityKeyMapped |
| @GridToStringInclude(sensitive = true) |
| private Object affKey; |
| |
| /** |
| * Empty constructor. |
| */ |
| public AffinityKey() { |
| // No-op. |
| } |
| |
| /** |
| * Initializes key wrapper for a given key. If affinity key |
| * is not initialized, then this key will be used for affinity. |
| * |
| * @param key Key. |
| */ |
| public AffinityKey(K key) { |
| A.notNull(key, "key"); |
| |
| this.key = key; |
| } |
| |
| /** |
| * Initializes key together with its affinity key counter-part. |
| * |
| * @param key Key. |
| * @param affKey Affinity key. |
| */ |
| public AffinityKey(K key, Object affKey) { |
| A.notNull(key, "key"); |
| |
| this.key = key; |
| this.affKey = affKey; |
| } |
| |
| /** |
| * Gets wrapped key. |
| * |
| * @return Wrapped key. |
| */ |
| public K key() { |
| return key; |
| } |
| |
| /** |
| * Sets wrapped key. |
| * |
| * @param key Wrapped key. |
| */ |
| public void key(K key) { |
| this.key = key; |
| } |
| |
| /** |
| * Gets affinity key to use for affinity mapping. If affinity key is not provided, |
| * then {@code key} value will be returned. |
| * <p> |
| * This method is annotated with {@link AffinityKeyMapped} and will be picked up |
| * by {@link GridCacheDefaultAffinityKeyMapper} automatically. |
| * |
| * @param <T> Type of affinity key. |
| * |
| * @return Affinity key to use for affinity mapping. |
| */ |
| public <T> T affinityKey() { |
| A.notNull(key, "key"); |
| |
| return (T)(affKey == null ? key : affKey); |
| } |
| |
| /** |
| * Sets affinity key to use for affinity mapping. If affinity key is not provided, |
| * then {@code key} value will be returned. |
| * |
| * @param affKey Affinity key to use for affinity mapping. |
| */ |
| public void affinityKey(Object affKey) { |
| this.affKey = affKey; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void writeExternal(ObjectOutput out) throws IOException { |
| out.writeObject(key); |
| out.writeObject(affKey); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { |
| key = (K)in.readObject(); |
| affKey = in.readObject(); |
| } |
| |
| /** |
| * Hash code implementation which delegates to the underlying {@link #key()}. Note, however, |
| * that different subclasses of {@link AffinityKey} will produce different hash codes. |
| * <p> |
| * Users should override this method if different behavior is desired. |
| * |
| * @return Hash code. |
| */ |
| @Override public int hashCode() { |
| A.notNull(key, "key"); |
| |
| return 31 * key.hashCode() + getClass().getName().hashCode(); |
| } |
| |
| /** |
| * Equality check which delegates to the underlying key equality. Note, however, that |
| * different subclasses of {@link AffinityKey} will never be equal. |
| * <p> |
| * Users should override this method if different behavior is desired. |
| * |
| * @param obj Object to check for equality. |
| * @return {@code True} if objects are equal. |
| */ |
| @Override public boolean equals(Object obj) { |
| A.notNull(key, "key"); |
| |
| return obj != null && getClass() == obj.getClass() && key.equals(((AffinityKey)obj).key); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public String toString() { |
| return S.toString(AffinityKey.class, this); |
| } |
| } |