View Javadoc

1   package org.apache.helix.util;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.TreeMap;
28  
29  import org.apache.helix.HelixException;
30  import org.apache.helix.model.IdealState;
31  import org.apache.helix.model.StateModelDefinition;
32  
33  public class RebalanceUtil
34  {
35    public static Map<String, Object> buildInternalIdealState(IdealState state)
36    {
37      // Try parse the partition number from name DB_n. If not, sort the partitions and
38      // assign id
39      Map<String, Integer> partitionIndex = new HashMap<String, Integer>();
40      Map<String, String> reversePartitionIndex = new HashMap<String, String>();
41      boolean indexInPartitionName = true;
42      for (String partitionId : state.getPartitionSet())
43      {
44        int lastPos = partitionId.lastIndexOf("_");
45        if (lastPos < 0)
46        {
47          indexInPartitionName = false;
48          break;
49        }
50        try
51        {
52          String idStr = partitionId.substring(lastPos + 1);
53          int partition = Integer.parseInt(idStr);
54          partitionIndex.put(partitionId, partition);
55          reversePartitionIndex.put(state.getResourceName() + "_" + partition, partitionId);
56        }
57        catch (Exception e)
58        {
59          indexInPartitionName = false;
60          partitionIndex.clear();
61          reversePartitionIndex.clear();
62          break;
63        }
64      }
65  
66      if (indexInPartitionName == false)
67      {
68        List<String> partitions = new ArrayList<String>();
69        partitions.addAll(state.getPartitionSet());
70        Collections.sort(partitions);
71        for (int i = 0; i < partitions.size(); i++)
72        {
73          partitionIndex.put(partitions.get(i), i);
74          reversePartitionIndex.put(state.getResourceName() + "_" + i, partitions.get(i));
75        }
76      }
77  
78      Map<String, List<Integer>> nodeMasterAssignmentMap =
79          new TreeMap<String, List<Integer>>();
80      Map<String, Map<String, List<Integer>>> combinedNodeSlaveAssignmentMap =
81          new TreeMap<String, Map<String, List<Integer>>>();
82      for (String partition : state.getPartitionSet())
83      {
84        List<String> instances = state.getRecord().getListField(partition);
85        String master = instances.get(0);
86        if (!nodeMasterAssignmentMap.containsKey(master))
87        {
88          nodeMasterAssignmentMap.put(master, new ArrayList<Integer>());
89        }
90        if (!combinedNodeSlaveAssignmentMap.containsKey(master))
91        {
92          combinedNodeSlaveAssignmentMap.put(master, new TreeMap<String, List<Integer>>());
93        }
94        nodeMasterAssignmentMap.get(master).add(partitionIndex.get(partition));
95        for (int i = 1; i < instances.size(); i++)
96        {
97          String instance = instances.get(i);
98          Map<String, List<Integer>> slaveMap = combinedNodeSlaveAssignmentMap.get(master);
99          if (!slaveMap.containsKey(instance))
100         {
101           slaveMap.put(instance, new ArrayList<Integer>());
102         }
103         slaveMap.get(instance).add(partitionIndex.get(partition));
104       }
105     }
106 
107     Map<String, Object> result = new TreeMap<String, Object>();
108     result.put("MasterAssignmentMap", nodeMasterAssignmentMap);
109     result.put("SlaveAssignmentMap", combinedNodeSlaveAssignmentMap);
110     result.put("replicas", Integer.parseInt(state.getReplicas()));
111     result.put("partitions", new Integer(state.getRecord().getListFields().size()));
112     result.put("reversePartitionIndex", reversePartitionIndex);
113     return result;
114   }
115   public static String[] parseStates(String clusterName, StateModelDefinition stateModDef)
116   {
117     String[] result = new String[2];
118     String masterStateValue = null, slaveStateValue = null;
119 
120     // StateModelDefinition def = new StateModelDefinition(stateModDef);
121 
122     List<String> statePriorityList = stateModDef.getStatesPriorityList();
123 
124     for (String state : statePriorityList)
125     {
126       String count = stateModDef.getNumInstancesPerState(state);
127       if (count.equals("1"))
128       {
129         if (masterStateValue != null)
130         {
131           throw new HelixException("Invalid or unsupported state model definition");
132         }
133         masterStateValue = state;
134       }
135       else if (count.equalsIgnoreCase("R"))
136       {
137         if (slaveStateValue != null)
138         {
139           throw new HelixException("Invalid or unsupported state model definition");
140         }
141         slaveStateValue = state;
142       }
143       else if (count.equalsIgnoreCase("N"))
144       {
145         if (!(masterStateValue == null && slaveStateValue == null))
146         {
147           throw new HelixException("Invalid or unsupported state model definition");
148         }
149         masterStateValue = slaveStateValue = state;
150       }
151     }
152     if (masterStateValue == null && slaveStateValue == null)
153     {
154       throw new HelixException("Invalid or unsupported state model definition");
155     }
156 
157     if (masterStateValue == null)
158     {
159       masterStateValue = slaveStateValue;
160     }
161     result[0] = masterStateValue;
162     result[1] = slaveStateValue;
163     return result;
164   }
165 }