1 package org.apache.helix.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
38
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
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 }