1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver;
20
21 import java.io.IOException;
22 import java.io.PrintWriter;
23 import java.io.StringWriter;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.concurrent.BlockingQueue;
28 import java.util.concurrent.Executors;
29 import java.util.concurrent.RejectedExecutionException;
30 import java.util.concurrent.RejectedExecutionHandler;
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.conf.Configuration;
38 import org.apache.hadoop.hbase.RemoteExceptionHandler;
39 import org.apache.hadoop.hbase.classification.InterfaceAudience;
40 import org.apache.hadoop.hbase.conf.ConfigurationManager;
41 import org.apache.hadoop.hbase.conf.PropagatingConfigurationObserver;
42 import org.apache.hadoop.hbase.regionserver.compactions.CompactionContext;
43 import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
44 import org.apache.hadoop.hbase.regionserver.throttle.CompactionThroughputControllerFactory;
45 import org.apache.hadoop.hbase.regionserver.throttle.ThroughputController;
46 import org.apache.hadoop.hbase.security.User;
47 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
48 import org.apache.hadoop.hbase.util.Pair;
49 import org.apache.hadoop.hbase.util.StealJobQueue;
50 import org.apache.hadoop.util.StringUtils;
51
52 import com.google.common.annotations.VisibleForTesting;
53 import com.google.common.base.Preconditions;
54
55
56
57
58 @InterfaceAudience.Private
59 public class CompactSplitThread implements CompactionRequestor, PropagatingConfigurationObserver {
60 private static final Log LOG = LogFactory.getLog(CompactSplitThread.class);
61
62
63 public final static String LARGE_COMPACTION_THREADS =
64 "hbase.regionserver.thread.compaction.large";
65 public final static int LARGE_COMPACTION_THREADS_DEFAULT = 1;
66
67
68 public final static String SMALL_COMPACTION_THREADS =
69 "hbase.regionserver.thread.compaction.small";
70 public final static int SMALL_COMPACTION_THREADS_DEFAULT = 1;
71
72
73 public final static String SPLIT_THREADS = "hbase.regionserver.thread.split";
74 public final static int SPLIT_THREADS_DEFAULT = 1;
75
76
77 public final static String MERGE_THREADS = "hbase.regionserver.thread.merge";
78 public final static int MERGE_THREADS_DEFAULT = 1;
79
80 public static final String REGION_SERVER_REGION_SPLIT_LIMIT =
81 "hbase.regionserver.regionSplitLimit";
82 public static final int DEFAULT_REGION_SERVER_REGION_SPLIT_LIMIT= 1000;
83
84 private final HRegionServer server;
85 private final Configuration conf;
86
87 private final ThreadPoolExecutor longCompactions;
88 private final ThreadPoolExecutor shortCompactions;
89 private final ThreadPoolExecutor splits;
90 private final ThreadPoolExecutor mergePool;
91
92 private volatile ThroughputController compactionThroughputController;
93
94
95
96
97
98
99 private int regionSplitLimit;
100
101
102 CompactSplitThread(HRegionServer server) {
103 super();
104 this.server = server;
105 this.conf = server.getConfiguration();
106 this.regionSplitLimit = conf.getInt(REGION_SERVER_REGION_SPLIT_LIMIT,
107 DEFAULT_REGION_SERVER_REGION_SPLIT_LIMIT);
108
109 int largeThreads = Math.max(1, conf.getInt(
110 LARGE_COMPACTION_THREADS, LARGE_COMPACTION_THREADS_DEFAULT));
111 int smallThreads = conf.getInt(
112 SMALL_COMPACTION_THREADS, SMALL_COMPACTION_THREADS_DEFAULT);
113
114 int splitThreads = conf.getInt(SPLIT_THREADS, SPLIT_THREADS_DEFAULT);
115
116
117 Preconditions.checkArgument(largeThreads > 0 && smallThreads > 0);
118
119 final String n = Thread.currentThread().getName();
120
121 StealJobQueue<Runnable> stealJobQueue = new StealJobQueue<>();
122 this.longCompactions = new ThreadPoolExecutor(largeThreads, largeThreads,
123 60, TimeUnit.SECONDS, stealJobQueue,
124 new ThreadFactory() {
125 @Override
126 public Thread newThread(Runnable r) {
127 String name = n + "-longCompactions-" + System.currentTimeMillis();
128 return new Thread(r, name);
129 }
130 });
131 this.longCompactions.setRejectedExecutionHandler(new Rejection());
132 this.longCompactions.prestartAllCoreThreads();
133 this.shortCompactions = new ThreadPoolExecutor(smallThreads, smallThreads,
134 60, TimeUnit.SECONDS, stealJobQueue.getStealFromQueue(),
135 new ThreadFactory() {
136 @Override
137 public Thread newThread(Runnable r) {
138 String name = n + "-shortCompactions-" + System.currentTimeMillis();
139 return new Thread(r, name);
140 }
141 });
142 this.shortCompactions
143 .setRejectedExecutionHandler(new Rejection());
144 this.splits = (ThreadPoolExecutor)
145 Executors.newFixedThreadPool(splitThreads,
146 new ThreadFactory() {
147 @Override
148 public Thread newThread(Runnable r) {
149 String name = n + "-splits-" + System.currentTimeMillis();
150 return new Thread(r, name);
151 }
152 });
153 int mergeThreads = conf.getInt(MERGE_THREADS, MERGE_THREADS_DEFAULT);
154 this.mergePool = (ThreadPoolExecutor) Executors.newFixedThreadPool(
155 mergeThreads, new ThreadFactory() {
156 @Override
157 public Thread newThread(Runnable r) {
158 String name = n + "-merges-" + System.currentTimeMillis();
159 return new Thread(r, name);
160 }
161 });
162
163
164 this.compactionThroughputController =
165 CompactionThroughputControllerFactory.create(server, conf);
166 }
167
168 @Override
169 public String toString() {
170 return "compaction_queue=("
171 + longCompactions.getQueue().size() + ":"
172 + shortCompactions.getQueue().size() + ")"
173 + ", split_queue=" + splits.getQueue().size()
174 + ", merge_queue=" + mergePool.getQueue().size();
175 }
176
177 public String dumpQueue() {
178 StringBuffer queueLists = new StringBuffer();
179 queueLists.append("Compaction/Split Queue dump:\n");
180 queueLists.append(" LargeCompation Queue:\n");
181 BlockingQueue<Runnable> lq = longCompactions.getQueue();
182 Iterator<Runnable> it = lq.iterator();
183 while (it.hasNext()) {
184 queueLists.append(" " + it.next().toString());
185 queueLists.append("\n");
186 }
187
188 if (shortCompactions != null) {
189 queueLists.append("\n");
190 queueLists.append(" SmallCompation Queue:\n");
191 lq = shortCompactions.getQueue();
192 it = lq.iterator();
193 while (it.hasNext()) {
194 queueLists.append(" " + it.next().toString());
195 queueLists.append("\n");
196 }
197 }
198
199 queueLists.append("\n");
200 queueLists.append(" Split Queue:\n");
201 lq = splits.getQueue();
202 it = lq.iterator();
203 while (it.hasNext()) {
204 queueLists.append(" " + it.next().toString());
205 queueLists.append("\n");
206 }
207
208 queueLists.append("\n");
209 queueLists.append(" Region Merge Queue:\n");
210 lq = mergePool.getQueue();
211 it = lq.iterator();
212 while (it.hasNext()) {
213 queueLists.append(" " + it.next().toString());
214 queueLists.append("\n");
215 }
216
217 return queueLists.toString();
218 }
219
220 public synchronized void requestRegionsMerge(final Region a,
221 final Region b, final boolean forcible, long masterSystemTime, User user) {
222 try {
223 mergePool.execute(new RegionMergeRequest(a, b, this.server, forcible, masterSystemTime,user));
224 if (LOG.isDebugEnabled()) {
225 LOG.debug("Region merge requested for " + a + "," + b + ", forcible="
226 + forcible + ". " + this);
227 }
228 } catch (RejectedExecutionException ree) {
229 LOG.warn("Could not execute merge for " + a + "," + b + ", forcible="
230 + forcible, ree);
231 }
232 }
233
234 public synchronized boolean requestSplit(final Region r) {
235
236 if (shouldSplitRegion() && ((HRegion)r).getCompactPriority() >= Store.PRIORITY_USER) {
237 byte[] midKey = ((HRegion)r).checkSplit();
238 if (midKey != null) {
239 requestSplit(r, midKey);
240 return true;
241 }
242 }
243 return false;
244 }
245
246 public synchronized void requestSplit(final Region r, byte[] midKey) {
247 requestSplit(r, midKey, null);
248 }
249
250
251
252
253 public synchronized void requestSplit(final Region r, byte[] midKey, User user) {
254 if (midKey == null) {
255 LOG.debug("Region " + r.getRegionInfo().getRegionNameAsString() +
256 " not splittable because midkey=null");
257 if (((HRegion)r).shouldForceSplit()) {
258 ((HRegion)r).clearSplit();
259 }
260 return;
261 }
262 try {
263 this.splits.execute(new SplitRequest(r, midKey, this.server, user));
264 if (LOG.isDebugEnabled()) {
265 LOG.debug("Split requested for " + r + ". " + this);
266 }
267 } catch (RejectedExecutionException ree) {
268 LOG.info("Could not execute split for " + r, ree);
269 }
270 }
271
272 @Override
273 public synchronized List<CompactionRequest> requestCompaction(final Region r, final String why)
274 throws IOException {
275 return requestCompaction(r, why, null);
276 }
277
278 @Override
279 public synchronized List<CompactionRequest> requestCompaction(final Region r, final String why,
280 List<Pair<CompactionRequest, Store>> requests) throws IOException {
281 return requestCompaction(r, why, Store.NO_PRIORITY, requests, null);
282 }
283
284 @Override
285 public synchronized CompactionRequest requestCompaction(final Region r, final Store s,
286 final String why, CompactionRequest request) throws IOException {
287 return requestCompaction(r, s, why, Store.NO_PRIORITY, request, null);
288 }
289
290 @Override
291 public synchronized List<CompactionRequest> requestCompaction(final Region r, final String why,
292 int p, List<Pair<CompactionRequest, Store>> requests, User user) throws IOException {
293 return requestCompactionInternal(r, why, p, requests, true, user);
294 }
295
296 private List<CompactionRequest> requestCompactionInternal(final Region r, final String why,
297 int p, List<Pair<CompactionRequest, Store>> requests, boolean selectNow, User user)
298 throws IOException {
299
300 List<CompactionRequest> ret = null;
301 if (requests == null) {
302 ret = selectNow ? new ArrayList<CompactionRequest>(r.getStores().size()) : null;
303 for (Store s : r.getStores()) {
304 CompactionRequest cr = requestCompactionInternal(r, s, why, p, null, selectNow, user);
305 if (selectNow) ret.add(cr);
306 }
307 } else {
308 Preconditions.checkArgument(selectNow);
309 ret = new ArrayList<CompactionRequest>(requests.size());
310 for (Pair<CompactionRequest, Store> pair : requests) {
311 ret.add(requestCompaction(r, pair.getSecond(), why, p, pair.getFirst(), user));
312 }
313 }
314 return ret;
315 }
316
317 @Override
318 public CompactionRequest requestCompaction(final Region r, final Store s,
319 final String why, int priority, CompactionRequest request, User user) throws IOException {
320 return requestCompactionInternal(r, s, why, priority, request, true, user);
321 }
322
323 public synchronized void requestSystemCompaction(
324 final Region r, final String why) throws IOException {
325 requestCompactionInternal(r, why, Store.NO_PRIORITY, null, false, null);
326 }
327
328 public void requestSystemCompaction(
329 final Region r, final Store s, final String why) throws IOException {
330 requestCompactionInternal(r, s, why, Store.NO_PRIORITY, null, false, null);
331 }
332
333
334
335
336
337
338
339
340
341 private synchronized CompactionRequest requestCompactionInternal(final Region r, final Store s,
342 final String why, int priority, CompactionRequest request, boolean selectNow, User user)
343 throws IOException {
344 if (this.server.isStopped()
345 || (r.getTableDesc() != null && !r.getTableDesc().isCompactionEnabled())) {
346 return null;
347 }
348
349 CompactionContext compaction = null;
350 if (selectNow) {
351 compaction = selectCompaction(r, s, priority, request, user);
352 if (compaction == null) return null;
353 }
354
355
356
357 ThreadPoolExecutor pool = (selectNow && s.throttleCompaction(compaction.getRequest().getSize()))
358 ? longCompactions : shortCompactions;
359 pool.execute(new CompactionRunner(s, r, compaction, pool, user));
360 ((HRegion)r).incrementCompactionsQueuedCount();
361 if (LOG.isDebugEnabled()) {
362 String type = (pool == shortCompactions) ? "Small " : "Large ";
363 LOG.debug(type + "Compaction requested: " + (selectNow ? compaction.toString() : "system")
364 + (why != null && !why.isEmpty() ? "; Because: " + why : "") + "; " + this);
365 }
366 return selectNow ? compaction.getRequest() : null;
367 }
368
369 private CompactionContext selectCompaction(final Region r, final Store s,
370 int priority, CompactionRequest request, User user) throws IOException {
371 CompactionContext compaction = s.requestCompaction(priority, request, user);
372 if (compaction == null) {
373 if(LOG.isDebugEnabled() && r.getRegionInfo() != null) {
374 LOG.debug("Not compacting " + r.getRegionInfo().getRegionNameAsString() +
375 " because compaction request was cancelled");
376 }
377 return null;
378 }
379 assert compaction.hasSelection();
380 if (priority != Store.NO_PRIORITY) {
381 compaction.getRequest().setPriority(priority);
382 }
383 return compaction;
384 }
385
386
387
388
389 void interruptIfNecessary() {
390 splits.shutdown();
391 mergePool.shutdown();
392 longCompactions.shutdown();
393 shortCompactions.shutdown();
394 }
395
396 private void waitFor(ThreadPoolExecutor t, String name) {
397 boolean done = false;
398 while (!done) {
399 try {
400 done = t.awaitTermination(60, TimeUnit.SECONDS);
401 LOG.info("Waiting for " + name + " to finish...");
402 if (!done) {
403 t.shutdownNow();
404 }
405 } catch (InterruptedException ie) {
406 LOG.warn("Interrupted waiting for " + name + " to finish...");
407 }
408 }
409 }
410
411 void join() {
412 waitFor(splits, "Split Thread");
413 waitFor(mergePool, "Merge Thread");
414 waitFor(longCompactions, "Large Compaction Thread");
415 waitFor(shortCompactions, "Small Compaction Thread");
416 }
417
418
419
420
421
422
423
424 public int getCompactionQueueSize() {
425 return longCompactions.getQueue().size() + shortCompactions.getQueue().size();
426 }
427
428 public int getLargeCompactionQueueSize() {
429 return longCompactions.getQueue().size();
430 }
431
432
433 public int getSmallCompactionQueueSize() {
434 return shortCompactions.getQueue().size();
435 }
436
437 public int getSplitQueueSize() {
438 return splits.getQueue().size();
439 }
440
441 private boolean shouldSplitRegion() {
442 if(server.getNumberOfOnlineRegions() > 0.9*regionSplitLimit) {
443 LOG.warn("Total number of regions is approaching the upper limit " + regionSplitLimit + ". "
444 + "Please consider taking a look at http://hbase.apache.org/book.html#ops.regionmgt");
445 }
446 return (regionSplitLimit > server.getNumberOfOnlineRegions());
447 }
448
449
450
451
452 public int getRegionSplitLimit() {
453 return this.regionSplitLimit;
454 }
455
456 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="EQ_COMPARETO_USE_OBJECT_EQUALS",
457 justification="Contrived use of compareTo")
458 private class CompactionRunner implements Runnable, Comparable<CompactionRunner> {
459 private final Store store;
460 private final HRegion region;
461 private CompactionContext compaction;
462 private int queuedPriority;
463 private ThreadPoolExecutor parent;
464 private User user;
465 private long time;
466
467 public CompactionRunner(Store store, Region region,
468 CompactionContext compaction, ThreadPoolExecutor parent, User user) {
469 super();
470 this.store = store;
471 this.region = (HRegion)region;
472 this.compaction = compaction;
473 this.queuedPriority = (this.compaction == null)
474 ? store.getCompactPriority() : compaction.getRequest().getPriority();
475 this.parent = parent;
476 this.user = user;
477 this.time = System.currentTimeMillis();
478 }
479
480 @Override
481 public String toString() {
482 return (this.compaction != null) ? ("Request = " + compaction.getRequest())
483 : ("regionName = " + region.toString() + ", storeName = " + store.toString() +
484 ", priority = " + queuedPriority + ", time = " + time);
485 }
486
487 private void doCompaction(User user) {
488
489 if (this.compaction == null) {
490 int oldPriority = this.queuedPriority;
491 this.queuedPriority = this.store.getCompactPriority();
492 if (this.queuedPriority > oldPriority) {
493
494
495 this.parent.execute(this);
496 return;
497 }
498 try {
499 this.compaction = selectCompaction(this.region, this.store, queuedPriority, null, user);
500 } catch (IOException ex) {
501 LOG.error("Compaction selection failed " + this, ex);
502 server.checkFileSystem();
503 region.decrementCompactionsQueuedCount();
504 return;
505 }
506 if (this.compaction == null) {
507 region.decrementCompactionsQueuedCount();
508 return;
509 }
510
511
512 assert this.compaction.hasSelection();
513 ThreadPoolExecutor pool = store.throttleCompaction(
514 compaction.getRequest().getSize()) ? longCompactions : shortCompactions;
515
516
517
518 if (this.parent == shortCompactions && pool == longCompactions) {
519 this.store.cancelRequestedCompaction(this.compaction);
520 this.compaction = null;
521 this.parent = pool;
522 this.parent.execute(this);
523 return;
524 }
525 }
526
527 assert this.compaction != null;
528
529 this.compaction.getRequest().beforeExecute();
530 try {
531
532
533 long start = EnvironmentEdgeManager.currentTime();
534 boolean completed =
535 region.compact(compaction, store, compactionThroughputController, user);
536 long now = EnvironmentEdgeManager.currentTime();
537 LOG.info(((completed) ? "Completed" : "Aborted") + " compaction: " +
538 this + "; duration=" + StringUtils.formatTimeDiff(now, start));
539 if (completed) {
540
541 if (store.getCompactPriority() <= 0) {
542 requestSystemCompaction(region, store, "Recursive enqueue");
543 } else {
544
545 requestSplit(region);
546 }
547 }
548 } catch (IOException ex) {
549 IOException remoteEx = RemoteExceptionHandler.checkIOException(ex);
550 LOG.error("Compaction failed " + this, remoteEx);
551 if (remoteEx != ex) {
552 LOG.info("Compaction failed at original callstack: " + formatStackTrace(ex));
553 }
554 region.reportCompactionRequestFailure();
555 server.checkFileSystem();
556 } catch (Exception ex) {
557 LOG.error("Compaction failed " + this, ex);
558 region.reportCompactionRequestFailure();
559 server.checkFileSystem();
560 } finally {
561 region.decrementCompactionsQueuedCount();
562 LOG.debug("CompactSplitThread Status: " + CompactSplitThread.this);
563 }
564 this.compaction.getRequest().afterExecute();
565 }
566
567 @Override
568 public void run() {
569 Preconditions.checkNotNull(server);
570 if (server.isStopped()
571 || (region.getTableDesc() != null && !region.getTableDesc().isCompactionEnabled())) {
572 region.decrementCompactionsQueuedCount();
573 return;
574 }
575 doCompaction(user);
576 }
577
578 private String formatStackTrace(Exception ex) {
579 StringWriter sw = new StringWriter();
580 PrintWriter pw = new PrintWriter(sw);
581 ex.printStackTrace(pw);
582 pw.flush();
583 return sw.toString();
584 }
585
586 @Override
587 public int compareTo(CompactionRunner o) {
588
589 int compareVal = queuedPriority - o.queuedPriority;
590 if (compareVal != 0) return compareVal;
591 CompactionContext tc = this.compaction, oc = o.compaction;
592
593 return (tc == null) ? ((oc == null) ? 0 : 1)
594 : ((oc == null) ? -1 : tc.getRequest().compareTo(oc.getRequest()));
595 }
596 }
597
598
599
600
601 private static class Rejection implements RejectedExecutionHandler {
602 @Override
603 public void rejectedExecution(Runnable runnable, ThreadPoolExecutor pool) {
604 if (runnable instanceof CompactionRunner) {
605 CompactionRunner runner = (CompactionRunner)runnable;
606 LOG.debug("Compaction Rejected: " + runner);
607 runner.store.cancelRequestedCompaction(runner.compaction);
608 }
609 }
610 }
611
612
613
614
615 @Override
616 public void onConfigurationChange(Configuration newConf) {
617
618
619
620
621
622 int largeThreads = Math.max(1, newConf.getInt(
623 LARGE_COMPACTION_THREADS,
624 LARGE_COMPACTION_THREADS_DEFAULT));
625 if (this.longCompactions.getCorePoolSize() != largeThreads) {
626 LOG.info("Changing the value of " + LARGE_COMPACTION_THREADS +
627 " from " + this.longCompactions.getCorePoolSize() + " to " +
628 largeThreads);
629 if(this.longCompactions.getCorePoolSize() < largeThreads) {
630 this.longCompactions.setMaximumPoolSize(largeThreads);
631 this.longCompactions.setCorePoolSize(largeThreads);
632 } else {
633 this.longCompactions.setCorePoolSize(largeThreads);
634 this.longCompactions.setMaximumPoolSize(largeThreads);
635 }
636 }
637
638 int smallThreads = newConf.getInt(SMALL_COMPACTION_THREADS,
639 SMALL_COMPACTION_THREADS_DEFAULT);
640 if (this.shortCompactions.getCorePoolSize() != smallThreads) {
641 LOG.info("Changing the value of " + SMALL_COMPACTION_THREADS +
642 " from " + this.shortCompactions.getCorePoolSize() + " to " +
643 smallThreads);
644 if(this.shortCompactions.getCorePoolSize() < smallThreads) {
645 this.shortCompactions.setMaximumPoolSize(smallThreads);
646 this.shortCompactions.setCorePoolSize(smallThreads);
647 } else {
648 this.shortCompactions.setCorePoolSize(smallThreads);
649 this.shortCompactions.setMaximumPoolSize(smallThreads);
650 }
651 }
652
653 int splitThreads = newConf.getInt(SPLIT_THREADS,
654 SPLIT_THREADS_DEFAULT);
655 if (this.splits.getCorePoolSize() != splitThreads) {
656 LOG.info("Changing the value of " + SPLIT_THREADS +
657 " from " + this.splits.getCorePoolSize() + " to " +
658 splitThreads);
659 if(this.splits.getCorePoolSize() < splitThreads) {
660 this.splits.setMaximumPoolSize(splitThreads);
661 this.splits.setCorePoolSize(splitThreads);
662 } else {
663 this.splits.setCorePoolSize(splitThreads);
664 this.splits.setMaximumPoolSize(splitThreads);
665 }
666 }
667
668 int mergeThreads = newConf.getInt(MERGE_THREADS,
669 MERGE_THREADS_DEFAULT);
670 if (this.mergePool.getCorePoolSize() != mergeThreads) {
671 LOG.info("Changing the value of " + MERGE_THREADS +
672 " from " + this.mergePool.getCorePoolSize() + " to " +
673 mergeThreads);
674 if(this.mergePool.getCorePoolSize() < mergeThreads) {
675 this.mergePool.setMaximumPoolSize(mergeThreads);
676 this.mergePool.setCorePoolSize(mergeThreads);
677 } else {
678 this.mergePool.setCorePoolSize(mergeThreads);
679 this.mergePool.setMaximumPoolSize(mergeThreads);
680 }
681 }
682
683 ThroughputController old = this.compactionThroughputController;
684 if (old != null) {
685 old.stop("configuration change");
686 }
687 this.compactionThroughputController =
688 CompactionThroughputControllerFactory.create(server, newConf);
689
690
691
692 this.conf.reloadConfiguration();
693 }
694
695 protected int getSmallCompactionThreadNum() {
696 return this.shortCompactions.getCorePoolSize();
697 }
698
699 protected int getLargeCompactionThreadNum() {
700 return this.longCompactions.getCorePoolSize();
701 }
702
703 protected int getSplitThreadNum() {
704 return this.splits.getCorePoolSize();
705 }
706
707 protected int getMergeThreadNum() {
708 return this.mergePool.getCorePoolSize();
709 }
710
711
712
713
714 @Override
715 public void registerChildren(ConfigurationManager manager) {
716
717 }
718
719
720
721
722 @Override
723 public void deregisterChildren(ConfigurationManager manager) {
724
725 }
726
727 @VisibleForTesting
728 public ThroughputController getCompactionThroughputController() {
729 return compactionThroughputController;
730 }
731
732 @VisibleForTesting
733
734
735
736
737
738 void shutdownLongCompactions(){
739 this.longCompactions.shutdown();
740 }
741 }