/* * Copyright 2017 LinkedIn Corp. All rights reserved. * * Licensed 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. */ package com.github.ambry.clustermap; import com.github.ambry.utils.Utils; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; /** * {@link PartitionId} implementation to use within dynamic cluster managers. */ class AmbryPartition extends PartitionId { private final Long id; private final ClusterManagerCallback clusterManagerCallback; private volatile PartitionState state; private static final short VERSION_FIELD_SIZE_IN_BYTES = 2; private static final short CURRENT_VERSION = 1; private static final int PARTITION_SIZE_IN_BYTES = VERSION_FIELD_SIZE_IN_BYTES + 8; /** * Instantiate an AmbryPartition instance. * @param id the id associated with this partition. * @param clusterManagerCallback the {@link ClusterManagerCallback} to use to make callbacks * to the {@link HelixClusterManager} * The initial state defaults to {@link PartitionState#READ_WRITE}. */ AmbryPartition(long id, ClusterManagerCallback clusterManagerCallback) { this.id = id; this.clusterManagerCallback = clusterManagerCallback; this.state = PartitionState.READ_WRITE; } @Override public byte[] getBytes() { return ClusterMapUtils.serializeShortAndLong(CURRENT_VERSION, id); } @Override public List<AmbryReplica> getReplicaIds() { return new ArrayList<>(clusterManagerCallback.getReplicaIdsForPartition(this)); } @Override public PartitionState getPartitionState() { return state; } @Override public boolean isEqual(String other) { return id.toString().equals(other); } @Override public String toString() { return "Partition[" + id + "]"; } @Override public int compareTo(PartitionId o) { AmbryPartition other = (AmbryPartition) o; return id.compareTo(other.id); } /** * Return the byte representation of the partition id from the given stream. * @param stream the {@link DataInputStream} containing the id * @return the byte representation fo the partition id. * @throws IOException if the read from the stream encounters an IOException. */ static byte[] readPartitionBytesFromStream(InputStream stream) throws IOException { return Utils.readBytesFromStream(stream, PARTITION_SIZE_IN_BYTES); } /** * Construct name based on the id that is appropriate for use as a file or directory name. * @return string representation of the id for use as part of file system path. */ String toPathString() { return id.toString(); } /** * Set the state of this partition. * @param newState the updated {@link PartitionState}. */ void setState(PartitionState newState) { state = newState; } /** * Take actions, if any, on being notified that this partition has become {@link PartitionState#READ_ONLY} */ void onPartitionReadOnly() { // no-op. The static manager does not deal with this. In the dynamic world, the cluster manager will rely // entirely on Helix for this. } }