/** * 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(); } } }