1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import java.util.Collection;
22
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.util.Bytes;
25
26
27
28
29
30
31
32 @InterfaceAudience.Private
33 public class RegionLocations {
34
35 private final int numNonNullElements;
36
37
38
39
40
41 private final HRegionLocation[] locations;
42
43
44
45
46
47
48
49
50 public RegionLocations(HRegionLocation... locations) {
51 int numNonNullElements = 0;
52 int maxReplicaId = -1;
53 int maxReplicaIdIndex = -1;
54 int index = 0;
55 for (HRegionLocation loc : locations) {
56 if (loc != null) {
57 if (loc.getServerName() != null) {
58 numNonNullElements++;
59 }
60 if (loc.getRegionInfo().getReplicaId() >= maxReplicaId) {
61 maxReplicaId = loc.getRegionInfo().getReplicaId();
62 maxReplicaIdIndex = index;
63 }
64 }
65 index++;
66 }
67 this.numNonNullElements = numNonNullElements;
68
69
70 maxReplicaId = maxReplicaId + (locations.length - (maxReplicaIdIndex + 1) );
71
72 if (maxReplicaId + 1 == locations.length) {
73 this.locations = locations;
74 } else {
75 this.locations = new HRegionLocation[maxReplicaId + 1];
76 for (HRegionLocation loc : locations) {
77 if (loc != null) {
78 this.locations[loc.getRegionInfo().getReplicaId()] = loc;
79 }
80 }
81 }
82 }
83
84 public RegionLocations(Collection<HRegionLocation> locations) {
85 this(locations.toArray(new HRegionLocation[locations.size()]));
86 }
87
88
89
90
91
92
93 public int size() {
94 return locations.length;
95 }
96
97
98
99
100
101 public int numNonNullElements() {
102 return numNonNullElements;
103 }
104
105
106
107
108
109 public boolean isEmpty() {
110 return numNonNullElements == 0;
111 }
112
113
114
115
116
117
118
119
120 public RegionLocations removeByServer(ServerName serverName) {
121 HRegionLocation[] newLocations = null;
122 for (int i = 0; i < locations.length; i++) {
123
124 if (locations[i] != null && serverName.equals(locations[i].getServerName())) {
125 if (newLocations == null) {
126 newLocations = new HRegionLocation[locations.length];
127 System.arraycopy(locations, 0, newLocations, 0, i);
128 }
129 newLocations[i] = null;
130 } else if (newLocations != null) {
131 newLocations[i] = locations[i];
132 }
133 }
134 return newLocations == null ? this : new RegionLocations(newLocations);
135 }
136
137
138
139
140
141
142
143 public RegionLocations remove(HRegionLocation location) {
144 if (location == null) return this;
145 if (location.getRegionInfo() == null) return this;
146 int replicaId = location.getRegionInfo().getReplicaId();
147 if (replicaId >= locations.length) return this;
148
149
150
151 if (locations[replicaId] == null
152 || !location.getRegionInfo().equals(locations[replicaId].getRegionInfo())
153 || !location.equals(locations[replicaId])) {
154 return this;
155 }
156
157 HRegionLocation[] newLocations = new HRegionLocation[locations.length];
158 System.arraycopy(locations, 0, newLocations, 0, locations.length);
159 newLocations[replicaId] = null;
160
161 return new RegionLocations(newLocations);
162 }
163
164
165
166
167
168
169
170 public RegionLocations remove(int replicaId) {
171 if (getRegionLocation(replicaId) == null) {
172 return this;
173 }
174
175 HRegionLocation[] newLocations = new HRegionLocation[locations.length];
176
177 System.arraycopy(locations, 0, newLocations, 0, locations.length);
178 if (replicaId < newLocations.length) {
179 newLocations[replicaId] = null;
180 }
181
182 return new RegionLocations(newLocations);
183 }
184
185
186
187
188
189
190
191
192
193
194 public RegionLocations mergeLocations(RegionLocations other) {
195 assert other != null;
196
197 HRegionLocation[] newLocations = null;
198
199
200
201 int max = other.locations.length;
202
203 for (int i = 0; i < max; i++) {
204 HRegionLocation thisLoc = this.getRegionLocation(i);
205 HRegionLocation otherLoc = other.getRegionLocation(i);
206
207 HRegionLocation selectedLoc = selectRegionLocation(thisLoc,
208 otherLoc, true, false);
209
210 if (selectedLoc != thisLoc) {
211 if (newLocations == null) {
212 newLocations = new HRegionLocation[max];
213 System.arraycopy(locations, 0, newLocations, 0, i);
214 }
215 }
216 if (newLocations != null) {
217 newLocations[i] = selectedLoc;
218 }
219 }
220
221 return newLocations == null ? this : new RegionLocations(newLocations);
222 }
223
224 private HRegionLocation selectRegionLocation(HRegionLocation oldLocation,
225 HRegionLocation location, boolean checkForEquals, boolean force) {
226 if (location == null) {
227 return oldLocation == null ? null : oldLocation;
228 }
229
230 if (oldLocation == null) {
231 return location;
232 }
233
234 if (force
235 || isGreaterThan(location.getSeqNum(), oldLocation.getSeqNum(), checkForEquals)) {
236 return location;
237 }
238 return oldLocation;
239 }
240
241
242
243
244
245
246
247
248
249
250
251 public RegionLocations updateLocation(HRegionLocation location,
252 boolean checkForEquals, boolean force) {
253 assert location != null;
254
255 int replicaId = location.getRegionInfo().getReplicaId();
256
257 HRegionLocation oldLoc = getRegionLocation(location.getRegionInfo().getReplicaId());
258 HRegionLocation selectedLoc = selectRegionLocation(oldLoc, location,
259 checkForEquals, force);
260
261 if (selectedLoc == oldLoc) {
262 return this;
263 }
264 HRegionLocation[] newLocations = new HRegionLocation[Math.max(locations.length, replicaId +1)];
265 System.arraycopy(locations, 0, newLocations, 0, locations.length);
266 newLocations[replicaId] = location;
267 return new RegionLocations(newLocations);
268 }
269
270 private boolean isGreaterThan(long a, long b, boolean checkForEquals) {
271 return a > b || (checkForEquals && (a == b));
272 }
273
274 public HRegionLocation getRegionLocation(int replicaId) {
275 if (replicaId >= locations.length) {
276 return null;
277 }
278 return locations[replicaId];
279 }
280
281
282
283
284
285
286
287 public HRegionLocation getRegionLocationByRegionName(byte[] regionName) {
288 for (HRegionLocation loc : locations) {
289 if (loc != null) {
290 if (Bytes.equals(loc.getRegionInfo().getRegionName(), regionName)
291 || Bytes.equals(loc.getRegionInfo().getEncodedNameAsBytes(), regionName)) {
292 return loc;
293 }
294 }
295 }
296 return null;
297 }
298
299 public HRegionLocation[] getRegionLocations() {
300 return locations;
301 }
302
303 public HRegionLocation getDefaultRegionLocation() {
304 return locations[HRegionInfo.DEFAULT_REPLICA_ID];
305 }
306
307
308
309
310 public HRegionLocation getRegionLocation() {
311 for (HRegionLocation loc : locations) {
312 if (loc != null) {
313 return loc;
314 }
315 }
316 return null;
317 }
318
319 @Override
320 public String toString() {
321 StringBuilder builder = new StringBuilder("[");
322 for (HRegionLocation loc : locations) {
323 if (builder.length() > 1) {
324 builder.append(", ");
325 }
326 builder.append(loc == null ? "null" : loc);
327 }
328 builder.append("]");
329 return builder.toString();
330 }
331
332 }