hadoop QuotaCounts 源码

  • 2022-10-20
  • 浏览 (84)

haddop QuotaCounts 代码

文件路径:/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/QuotaCounts.java

/**
 * 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.hdfs.server.namenode;

import org.apache.hadoop.classification.VisibleForTesting;
import org.apache.hadoop.fs.StorageType;
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
import org.apache.hadoop.hdfs.util.ConstEnumCounters;
import org.apache.hadoop.hdfs.util.EnumCounters;

import java.util.function.Consumer;

/**
 * Counters for namespace, storage space and storage type space quota and usage.
 */
public class QuotaCounts {

  /**
   * We pre-define 4 most common used EnumCounters objects. When the nsSsCounts
   * and tsCounts are set to the 4 most common used value, we just point them to
   * the pre-defined const EnumCounters objects instead of constructing many
   * objects with the same value. See HDFS-14547.
   */
  final static EnumCounters<Quota> QUOTA_RESET =
      new ConstEnumCounters<>(Quota.class, HdfsConstants.QUOTA_RESET);
  final static EnumCounters<Quota> QUOTA_DEFAULT =
      new ConstEnumCounters<>(Quota.class, 0);
  final static EnumCounters<StorageType> STORAGE_TYPE_RESET =
      new ConstEnumCounters<>(StorageType.class, HdfsConstants.QUOTA_RESET);
  final static EnumCounters<StorageType> STORAGE_TYPE_DEFAULT =
      new ConstEnumCounters<>(StorageType.class, 0);

  /**
   * Modify counter with action. If the counter is ConstEnumCounters, copy all
   * the values of it to a new EnumCounters object, and modify the new obj.
   *
   * @param counter the EnumCounters to be modified.
   * @param action the modifying action on counter.
   * @return the modified counter.
   */
  static <T extends Enum<T>> EnumCounters<T> modify(EnumCounters<T> counter,
      Consumer<EnumCounters<T>> action) {
    if (counter instanceof ConstEnumCounters) {
      counter = counter.deepCopyEnumCounter();
    }
    action.accept(counter);
    return counter;
  }

  // Name space and storage space counts (HDFS-7775 refactors the original disk
  // space count to storage space counts)
  @VisibleForTesting
  EnumCounters<Quota> nsSsCounts;
  // Storage type space counts
  @VisibleForTesting
  EnumCounters<StorageType> tsCounts;

  public static class Builder {
    private EnumCounters<Quota> nsSsCounts;
    private EnumCounters<StorageType> tsCounts;

    public Builder() {
      this.nsSsCounts = QUOTA_DEFAULT;
      this.tsCounts = STORAGE_TYPE_DEFAULT;
    }

    public Builder nameSpace(long val) {
      nsSsCounts =
          setQuotaCounter(nsSsCounts, Quota.NAMESPACE, Quota.STORAGESPACE, val);
      return this;
    }

    public Builder storageSpace(long val) {
      nsSsCounts =
          setQuotaCounter(nsSsCounts, Quota.STORAGESPACE, Quota.NAMESPACE, val);
      return this;
    }

    public Builder typeSpaces(EnumCounters<StorageType> val) {
      if (val != null) {
        if (val == STORAGE_TYPE_DEFAULT || val == STORAGE_TYPE_RESET) {
          tsCounts = val;
        } else {
          tsCounts = modify(tsCounts, ec -> ec.set(val));
        }
      }
      return this;
    }

    public Builder typeSpaces(long val) {
      if (val == HdfsConstants.QUOTA_RESET) {
        tsCounts = STORAGE_TYPE_RESET;
      } else if (val == 0) {
        tsCounts = STORAGE_TYPE_DEFAULT;
      } else {
        tsCounts = modify(tsCounts, ec -> ec.reset(val));
      }
      return this;
    }

    public Builder quotaCount(QuotaCounts that) {
      if (that.nsSsCounts == QUOTA_DEFAULT || that.nsSsCounts == QUOTA_RESET) {
        nsSsCounts = that.nsSsCounts;
      } else {
        nsSsCounts = modify(nsSsCounts, ec -> ec.set(that.nsSsCounts));
      }
      if (that.tsCounts == STORAGE_TYPE_DEFAULT
          || that.tsCounts == STORAGE_TYPE_RESET) {
        tsCounts = that.tsCounts;
      } else {
        tsCounts = modify(tsCounts, ec -> ec.set(that.tsCounts));
      }
      return this;
    }

    public QuotaCounts build() {
      return new QuotaCounts(this);
    }
  }

  private QuotaCounts(Builder builder) {
    this.nsSsCounts = builder.nsSsCounts;
    this.tsCounts = builder.tsCounts;
  }

  public QuotaCounts add(QuotaCounts that) {
    nsSsCounts = modify(nsSsCounts, ec -> ec.add(that.nsSsCounts));
    tsCounts = modify(tsCounts, ec -> ec.add(that.tsCounts));
    return this;
  }

  public QuotaCounts subtract(QuotaCounts that) {
    nsSsCounts = modify(nsSsCounts, ec -> ec.subtract(that.nsSsCounts));
    tsCounts = modify(tsCounts, ec -> ec.subtract(that.tsCounts));
    return this;
  }

