package org.apache.solr.common.cloud;
/*
* 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.
*/
import org.apache.noggit.JSONUtil;
import org.apache.noggit.JSONWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* A Slice contains immutable information about a logical shard (all replicas that share the same shard id).
*/
public class Slice extends ZkNodeProps {
public static String REPLICAS = "replicas";
public static String RANGE = "range";
public static String LEADER = "leader"; // FUTURE: do we want to record the leader as a slice property in the JSON (as opposed to isLeader as a replica property?)
private final String name;
private final HashPartitioner.Range range;
private final Integer replicationFactor;
private final Map<String,Replica> replicas;
private final Replica leader;
/**
* @param name The name of the slice
* @param replicas The replicas of the slice. This is used directly and a copy is not made. If null, replicas will be constructed from props.
* @param props The properties of the slice - a shallow copy will always be made.
*/
public Slice(String name, Map<String,Replica> replicas, Map<String,Object> props) {
super( props==null ? new LinkedHashMap<String,Object>(2) : new LinkedHashMap<String,Object>(props));
this.name = name;
Object rangeObj = propMap.get(RANGE);
HashPartitioner.Range tmpRange = null;
if (rangeObj instanceof HashPartitioner.Range) {
tmpRange = (HashPartitioner.Range)rangeObj;
} else if (rangeObj != null) {
HashPartitioner hp = new HashPartitioner();
tmpRange = hp.fromString(rangeObj.toString());
}
range = tmpRange;
replicationFactor = null; // future
// add the replicas *after* the other properties (for aesthetics, so it's easy to find slice properties in the JSON output)
this.replicas = replicas != null ? replicas : makeReplicas((Map<String,Object>)propMap.get(REPLICAS));
propMap.put(REPLICAS, this.replicas);
leader = findLeader();
}
private Map<String,Replica> makeReplicas(Map<String,Object> genericReplicas) {
if (genericReplicas == null) return new HashMap<String,Replica>(1);
Map<String,Replica> result = new LinkedHashMap<String, Replica>(genericReplicas.size());
for (Map.Entry<String,Object> entry : genericReplicas.entrySet()) {
String name = entry.getKey();
Object val = entry.getValue();
Replica r;
if (val instanceof Replica) {
r = (Replica)val;
} else {
r = new Replica(name, (Map<String,Object>)val);
}
result.put(name, r);
}
return result;
}
private Replica findLeader() {
for (Replica replica : replicas.values()) {
if (replica.getStr(LEADER) != null) return replica;
}
return null;
}
/**
* Return slice name (shard id).
*/
public String getName() {
return name;
}
/**
* Gets the list of replicas for this slice.
*/
public Collection<Replica> getReplicas() {
return replicas.values();
}
/**
* Get the map of coreNodeName to replicas for this slice.
*/
public Map<String, Replica> getReplicasMap() {
return replicas;
}
public Map<String,Replica> getReplicasCopy() {
return new LinkedHashMap<String,Replica>(replicas);
}
public Replica getLeader() {
return leader;
}
@Override
public String toString() {
return name + ':' + JSONUtil.toJSON(propMap);
}
@Override
public void write(JSONWriter jsonWriter) {
jsonWriter.write(propMap);
}
}