|
25 | 25 | import java.util.Iterator; |
26 | 26 | import java.util.Map; |
27 | 27 | import java.util.Map.Entry; |
| 28 | +import java.util.Optional; |
| 29 | +import java.util.Set; |
28 | 30 | import java.util.concurrent.ConcurrentHashMap; |
29 | 31 |
|
30 | 32 | import org.apache.commons.lang3.builder.HashCodeBuilder; |
@@ -693,23 +695,66 @@ public Map<RegionInfo, Long> snapshotRegionSizes() { |
693 | 695 | return copy; |
694 | 696 | } |
695 | 697 |
|
696 | | - int pruneEntriesOlderThan(long timeToPruneBefore) { |
| 698 | + int pruneEntriesOlderThan(long timeToPruneBefore, QuotaObserverChore quotaObserverChore) { |
697 | 699 | if (regionSizes == null) { |
698 | 700 | return 0; |
699 | 701 | } |
700 | 702 | int numEntriesRemoved = 0; |
701 | | - Iterator<Entry<RegionInfo,SizeSnapshotWithTimestamp>> iterator = |
| 703 | + Iterator<Entry<RegionInfo, SizeSnapshotWithTimestamp>> iterator = |
702 | 704 | regionSizes.entrySet().iterator(); |
703 | 705 | while (iterator.hasNext()) { |
704 | | - long currentEntryTime = iterator.next().getValue().getTime(); |
705 | | - if (currentEntryTime < timeToPruneBefore) { |
| 706 | + RegionInfo regionInfo = iterator.next().getKey(); |
| 707 | + long currentEntryTime = regionSizes.get(regionInfo).getTime(); |
| 708 | + // do not prune the entries if table is in violation and |
| 709 | + // violation policy is disable to avoid cycle of enable/disable. |
| 710 | + // Please refer HBASE-22012 for more details. |
| 711 | + // prune entries older than time. |
| 712 | + if (currentEntryTime < timeToPruneBefore && !isInViolationAndPolicyDisable( |
| 713 | + regionInfo.getTable(), quotaObserverChore)) { |
706 | 714 | iterator.remove(); |
707 | 715 | numEntriesRemoved++; |
708 | 716 | } |
709 | 717 | } |
710 | 718 | return numEntriesRemoved; |
711 | 719 | } |
712 | 720 |
|
| 721 | + /** |
| 722 | + * Method to check if a table is in violation and policy set on table is DISABLE. |
| 723 | + * |
| 724 | + * @param tableName tableName to check. |
| 725 | + * @param quotaObserverChore QuotaObserverChore instance |
| 726 | + * @return returns true if table is in violation and policy is disable else false. |
| 727 | + */ |
| 728 | + private boolean isInViolationAndPolicyDisable(TableName tableName, |
| 729 | + QuotaObserverChore quotaObserverChore) { |
| 730 | + boolean isInViolationAtTable = false; |
| 731 | + boolean isInViolationAtNamespace = false; |
| 732 | + SpaceViolationPolicy tablePolicy = null; |
| 733 | + SpaceViolationPolicy namespacePolicy = null; |
| 734 | + // Get Current Snapshot for the given table |
| 735 | + SpaceQuotaSnapshot tableQuotaSnapshot = quotaObserverChore.getTableQuotaSnapshot(tableName); |
| 736 | + SpaceQuotaSnapshot namespaceQuotaSnapshot = |
| 737 | + quotaObserverChore.getNamespaceQuotaSnapshot(tableName.getNamespaceAsString()); |
| 738 | + if (tableQuotaSnapshot != null) { |
| 739 | + // check if table in violation |
| 740 | + isInViolationAtTable = tableQuotaSnapshot.getQuotaStatus().isInViolation(); |
| 741 | + Optional<SpaceViolationPolicy> policy = tableQuotaSnapshot.getQuotaStatus().getPolicy(); |
| 742 | + if (policy.isPresent()) { |
| 743 | + tablePolicy = policy.get(); |
| 744 | + } |
| 745 | + } |
| 746 | + if (namespaceQuotaSnapshot != null) { |
| 747 | + // check namespace in violation |
| 748 | + isInViolationAtNamespace = namespaceQuotaSnapshot.getQuotaStatus().isInViolation(); |
| 749 | + Optional<SpaceViolationPolicy> policy = namespaceQuotaSnapshot.getQuotaStatus().getPolicy(); |
| 750 | + if (policy.isPresent()) { |
| 751 | + namespacePolicy = policy.get(); |
| 752 | + } |
| 753 | + } |
| 754 | + return (tablePolicy == SpaceViolationPolicy.DISABLE && isInViolationAtTable) || ( |
| 755 | + namespacePolicy == SpaceViolationPolicy.DISABLE && isInViolationAtNamespace); |
| 756 | + } |
| 757 | + |
713 | 758 | /** |
714 | 759 | * Removes each region size entry where the RegionInfo references the provided TableName. |
715 | 760 | * |
|
0 commit comments