blob: cc4af3dfb474630c684835532726e79755ac61d3 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager;
import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager;
public class QueueCapacities {
private static final String NL = CommonNodeLabelsManager.NO_LABEL;
private static final float LABEL_DOESNT_EXIST_CAP = 0f;
private Map<String, Capacities> capacitiesMap;
private ReadLock readLock;
private WriteLock writeLock;
private final boolean isRoot;
public QueueCapacities(boolean isRoot) {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
readLock = lock.readLock();
writeLock = lock.writeLock();
capacitiesMap = new HashMap<String, Capacities>();
this.isRoot = isRoot;
}
// Usage enum here to make implement cleaner
private enum CapacityType {
USED_CAP(0), ABS_USED_CAP(1), MAX_CAP(2), ABS_MAX_CAP(3), CAP(4), ABS_CAP(5),
MAX_AM_PERC(6), RESERVED_CAP(7), ABS_RESERVED_CAP(8);
private int idx;
private CapacityType(int idx) {
this.idx = idx;
}
}
private static class Capacities {
private float[] capacitiesArr;
public Capacities() {
capacitiesArr = new float[CapacityType.values().length];
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("{used=" + capacitiesArr[0] + "%, ");
sb.append("abs_used=" + capacitiesArr[1] + "%, ");
sb.append("max_cap=" + capacitiesArr[2] + "%, ");
sb.append("abs_max_cap=" + capacitiesArr[3] + "%, ");
sb.append("cap=" + capacitiesArr[4] + "%, ");
sb.append("abs_cap=" + capacitiesArr[5] + "%}");
sb.append("max_am_perc=" + capacitiesArr[6] + "%}");
sb.append("reserved_cap=" + capacitiesArr[7] + "%}");
sb.append("abs_reserved_cap=" + capacitiesArr[8] + "%}");
return sb.toString();
}
}
private float _get(String label, CapacityType type) {
try {
readLock.lock();
Capacities cap = capacitiesMap.get(label);
if (null == cap) {
return LABEL_DOESNT_EXIST_CAP;
}
return cap.capacitiesArr[type.idx];
} finally {
readLock.unlock();
}
}
private void _set(String label, CapacityType type, float value) {
try {
writeLock.lock();
Capacities cap = capacitiesMap.get(label);
if (null == cap) {
cap = new Capacities();
capacitiesMap.put(label, cap);
}
cap.capacitiesArr[type.idx] = value;
} finally {
writeLock.unlock();
}
}
/* Used Capacity Getter and Setter */
public float getUsedCapacity() {
return _get(NL, CapacityType.USED_CAP);
}
public float getUsedCapacity(String label) {
return _get(label, CapacityType.USED_CAP);
}
public void setUsedCapacity(float value) {
_set(NL, CapacityType.USED_CAP, value);
}
public void setUsedCapacity(String label, float value) {
_set(label, CapacityType.USED_CAP, value);
}
/* Absolute Used Capacity Getter and Setter */
public float getAbsoluteUsedCapacity() {
return _get(NL, CapacityType.ABS_USED_CAP);
}
public float getAbsoluteUsedCapacity(String label) {
return _get(label, CapacityType.ABS_USED_CAP);
}
public void setAbsoluteUsedCapacity(float value) {
_set(NL, CapacityType.ABS_USED_CAP, value);
}
public void setAbsoluteUsedCapacity(String label, float value) {
_set(label, CapacityType.ABS_USED_CAP, value);
}
/* Capacity Getter and Setter */
public float getCapacity() {
return _get(NL, CapacityType.CAP);
}
public float getCapacity(String label) {
if (StringUtils.equals(label, RMNodeLabelsManager.NO_LABEL) && isRoot) {
return 1f;
}
return _get(label, CapacityType.CAP);
}
public void setCapacity(float value) {
_set(NL, CapacityType.CAP, value);
}
public void setCapacity(String label, float value) {
_set(label, CapacityType.CAP, value);
}
/* Absolute Capacity Getter and Setter */
public float getAbsoluteCapacity() {
return _get(NL, CapacityType.ABS_CAP);
}
public float getAbsoluteCapacity(String label) {
if (StringUtils.equals(label, RMNodeLabelsManager.NO_LABEL) && isRoot) {
return 1f;
}
return _get(label, CapacityType.ABS_CAP);
}
public void setAbsoluteCapacity(float value) {
_set(NL, CapacityType.ABS_CAP, value);
}
public void setAbsoluteCapacity(String label, float value) {
_set(label, CapacityType.ABS_CAP, value);
}
/* Maximum Capacity Getter and Setter */
public float getMaximumCapacity() {
return _get(NL, CapacityType.MAX_CAP);
}
public float getMaximumCapacity(String label) {
return _get(label, CapacityType.MAX_CAP);
}
public void setMaximumCapacity(float value) {
_set(NL, CapacityType.MAX_CAP, value);
}
public void setMaximumCapacity(String label, float value) {
_set(label, CapacityType.MAX_CAP, value);
}
/* Absolute Maximum Capacity Getter and Setter */
public float getAbsoluteMaximumCapacity() {
return _get(NL, CapacityType.ABS_MAX_CAP);
}
public float getAbsoluteMaximumCapacity(String label) {
return _get(label, CapacityType.ABS_MAX_CAP);
}
public void setAbsoluteMaximumCapacity(float value) {
_set(NL, CapacityType.ABS_MAX_CAP, value);
}
public void setAbsoluteMaximumCapacity(String label, float value) {
_set(label, CapacityType.ABS_MAX_CAP, value);
}
/* Absolute Maximum AM resource percentage Getter and Setter */
public float getMaxAMResourcePercentage() {
return _get(NL, CapacityType.MAX_AM_PERC);
}
public float getMaxAMResourcePercentage(String label) {
return _get(label, CapacityType.MAX_AM_PERC);
}
public void setMaxAMResourcePercentage(String label, float value) {
_set(label, CapacityType.MAX_AM_PERC, value);
}
public void setMaxAMResourcePercentage(float value) {
_set(NL, CapacityType.MAX_AM_PERC, value);
}
/* Reserved Capacity Getter and Setter */
public float getReservedCapacity() {
return _get(NL, CapacityType.RESERVED_CAP);
}
public float getReservedCapacity(String label) {
return _get(label, CapacityType.RESERVED_CAP);
}
public void setReservedCapacity(float value) {
_set(NL, CapacityType.RESERVED_CAP, value);
}
public void setReservedCapacity(String label, float value) {
_set(label, CapacityType.RESERVED_CAP, value);
}
/* Absolute Reserved Capacity Getter and Setter */
public float getAbsoluteReservedCapacity() {
return _get(NL, CapacityType.ABS_RESERVED_CAP);
}
public float getAbsoluteReservedCapacity(String label) {
return _get(label, CapacityType.ABS_RESERVED_CAP);
}
public void setAbsoluteReservedCapacity(float value) {
_set(NL, CapacityType.ABS_RESERVED_CAP, value);
}
public void setAbsoluteReservedCapacity(String label, float value) {
_set(label, CapacityType.ABS_RESERVED_CAP, value);
}
/**
* Clear configurable fields, like
* (absolute)capacity/(absolute)maximum-capacity, this will be used by queue
* reinitialize, when we reinitialize a queue, we will first clear all
* configurable fields, and load new values
*/
public void clearConfigurableFields() {
try {
writeLock.lock();
for (String label : capacitiesMap.keySet()) {
_set(label, CapacityType.CAP, 0);
_set(label, CapacityType.MAX_CAP, 0);
_set(label, CapacityType.ABS_CAP, 0);
_set(label, CapacityType.ABS_MAX_CAP, 0);
}
} finally {
writeLock.unlock();
}
}
public Set<String> getExistingNodeLabels() {
try {
readLock.lock();
return new HashSet<String>(capacitiesMap.keySet());
} finally {
readLock.unlock();
}
}
@Override
public String toString() {
try {
readLock.lock();
return this.capacitiesMap.toString();
} finally {
readLock.unlock();
}
}
public Set<String> getNodePartitionsSet() {
try {
readLock.lock();
return capacitiesMap.keySet();
} finally {
readLock.unlock();
}
}
}