/* * 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.distributed.dht.preloader; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.UUID; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; /** * Full partition map. */ public class GridDhtPartitionFullMap extends HashMap<UUID, GridDhtPartitionMap> implements Comparable<GridDhtPartitionFullMap>, Externalizable { /** */ private static final long serialVersionUID = 0L; /** Node ID. */ private UUID nodeId; /** Node order. */ private long nodeOrder; /** Update sequence number. */ private long updateSeq; /** * @param nodeId Node ID. * @param nodeOrder Node order. * @param updateSeq Update sequence number. */ public GridDhtPartitionFullMap(UUID nodeId, long nodeOrder, long updateSeq) { assert nodeId != null; assert nodeOrder > 0; assert updateSeq > 0; this.nodeId = nodeId; this.nodeOrder = nodeOrder; this.updateSeq = updateSeq; } /** * @param nodeId Node ID. * @param nodeOrder Node order. * @param updateSeq Update sequence number. * @param m Map to copy. * @param onlyActive If {@code true}, then only active partitions will be included. */ public GridDhtPartitionFullMap(UUID nodeId, long nodeOrder, long updateSeq, Map<UUID, GridDhtPartitionMap> m, boolean onlyActive) { assert nodeId != null; assert updateSeq > 0; assert nodeOrder > 0; this.nodeId = nodeId; this.nodeOrder = nodeOrder; this.updateSeq = updateSeq; for (Map.Entry<UUID, GridDhtPartitionMap> e : m.entrySet()) { GridDhtPartitionMap part = e.getValue(); GridDhtPartitionMap cpy = new GridDhtPartitionMap(part.nodeId(), part.updateSequence(), part.topologyVersion(), part.map(), onlyActive); put(e.getKey(), cpy); } } /** * @param m Map to copy. * @param updateSeq Update sequence. */ public GridDhtPartitionFullMap(GridDhtPartitionFullMap m, long updateSeq) { super(m); nodeId = m.nodeId; nodeOrder = m.nodeOrder; this.updateSeq = updateSeq; } /** * Empty constructor required for {@link Externalizable}. */ public GridDhtPartitionFullMap() { // No-op. } /** * @return {@code True} if properly initialized. */ public boolean valid() { return nodeId != null && nodeOrder > 0; } /** * @return Node ID. */ public UUID nodeId() { return nodeId; } /** * @return Node order. */ public long nodeOrder() { return nodeOrder; } /** * @return Update sequence. */ public long updateSequence() { return updateSeq; } /** * @param fullMap Map. * @return {@code True} if this map and given map contain the same data. */ public boolean partitionStateEquals(GridDhtPartitionFullMap fullMap) { if (size() != fullMap.size()) return false; for (Map.Entry<UUID, GridDhtPartitionMap> e : entrySet()) { GridDhtPartitionMap m = fullMap.get(e.getKey()); if (m == null || !m.map().equals(e.getValue().map())) return false; } return true; } /** * @param updateSeq New update sequence value. */ public void newUpdateSequence(long updateSeq) { this.updateSeq = updateSeq; } /** * @param updateSeq New update sequence value. * @return Old update sequence value. */ public long updateSequence(long updateSeq) { long old = this.updateSeq; assert updateSeq >= old : "Invalid update sequence [cur=" + old + ", new=" + updateSeq + ", partMap=" + toFullString() + ']'; this.updateSeq = updateSeq; return old; } /** {@inheritDoc} */ @Override public int compareTo(GridDhtPartitionFullMap o) { assert nodeId == null || (nodeOrder != o.nodeOrder && !nodeId.equals(o.nodeId)) || (nodeOrder == o.nodeOrder && nodeId.equals(o.nodeId)): "Inconsistent node order and ID [id1=" + nodeId + ", order1=" + nodeOrder + ", id2=" + o.nodeId + ", order2=" + o.nodeOrder + ']'; if (nodeId == null && o.nodeId != null) return -1; else if (nodeId != null && o.nodeId == null) return 1; else if (nodeId == null && o.nodeId == null) return 0; int res = Long.compare(nodeOrder, o.nodeOrder); if (res == 0) res = Long.compare(updateSeq, o.updateSeq); return res; } /** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { U.writeUuid(out, nodeId); out.writeLong(nodeOrder); out.writeLong(updateSeq); U.writeMap(out, this); } /** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { nodeId = U.readUuid(in); nodeOrder = in.readLong(); updateSeq = in.readLong(); putAll(U.<UUID, GridDhtPartitionMap>readMap(in)); } /** {@inheritDoc} */ @Override public boolean equals(Object o) { if (this == o) return true; GridDhtPartitionFullMap other = (GridDhtPartitionFullMap)o; return other.nodeId.equals(nodeId) && other.updateSeq == updateSeq; } /** {@inheritDoc} */ @Override public int hashCode() { return 31 * nodeId.hashCode() + (int)(updateSeq ^ (updateSeq >>> 32)); } /** * @return Map string representation. */ public String map2string() { Iterator<Map.Entry<UUID, GridDhtPartitionMap>> it = entrySet().iterator(); if (!it.hasNext()) return "{}"; StringBuilder buf = new StringBuilder(); buf.append('{'); while(true) { Map.Entry<UUID, GridDhtPartitionMap> e = it.next(); UUID nodeId = e.getKey(); GridDhtPartitionMap partMap = e.getValue(); buf.append(nodeId).append('=').append(partMap.toFullString()); if (!it.hasNext()) return buf.append('}').toString(); buf.append(", "); } } /** * @return Full string representation. */ public String toFullString() { return S.toString(GridDhtPartitionFullMap.class, this, "size", size(), "map", map2string()); } /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridDhtPartitionFullMap.class, this, "size", size()); } }