1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.util;
21
22 import java.io.IOException;
23 import java.io.InterruptedIOException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.concurrent.Callable;
27 import java.util.concurrent.CompletionService;
28 import java.util.concurrent.ExecutionException;
29 import java.util.concurrent.ExecutorCompletionService;
30 import java.util.concurrent.Future;
31 import java.util.concurrent.ThreadFactory;
32 import java.util.concurrent.ThreadPoolExecutor;
33 import java.util.concurrent.TimeUnit;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.hadoop.classification.InterfaceAudience;
38 import org.apache.hadoop.conf.Configuration;
39 import org.apache.hadoop.fs.Path;
40 import org.apache.hadoop.hbase.HRegionInfo;
41 import org.apache.hadoop.hbase.HTableDescriptor;
42 import org.apache.hadoop.hbase.regionserver.HRegion;
43
44
45
46
47 @InterfaceAudience.Private
48 public abstract class ModifyRegionUtils {
49 private static final Log LOG = LogFactory.getLog(ModifyRegionUtils.class);
50
51 private ModifyRegionUtils() {
52 }
53
54 public interface RegionFillTask {
55 void fillRegion(final HRegion region) throws IOException;
56 }
57
58
59
60
61
62
63
64
65
66
67
68 public static List<HRegionInfo> createRegions(final Configuration conf, final Path rootDir,
69 final HTableDescriptor hTableDescriptor, final HRegionInfo[] newRegions) throws IOException {
70 return createRegions(conf, rootDir, hTableDescriptor, newRegions, null);
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84 public static List<HRegionInfo> createRegions(final Configuration conf, final Path rootDir,
85 final HTableDescriptor hTableDescriptor, final HRegionInfo[] newRegions,
86 final RegionFillTask task) throws IOException {
87 if (newRegions == null) return null;
88 int regionNumber = newRegions.length;
89 ThreadPoolExecutor regionOpenAndInitThreadPool = getRegionOpenAndInitThreadPool(conf,
90 "RegionOpenAndInitThread-" + hTableDescriptor.getTableName(), regionNumber);
91 CompletionService<HRegionInfo> completionService = new ExecutorCompletionService<HRegionInfo>(
92 regionOpenAndInitThreadPool);
93 List<HRegionInfo> regionInfos = new ArrayList<HRegionInfo>();
94 for (final HRegionInfo newRegion : newRegions) {
95 completionService.submit(new Callable<HRegionInfo>() {
96 public HRegionInfo call() throws IOException {
97
98 HRegion region = HRegion.createHRegion(newRegion,
99 rootDir, conf, hTableDescriptor, null,
100 false, true);
101 try {
102
103 if (task != null) {
104 task.fillRegion(region);
105 }
106 } finally {
107
108 region.close();
109 }
110 return region.getRegionInfo();
111 }
112 });
113 }
114 try {
115
116 for (int i = 0; i < regionNumber; i++) {
117 Future<HRegionInfo> future = completionService.take();
118 HRegionInfo regionInfo = future.get();
119 regionInfos.add(regionInfo);
120 }
121 } catch (InterruptedException e) {
122 LOG.error("Caught " + e + " during region creation");
123 throw new InterruptedIOException(e.getMessage());
124 } catch (ExecutionException e) {
125 throw new IOException(e);
126 } finally {
127 regionOpenAndInitThreadPool.shutdownNow();
128 }
129 return regionInfos;
130 }
131
132
133
134
135
136 static ThreadPoolExecutor getRegionOpenAndInitThreadPool(final Configuration conf,
137 final String threadNamePrefix, int regionNumber) {
138 int maxThreads = Math.min(regionNumber, conf.getInt(
139 "hbase.hregion.open.and.init.threads.max", 10));
140 ThreadPoolExecutor regionOpenAndInitThreadPool = Threads
141 .getBoundedCachedThreadPool(maxThreads, 30L, TimeUnit.SECONDS,
142 new ThreadFactory() {
143 private int count = 1;
144
145 public Thread newThread(Runnable r) {
146 Thread t = new Thread(r, threadNamePrefix + "-" + count++);
147 return t;
148 }
149 });
150 return regionOpenAndInitThreadPool;
151 }
152 }