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 public CompactionRequest requestCompaction(final Region r, final Store s,
318 final String why, int priority, CompactionRequest request, User user) throws IOException {
319 return requestCompactionInternal(r, s, why, priority, request, true, user);
320 }
321
322 public synchronized void requestSystemCompaction(
323 final Region r, final String why) throws IOException {
324 requestCompactionInternal(r, why, Store.NO_PRIORITY, null, false, null);
325 }
326
327 public void requestSystemCompaction(
328 final Region r, final Store s, final String why) throws IOException {
329 requestCompactionInternal(r, s, why, Store.NO_PRIORITY, null, false, null);
330 }
331
332
333
334
335
336
337
338
339
340 private synchronized CompactionRequest requestCompactionInternal(final Region r, final Store s,
341 final String why, int priority, CompactionRequest request, boolean selectNow, User user)
342 throws IOException {
343 if (this.server.isStopped()
344 || (r.getTableDesc() != null && !r.getTableDesc().isCompactionEnabled())) {
345 return null;
346 }
347
348 CompactionContext compaction = null;
349 if (selectNow) {
350 compaction = selectCompaction(r, s, priority, request, user);
351 if (compaction == null) return null;
352 }
353
354
355
356 ThreadPoolExecutor pool = (selectNow && s.throttleCompaction(compaction.getRequest().getSize()))
357 ? longCompactions : shortCompactions;
358 pool.execute(new CompactionRunner(s, r, compaction, pool, user));
359 ((HRegion)r).incrementCompactionsQueuedCount();
360 if (LOG.isDebugEnabled()) {
361 String type = (pool == shortCompactions) ? "Small " : "Large ";
362 LOG.debug(type + "Compaction requested: " + (selectNow ? compaction.toString() : "system")
363 + (why != null && !why.isEmpty() ? "; Because: " + why : "") + "; " + this);
364 }
365 return selectNow ? compaction.getRequest() : null;
366 }
367
368 private CompactionContext selectCompaction(final Region r, final Store s,
369 int priority, CompactionRequest request, User user) throws IOException {
370 CompactionContext compaction = s.requestCompaction(priority, request, user);
371 if (compaction == null) {
372 if(LOG.isDebugEnabled() && r.getRegionInfo() != null) {
373 LOG.debug("Not compacting " + r.getRegionInfo().getRegionNameAsString() +
374 " because compaction request was cancelled");
375 }
376 return null;
377 }
378 assert compaction.hasSelection();
379 if (priority != Store.NO_PRIORITY) {
380 compaction.getRequest().setPriority(priority);
381 }
382 return compaction;
383 }
384
385
386
387
388 void interruptIfNecessary() {
389 splits.shutdown();
390 mergePool.shutdown();
391 longCompactions.shutdown();
392 shortCompactions.shutdown();
393 }
394
395 private void waitFor(ThreadPoolExecutor t, String name) {
396 boolean done = false;
397 while (!done) {
398 try {
399 done = t.awaitTermination(60, TimeUnit.SECONDS);
400 LOG.info("Waiting for " + name + " to finish...");
401 if (!done) {
402 t.shutdownNow();
403 }
404 } catch (InterruptedException ie) {
405 LOG.warn("Interrupted waiting for " + name + " to finish...");
406 }
407 }
408 }
409
410 void join() {
411 waitFor(splits, "Split Thread");
412 waitFor(mergePool, "Merge Thread");
413 waitFor(longCompactions, "Large Compaction Thread");
414 waitFor(shortCompactions, "Small Compaction Thread");
415 }
416
417
418
419
420
421
422
423 public int getCompactionQueueSize() {
424 return longCompactions.getQueue().size() + shortCompactions.getQueue().size();
425 }
426
427 public int getLargeCompactionQueueSize() {
428 return longCompactions.getQueue().size();
429 }
430
431
432 public int getSmallCompactionQueueSize() {
433 return shortCompactions.getQueue().size();
434 }
435
436 public int getSplitQueueSize() {
437 return splits.getQueue().size();
438 }
439
440 private boolean shouldSplitRegion() {
441 if(server.getNumberOfOnlineRegions() > 0.9*regionSplitLimit) {
442 LOG.warn("Total number of regions is approaching the upper limit " + regionSplitLimit + ". "
443 + "Please consider taking a look at http://hbase.apache.org/book.html#ops.regionmgt");
444 }
445 return (regionSplitLimit > server.getNumberOfOnlineRegions());
446 }
447
448
449
450
451 public int getRegionSplitLimit() {
452 return this.regionSplitLimit;
453 }
454
455 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="EQ_COMPARETO_USE_OBJECT_EQUALS",
456 justification="Contrived use of compareTo")
457 private class CompactionRunner implements Runnable, Comparable<CompactionRunner> {
458 private final Store store;
459 private final HRegion region;
460 private CompactionContext compaction;
461 private int queuedPriority;
462 private ThreadPoolExecutor parent;
463 private User user;
464 private long time;
465
466 public CompactionRunner(Store store, Region region,
467 CompactionContext compaction, ThreadPoolExecutor parent, User user) {
468 super();
469 this.store = store;
470 this.region = (HRegion)region;
471 this.compaction = compaction;
472 this.queuedPriority = (this.compaction == null)
473 ? store.getCompactPriority() : compaction.getRequest().getPriority();
474 this.parent = parent;
475 this.user = user;
476 this.time = System.currentTimeMillis();
477 }
478
479 @Override
480 public String toString() {
481 return (this.compaction != null) ? ("Request = " + compaction.getRequest())
482 : ("regionName = " + region.toString() + ", storeName = " + store.toString() +
483 ", priority = " + queuedPriority + ", time = " + time);
484 }
485
486 private void doCompaction(User user) {
487
488 if (this.compaction == null) {
489 int oldPriority = this.queuedPriority;
490 this.queuedPriority = this.store.getCompactPriority();
491 if (this.queuedPriority > oldPriority) {
492
493
494 this.parent.execute(this);
495 return;
496 }
497 try {
498 this.compaction = selectCompaction(this.region, this.store, queuedPriority, null, user);
499 } catch (IOException ex) {
500 LOG.error("Compaction selection failed " + this, ex);
501 server.checkFileSystem();
502 region.decrementCompactionsQueuedCount();
503 return;
504 }
505 if (this.compaction == null) {
506 region.decrementCompactionsQueuedCount();
507 return;
508 }
509
510
511 assert this.compaction.hasSelection();
512 ThreadPoolExecutor pool = store.throttleCompaction(
513 compaction.getRequest().getSize()) ? longCompactions : shortCompactions;
514
515
516
517 if (this.parent == shortCompactions && pool == longCompactions) {
518 this.store.cancelRequestedCompaction(this.compaction);
519 this.compaction = null;
520 this.parent = pool;
521 this.parent.execute(this);
522 return;
523 }
524 }
525
526 assert this.compaction != null;
527
528 this.compaction.getRequest().beforeExecute();
529 try {
530
531
532 long start = EnvironmentEdgeManager.currentTime();
533 boolean completed =
534 region.compact(compaction, store, compactionThroughputController, user);
535 long now = EnvironmentEdgeManager.currentTime();
536 LOG.info(((completed) ? "Completed" : "Aborted") + " compaction: " +
537 this + "; duration=" + StringUtils.formatTimeDiff(now, start));
538 if (completed) {
539
540 if (store.getCompactPriority() <= 0) {
541 requestSystemCompaction(region, store, "Recursive enqueue");
542 } else {
543
544 requestSplit(region);
545 }
546 }
547 } catch (IOException ex) {
548 IOException remoteEx = RemoteExceptionHandler.checkIOException(ex);
549 LOG.error("Compaction failed " + this, remoteEx);
550 if (remoteEx != ex) {
551 LOG.info("Compaction failed at original callstack: " + formatStackTrace(ex));
552 }
553 region.reportCompactionRequestFailure();
554 server.checkFileSystem();
555 } catch (Exception ex) {
556 LOG.error("Compaction failed " + this, ex);
557 region.reportCompactionRequestFailure();
558 server.checkFileSystem();
559 } finally {
560 region.decrementCompactionsQueuedCount();
561 LOG.debug("CompactSplitThread Status: " + CompactSplitThread.this);
562 }
563 this.compaction.getRequest().afterExecute();
564 }
565
566 @Override
567 public void run() {
568 Preconditions.checkNotNull(server);
569 if (server.isStopped()
570 || (region.getTableDesc() != null && !region.getTableDesc().isCompactionEnabled())) {
571 region.decrementCompactionsQueuedCount();
572 return;
573 }
574 doCompaction(user);
575 }
576
577 private String formatStackTrace(Exception ex) {
578 StringWriter sw = new StringWriter();
579 PrintWriter pw = new PrintWriter(sw);
580 ex.printStackTrace(pw);
581 pw.flush();
582 return sw.toString();
583 }
584
585 @Override
586 public int compareTo(CompactionRunner o) {
587
588 int compareVal = queuedPriority - o.queuedPriority;
589 if (compareVal != 0) return compareVal;
590 CompactionContext tc = this.compaction, oc = o.compaction;
591
592 return (tc == null) ? ((oc == null) ? 0 : 1)
593 : ((oc == null) ? -1 : tc.getRequest().compareTo(oc.getRequest()));
594 }
595 }
596
597
598
599
600 private static class Rejection implements RejectedExecutionHandler {
601 @Override
602 public void rejectedExecution(Runnable runnable, ThreadPoolExecutor pool) {
603 if (runnable instanceof CompactionRunner) {
604 CompactionRunner runner = (CompactionRunner)runnable;
605 LOG.debug("Compaction Rejected: " + runner);
606 runner.store.cancelRequestedCompaction(runner.compaction);
607 }
608 }
609 }
610
611
612
613
614 @Override
615 public void onConfigurationChange(Configuration newConf) {
616
617
618
619
620
621 int largeThreads = Math.max(1, newConf.getInt(
622 LARGE_COMPACTION_THREADS,
623 LARGE_COMPACTION_THREADS_DEFAULT));
624 if (this.longCompactions.getCorePoolSize() != largeThreads) {
625 LOG.info("Changing the value of " + LARGE_COMPACTION_THREADS +
626 " from " + this.longCompactions.getCorePoolSize() + " to " +
627 largeThreads);
628 if(this.longCompactions.getCorePoolSize() < largeThreads) {
629 this.longCompactions.setMaximumPoolSize(largeThreads);
630 this.longCompactions.setCorePoolSize(largeThreads);
631 } else {
632 this.longCompactions.setCorePoolSize(largeThreads);
633 this.longCompactions.setMaximumPoolSize(largeThreads);
634 }
635 }
636
637 int smallThreads = newConf.getInt(SMALL_COMPACTION_THREADS,
638 SMALL_COMPACTION_THREADS_DEFAULT);
639 if (this.shortCompactions.getCorePoolSize() != smallThreads) {
640 LOG.info("Changing the value of " + SMALL_COMPACTION_THREADS +
641 " from " + this.shortCompactions.getCorePoolSize() + " to " +
642 smallThreads);
643 if(this.shortCompactions.getCorePoolSize() < smallThreads) {
644 this.shortCompactions.setMaximumPoolSize(smallThreads);
645 this.shortCompactions.setCorePoolSize(smallThreads);
646 } else {
647 this.shortCompactions.setCorePoolSize(smallThreads);
648 this.shortCompactions.setMaximumPoolSize(smallThreads);
649 }
650 }
651
652 int splitThreads = newConf.getInt(SPLIT_THREADS,
653 SPLIT_THREADS_DEFAULT);
654 if (this.splits.getCorePoolSize() != splitThreads) {
655 LOG.info("Changing the value of " + SPLIT_THREADS +
656 " from " + this.splits.getCorePoolSize() + " to " +
657 splitThreads);
658 if(this.splits.getCorePoolSize() < splitThreads) {
659 this.splits.setMaximumPoolSize(splitThreads);
660 this.splits.setCorePoolSize(splitThreads);
661 } else {
662 this.splits.setCorePoolSize(splitThreads);
663 this.splits.setMaximumPoolSize(splitThreads);
664 }
665 }
666
667 int mergeThreads = newConf.getInt(MERGE_THREADS,
668 MERGE_THREADS_DEFAULT);
669 if (this.mergePool.getCorePoolSize() != mergeThreads) {
670 LOG.info("Changing the value of " + MERGE_THREADS +
671 " from " + this.mergePool.getCorePoolSize() + " to " +
672 mergeThreads);
673 if(this.mergePool.getCorePoolSize() < mergeThreads) {
674 this.mergePool.setMaximumPoolSize(mergeThreads);
675 this.mergePool.setCorePoolSize(mergeThreads);
676 } else {
677 this.mergePool.setCorePoolSize(mergeThreads);
678 this.mergePool.setMaximumPoolSize(mergeThreads);
679 }
680 }
681
682 ThroughputController old = this.compactionThroughputController;
683 if (old != null) {
684 old.stop("configuration change");
685 }
686 this.compactionThroughputController =
687 CompactionThroughputControllerFactory.create(server, newConf);
688
689
690
691 this.conf.reloadConfiguration();
692 }
693
694 protected int getSmallCompactionThreadNum() {
695 return this.shortCompactions.getCorePoolSize();
696 }
697
698 protected int getLargeCompactionThreadNum() {
699 return this.longCompactions.getCorePoolSize();
700 }
701
702 protected int getSplitThreadNum() {
703 return this.splits.getCorePoolSize();
704 }
705
706 protected int getMergeThreadNum() {
707 return this.mergePool.getCorePoolSize();
708 }
709
710
711
712
713 @Override
714 public void registerChildren(ConfigurationManager manager) {
715
716 }
717
718
719
720
721 @Override
722 public void deregisterChildren(ConfigurationManager manager) {
723
724 }
725
726 @VisibleForTesting
727 public ThroughputController getCompactionThroughputController() {
728 return compactionThroughputController;
729 }
730
731 @VisibleForTesting
732
733
734
735
736
737 void shutdownLongCompactions(){
738 this.longCompactions.shutdown();
739 }
740 }