/**
* (c) Copyright 2014 WibiData, Inc.
*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kiji.mapreduce.framework;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
/**
* Class representing a smallest-possible range of tokens that share replica nodes.
*
* This class essentially maps to a Cassandra virtual node (vnode).
*/
final class CassandraSubSplit {
// TODO: Add separate field for actual owner of token, versus replica nodes?
/** Starting token (inclusive). */
private final long mStartToken;
/** Ending token (inclusive). */
private final long mEndToken;
/** List of hosts that contain copies of data in the token range. */
private final Set<String> mHosts;
/** Minimum token value (assuming Murmur3 partitioner). */
public static final long RING_START_TOKEN = Long.MIN_VALUE;
/** Maximum token value (assuming Murmur3 partitioner). */
public static final long RING_END_TOKEN = Long.MAX_VALUE;
/**
* Create a subsplit given a token range and a set of replica nodes.
*
* @param startToken The minimum token for the subsplit (inclusive).
* @param endToken The maximum token for the subsplit (inclusive).
* @param hosts A set of replica nodes for this token range.
* @return A new subsplit for this token range.
*/
public static CassandraSubSplit createFromHostSet(
long startToken, long endToken, Set<String> hosts) {
return new CassandraSubSplit(startToken, endToken, hosts);
}
/**
* Create a subsplit given a token range and a set of replica nodes.
*
* @param startToken The minimum token for the subsplit (inclusive).
* @param endToken The maximum token for the subsplit (inclusive).
* @param host The master node for this token range.
* @return A new subsplit for this token range.
*/
public static CassandraSubSplit createFromHost(long startToken, long endToken, String host) {
Set<String> hosts = Sets.newHashSet();
hosts.add(host);
return new CassandraSubSplit(startToken, endToken, hosts);
}
/**
* Private constructor for a subsplit.
*
* @param startToken The minimum token for the subsplit (inclusive).
* @param endToken The maximum token for the subsplit (inclusive).
* @param hosts A set of replica nodes for this token range.
*/
private CassandraSubSplit(long startToken, long endToken, Set<String> hosts) {
Preconditions.checkNotNull(hosts);
Preconditions.checkArgument(hosts.size() > 0);
for (String host : hosts) {
Preconditions.checkNotNull(host);
Preconditions.checkArgument(host.length() > 1);
}
this.mStartToken = startToken;
this.mEndToken = endToken;
this.mHosts = Sets.newHashSet(hosts);
}
/** {@inheritDoc} */
@Override
public String toString() {
return String.format(
"Subsplit from %s to %s @ %s",
mStartToken,
mEndToken,
mHosts
);
}
/**
* Getter for the minimum token value for this subsplit.
*
* @return The minimum token value for this subsplit.
*/
public long getStartToken() {
return mStartToken;
}
/**
* Getter for the maximum token value for this subsplit.
*
* @return The maximum token value for this subsplit.
*/
public long getEndToken() {
return mEndToken;
}
/**
* Getter for the replica nodes for this subsplit.
*
* @return The replica nodes for this subsplit.
*/
public Set<String> getHosts() {
return mHosts;
}
/**
* Get a comma-separated list of the hosts for this subsplit.
*
* @return A CSV of hosts, as a string.
*/
public String getSortedHostListAsString() {
Preconditions.checkNotNull(mHosts);
List<String> hostList = Lists.newArrayList(mHosts);
Collections.sort(hostList);
Preconditions.checkNotNull(hostList);
Preconditions.checkArgument(hostList.size() > 0);
return Joiner.on(",").join(hostList);
}
}