// get a typed context
PartitionedRebalancerContext context =
rebalancerConfig.getRebalancerContext(PartitionedRebalancerContext.class);
// Initialize an empty mapping of locks to participants
ResourceAssignment assignment = new ResourceAssignment(context.getResourceId());
// Get the list of live participants in the cluster
List<ParticipantId> liveParticipants =
new ArrayList<ParticipantId>(cluster.getLiveParticipantMap().keySet());
// Get the state model (should be a simple lock/unlock model) and the highest-priority state
StateModelDefId stateModelDefId = context.getStateModelDefId();
StateModelDefinition stateModelDef = cluster.getStateModelMap().get(stateModelDefId);
if (stateModelDef.getStatesPriorityList().size() < 1) {
LOG.error("Invalid state model definition. There should be at least one state.");
return assignment;
}
State lockState = stateModelDef.getTypedStatesPriorityList().get(0);
// Count the number of participants allowed to lock each lock
String stateCount = stateModelDef.getNumParticipantsPerState(lockState);
int lockHolders = 0;
try {
// a numeric value is a custom-specified number of participants allowed to lock the lock
lockHolders = Integer.parseInt(stateCount);
} catch (NumberFormatException e) {
LOG.error("Invalid state model definition. The lock state does not have a valid count");
return assignment;
}
// Fairly assign the lock state to the participants using a simple mod-based sequential
// assignment. For instance, if each lock can be held by 3 participants, lock 0 would be held
// by participants (0, 1, 2), lock 1 would be held by (1, 2, 3), and so on, wrapping around the
// number of participants as necessary.
// This assumes a simple lock-unlock model where the only state of interest is which nodes have
// acquired each lock.
int i = 0;
for (PartitionId partition : context.getPartitionSet()) {
Map<ParticipantId, State> replicaMap = new HashMap<ParticipantId, State>();
for (int j = i; j < i + lockHolders; j++) {
int participantIndex = j % liveParticipants.size();
ParticipantId participant = liveParticipants.get(participantIndex);
// enforce that a participant can only have one instance of a given lock
if (!replicaMap.containsKey(participant)) {
replicaMap.put(participant, lockState);
}
}
assignment.addReplicaMap(partition, replicaMap);
i++;
}
return assignment;
}