  /**
   * Returns a QuotaCounts whose value is {@code (-this)}.
   *
   * @return {@code -this}
   */
  public QuotaCounts negation() {
    QuotaCounts ret = new QuotaCounts.Builder().quotaCount(this).build();
    ret.nsSsCounts = modify(ret.nsSsCounts, ec -> ec.negation());
    ret.tsCounts = modify(ret.tsCounts, ec -> ec.negation());
    return ret;
  }

  public long getNameSpace(){
    return nsSsCounts.get(Quota.NAMESPACE);
  }

  public void setNameSpace(long nameSpaceCount) {
    nsSsCounts =
        setQuotaCounter(nsSsCounts, Quota.NAMESPACE, Quota.STORAGESPACE,
            nameSpaceCount);
  }

  public void addNameSpace(long nsDelta) {
    nsSsCounts = modify(nsSsCounts, ec -> ec.add(Quota.NAMESPACE, nsDelta));
  }

  public long getStorageSpace(){
    return nsSsCounts.get(Quota.STORAGESPACE);
  }

  public void setStorageSpace(long spaceCount) {
    nsSsCounts =
        setQuotaCounter(nsSsCounts, Quota.STORAGESPACE, Quota.NAMESPACE,
            spaceCount);
  }

  public void addStorageSpace(long dsDelta) {
    nsSsCounts = modify(nsSsCounts, ec -> ec.add(Quota.STORAGESPACE, dsDelta));
  }

  public EnumCounters<StorageType> getTypeSpaces() {
    EnumCounters<StorageType> ret =
        new EnumCounters<StorageType>(StorageType.class);
    ret.set(tsCounts);
    return ret;
  }

  void setTypeSpaces(EnumCounters<StorageType> that) {
    if (that == STORAGE_TYPE_DEFAULT || that == STORAGE_TYPE_RESET) {
      tsCounts = that;
    } else if (that != null) {
      tsCounts = modify(tsCounts, ec -> ec.set(that));
    }
  }

  long getTypeSpace(StorageType type) {
    return this.tsCounts.get(type);
  }

  void setTypeSpace(StorageType type, long spaceCount) {
    tsCounts = modify(tsCounts, ec -> ec.set(type, spaceCount));
  }

  public void addTypeSpace(StorageType type, long delta) {
    tsCounts = modify(tsCounts, ec -> ec.add(type, delta));
  }

  public boolean anyNsSsCountGreaterOrEqual(long val) {
  if (nsSsCounts == QUOTA_DEFAULT) {
      return val <= 0;
    } else if (nsSsCounts == QUOTA_RESET) {
      return val <= HdfsConstants.QUOTA_RESET;
    }
    return nsSsCounts.anyGreaterOrEqual(val);
  }

  public boolean anyTypeSpaceCountGreaterOrEqual(long val) {
    if (tsCounts == STORAGE_TYPE_DEFAULT) {
      return val <= 0;
    } else if (tsCounts == STORAGE_TYPE_RESET) {
      return val <= HdfsConstants.QUOTA_RESET;
    }
    return tsCounts.anyGreaterOrEqual(val);
  }

  /**
   * Set inputCounts' value of Quota type quotaToSet to val.
   * inputCounts should be the left side value of this method.
   *
   * @param inputCounts the EnumCounters instance.
   * @param quotaToSet the quota type to be set.
   * @param otherQuota the other quota type besides quotaToSet.
   * @param val the value to be set.
   * @return the modified inputCounts.
   */
  private static EnumCounters<Quota> setQuotaCounter(
      EnumCounters<Quota> inputCounts, Quota quotaToSet, Quota otherQuota,
      long val) {
    if (val == HdfsConstants.QUOTA_RESET
        && inputCounts.get(otherQuota) == HdfsConstants.QUOTA_RESET) {
      return QUOTA_RESET;
    } else if (val == 0 && inputCounts.get(otherQuota) == 0) {
      return QUOTA_DEFAULT;
    } else {
      return modify(inputCounts, ec -> ec.set(quotaToSet, val));
    }
  }

  @Override
  public String toString() {
    return "name space=" + getNameSpace() +
        "\nstorage space=" + getStorageSpace() +
        "\nstorage types=" + getTypeSpaces();
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    } else if (!(obj instanceof QuotaCounts)) {
      return false;
    }
    final QuotaCounts that = (QuotaCounts)obj;
    return this.nsSsCounts.equals(that.nsSsCounts)
        && this.tsCounts.equals(that.tsCounts);
  }

  @Override
  public int hashCode() {
    assert false : "hashCode not designed";
    return 42; // any arbitrary constant will do
  }

}

相关信息

hadoop 源码目录

相关文章

hadoop AclEntryStatusFormat 源码

hadoop AclFeature 源码

hadoop AclStorage 源码

hadoop AclTransformation 源码

hadoop AuditLogger 源码

hadoop BackupImage 源码

hadoop BackupJournalManager 源码

hadoop BackupNode 源码

hadoop BackupState 源码

hadoop CacheManager 源码

0  赞