1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.hadoop.hbase.quotas;
18
19 import java.io.IOException;
20 import java.util.Map;
21 import java.util.Map.Entry;
22 import java.util.Objects;
23 import java.util.concurrent.locks.ReentrantReadWriteLock;
24 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
25 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
26
27 import org.apache.hadoop.hbase.HRegionInfo;
28 import org.apache.hadoop.hbase.TableName;
29 import org.apache.hadoop.hbase.client.Connection;
30 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
31 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
32 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.SpaceQuota;
33 import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot.SpaceQuotaStatus;
34
35 import com.google.common.base.Predicate;
36 import com.google.common.collect.Iterables;
37
38
39
40
41 public class TableQuotaSnapshotStore implements QuotaSnapshotStore<TableName> {
42 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
43 private final ReadLock rlock = lock.readLock();
44 private final WriteLock wlock = lock.writeLock();
45
46 private final Connection conn;
47 private final QuotaObserverChore chore;
48 private Map<HRegionInfo,Long> regionUsage;
49
50 public TableQuotaSnapshotStore(Connection conn, QuotaObserverChore chore, Map<HRegionInfo,Long> regionUsage) {
51 this.conn = Objects.requireNonNull(conn);
52 this.chore = Objects.requireNonNull(chore);
53 this.regionUsage = Objects.requireNonNull(regionUsage);
54 }
55
56 @Override
57 public SpaceQuota getSpaceQuota(TableName subject) throws IOException {
58 Quotas quotas = getQuotaForTable(subject);
59 if (quotas != null && quotas.hasSpace()) {
60 return quotas.getSpace();
61 }
62 return null;
63 }
64
65
66
67 Quotas getQuotaForTable(TableName table) throws IOException {
68 return QuotaTableUtil.getTableQuota(conn, table);
69 }
70
71 @Override
72 public SpaceQuotaSnapshot getCurrentState(TableName table) {
73
74 return chore.getTableQuotaSnapshot(table);
75 }
76
77 @Override
78 public SpaceQuotaSnapshot getTargetState(TableName table, SpaceQuota spaceQuota) {
79 rlock.lock();
80 try {
81 final long sizeLimitInBytes = spaceQuota.getSoftLimit();
82 long sum = 0L;
83 for (Entry<HRegionInfo,Long> entry : filterBySubject(table)) {
84 sum += entry.getValue();
85 }
86
87 SpaceQuotaStatus status = sum <= sizeLimitInBytes ? SpaceQuotaStatus.notInViolation()
88 : new SpaceQuotaStatus(ProtobufUtil.toViolationPolicy(spaceQuota.getViolationPolicy()));
89 return new SpaceQuotaSnapshot(status, sum, sizeLimitInBytes);
90 } finally {
91 rlock.unlock();
92 }
93 }
94
95 @Override
96 public Iterable<Entry<HRegionInfo,Long>> filterBySubject(final TableName table) {
97 rlock.lock();
98 try {
99 return Iterables.filter(regionUsage.entrySet(), new Predicate<Entry<HRegionInfo,Long>>() {
100 @Override
101 public boolean apply(Entry<HRegionInfo,Long> input) {
102 return table.equals(input.getKey().getTable());
103 }
104 });
105 } finally {
106 rlock.unlock();
107 }
108 }
109
110 @Override
111 public void setCurrentState(TableName table, SpaceQuotaSnapshot snapshot) {
112
113 this.chore.setTableQuotaSnapshot(table, snapshot);
114 }
115
116 @Override
117 public void setRegionUsage(Map<HRegionInfo,Long> regionUsage) {
118 wlock.lock();
119 try {
120 this.regionUsage = Objects.requireNonNull(regionUsage);
121 } finally {
122 wlock.unlock();
123 }
124 }
125 }