1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.util.compaction;
19
20 import com.google.common.base.Optional;
21 import com.google.common.collect.Lists;
22 import com.google.common.collect.Maps;
23 import com.google.common.collect.Sets;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.concurrent.locks.ReadWriteLock;
28 import java.util.concurrent.locks.ReentrantReadWriteLock;
29 import org.apache.hadoop.hbase.ServerName;
30 import org.apache.hadoop.hbase.classification.InterfaceAudience;
31
32 @InterfaceAudience.Private
33 class ClusterCompactionQueues {
34
35 private final Map<ServerName, List<MajorCompactionRequest>> compactionQueues;
36 private final Set<ServerName> compactingServers;
37 private final ReadWriteLock lock;
38 private final int concurrentServers;
39
40 ClusterCompactionQueues(int concurrentServers) {
41 this.concurrentServers = concurrentServers;
42
43 this.compactionQueues = Maps.newHashMap();
44 this.lock = new ReentrantReadWriteLock();
45 this.compactingServers = Sets.newHashSet();
46 }
47
48 void addToCompactionQueue(ServerName serverName, MajorCompactionRequest info) {
49 this.lock.writeLock().lock();
50 try {
51 List<MajorCompactionRequest> result = this.compactionQueues.get(serverName);
52 if (result == null) {
53 result = Lists.newArrayList();
54 compactionQueues.put(serverName, result);
55 }
56 result.add(info);
57 } finally {
58 this.lock.writeLock().unlock();
59 }
60 }
61
62 boolean hasWorkItems() {
63 lock.readLock().lock();
64 try {
65 for (List<MajorCompactionRequest> majorCompactionRequests : this.compactionQueues.values()) {
66 if (!majorCompactionRequests.isEmpty()) {
67 return true;
68 }
69 }
70 return false;
71 } finally {
72 lock.readLock().unlock();
73 }
74 }
75
76 int getCompactionRequestsLeftToFinish() {
77 lock.readLock().lock();
78 try {
79 int size = 0;
80 for (List<MajorCompactionRequest> queue : compactionQueues.values()) {
81 size += queue.size();
82 }
83 return size;
84 } finally {
85 lock.readLock().unlock();
86 }
87 }
88
89 List<MajorCompactionRequest> getQueue(ServerName serverName) {
90 lock.readLock().lock();
91 try {
92 return compactionQueues.get(serverName);
93 } finally {
94 lock.readLock().unlock();
95 }
96 }
97
98 MajorCompactionRequest reserveForCompaction(ServerName serverName) {
99 lock.writeLock().lock();
100 try {
101 if (!compactionQueues.get(serverName).isEmpty()) {
102 compactingServers.add(serverName);
103 return compactionQueues.get(serverName).remove(0);
104 }
105 return null;
106 } finally {
107 lock.writeLock().unlock();
108 }
109 }
110
111 void releaseCompaction(ServerName serverName) {
112 lock.writeLock().lock();
113 try {
114 compactingServers.remove(serverName);
115 } finally {
116 lock.writeLock().unlock();
117 }
118 }
119
120 boolean atCapacity() {
121 lock.readLock().lock();
122 try {
123 return compactingServers.size() >= concurrentServers;
124 } finally {
125 lock.readLock().unlock();
126 }
127 }
128
129 Optional<ServerName> getLargestQueueFromServersNotCompacting() {
130 lock.readLock().lock();
131 try {
132 Sets.SetView<ServerName> difference =
133 Sets.difference(compactionQueues.keySet(), compactingServers);
134 ServerName serverName = null;
135 int maxItems = 0;
136 for (ServerName server : difference) {
137 if (compactionQueues.get(server).size() > maxItems) {
138 maxItems = compactionQueues.get(server).size();
139 serverName = server;
140 }
141 }
142 return Optional.fromNullable(serverName);
143 } finally {
144 lock.readLock().unlock();
145 }
146 }
147 }