1 package org.apache.helix.tools;
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.List;
25 import java.util.Map;
26 import java.util.Random;
27 import java.util.TreeMap;
28
29 import org.apache.helix.ZNRecord;
30 import org.apache.helix.model.IdealState.IdealStateProperty;
31
32
33
34
35
36
37
38
39
40
41
42
43 public class IdealStateCalculatorByShuffling
44 {
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public static ZNRecord calculateIdealState(List<String> instanceNames,
61 int partitions, int replicas, String resourceName, long randomSeed)
62 {
63 return calculateIdealState(instanceNames, partitions, replicas, resourceName, randomSeed, "MASTER", "SLAVE");
64 }
65 public static ZNRecord calculateIdealState(List<String> instanceNames,
66 int partitions, int replicas, String resourceName, long randomSeed, String masterValue, String slaveValue)
67 {
68 if (instanceNames.size() <= replicas)
69 {
70 throw new IllegalArgumentException(
71 "Replicas must be less than number of storage nodes");
72 }
73
74 Collections.sort(instanceNames);
75
76 ZNRecord result = new ZNRecord(resourceName);
77
78 List<Integer> partitionList = new ArrayList<Integer>(partitions);
79 for (int i = 0; i < partitions; i++)
80 {
81 partitionList.add(new Integer(i));
82 }
83 Random rand = new Random(randomSeed);
84
85 Collections.shuffle(partitionList, rand);
86
87 for (int i = 0; i < partitionList.size(); i++)
88 {
89 int partitionId = partitionList.get(i);
90 Map<String, String> partitionAssignment = new TreeMap<String, String>();
91 int masterNode = i % instanceNames.size();
92
93 partitionAssignment.put(instanceNames.get(masterNode), masterValue);
94
95
96
97 for (int j = 1; j <= replicas; j++)
98 {
99 int index = (masterNode + j * partitionList.size()) % instanceNames.size();
100 while(partitionAssignment.keySet().contains(instanceNames.get(index)))
101 {
102 index = (index +1) % instanceNames.size();
103 }
104 partitionAssignment
105 .put(instanceNames.get(index),
106 slaveValue);
107 }
108 String partitionName = resourceName + "_" + partitionId;
109 result.setMapField(partitionName, partitionAssignment);
110 }
111 result.setSimpleField(IdealStateProperty.NUM_PARTITIONS.toString(), String.valueOf(partitions));
112 return result;
113 }
114
115 public static ZNRecord calculateIdealState(List<String> instanceNames,
116 int partitions, int replicas, String resourceName)
117 {
118 long randomSeed = 888997632;
119
120 return calculateIdealState(instanceNames, partitions, replicas, resourceName,
121 randomSeed);
122 }
123 }