diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/client/OzoneQuota.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/client/OzoneQuota.java index b3a762e2eda1..c8cf4fdd42ba 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/client/OzoneQuota.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/client/OzoneQuota.java @@ -1,4 +1,4 @@ -/** +/* * 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 @@ -19,12 +19,13 @@ package org.apache.hadoop.hdds.client; import com.google.common.base.Strings; +import org.apache.hadoop.ozone.OzoneConsts; +import org.apache.ratis.util.Preconditions; -import static org.apache.hadoop.ozone.OzoneConsts.GB; -import static org.apache.hadoop.ozone.OzoneConsts.KB; -import static org.apache.hadoop.ozone.OzoneConsts.MB; -import static org.apache.hadoop.ozone.OzoneConsts.TB; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * represents an OzoneQuota Object that can be applied to @@ -32,39 +33,71 @@ */ public final class OzoneQuota { - public static final String OZONE_QUOTA_B = "B"; - public static final String OZONE_QUOTA_KB = "KB"; - public static final String OZONE_QUOTA_MB = "MB"; - public static final String OZONE_QUOTA_GB = "GB"; - public static final String OZONE_QUOTA_TB = "TB"; - /** Quota Units.*/ - public enum Units { B, KB, MB, GB, TB } + public enum Units { + // the names and the ordering are important + B(1), + KB(OzoneConsts.KB), + MB(OzoneConsts.MB), + GB(OzoneConsts.GB), + TB(OzoneConsts.TB), + PB(OzoneConsts.PB), + EB(OzoneConsts.EB); + + private final long size; + private final List cache; + + Units(long size) { + this.size = size; + this.cache = createCache(this); + } - // Quota to decide how many buckets can be created. - private long quotaInNamespace; - // Quota to decide how many storage space will be used in bytes. - private long quotaInBytes; - private RawQuotaInBytes rawQuotaInBytes; - // Data class of Quota. - private static QuotaList quotaList; + private static List createCache(Units unit) { + final List quotas = new ArrayList<>(1024); + for (int i = 0; i < 1024; i++) { + quotas.add(new RawQuotaInBytes(unit, i)); + } + return Collections.unmodifiableList(quotas); + } + + public long getSize() { + return size; + } - /** Setting QuotaList parameters from large to small. */ + RawQuotaInBytes getRawQuotaInBytes(long b) { + return b < cache.size() ? cache.get(Math.toIntExact(b)) + : new RawQuotaInBytes(this, b); + } + } + + private static final List PARSE_ORDER; static { - quotaList = new QuotaList(); - quotaList.addQuotaList(OZONE_QUOTA_TB, Units.TB, TB); - quotaList.addQuotaList(OZONE_QUOTA_GB, Units.GB, GB); - quotaList.addQuotaList(OZONE_QUOTA_MB, Units.MB, MB); - quotaList.addQuotaList(OZONE_QUOTA_KB, Units.KB, KB); - quotaList.addQuotaList(OZONE_QUOTA_B, Units.B, 1L); + List reversed = new ArrayList<>(Arrays.asList(Units.values())); + Collections.reverse(reversed); + PARSE_ORDER = Collections.unmodifiableList(reversed); } + // Quota to decide how many buckets can be created. + private long quotaInNamespace; + // Quota to decide how many storage space will be used in bytes. + private final long quotaInBytes; + private final RawQuotaInBytes rawQuotaInBytes; + /** * Used to convert user input values into bytes such as: 1MB-> 1048576. */ private static class RawQuotaInBytes { - private Units unit; - private long size; + static RawQuotaInBytes valueOf(long quotaInBytes) { + Preconditions.assertTrue(quotaInBytes >= 0, () -> "quotaInBytes = " + quotaInBytes + " must be >= 0"); + final int i = Long.numberOfTrailingZeros(quotaInBytes) / 10; + final Units unit = Units.values()[i]; + final RawQuotaInBytes b = unit.getRawQuotaInBytes(quotaInBytes >> (i * 10)); + Preconditions.assertSame(quotaInBytes, b.sizeInBytes(), "sizeInBytes"); + return b; + } + + private final Units unit; + private final long size; RawQuotaInBytes(Units unit, long size) { this.unit = unit; @@ -83,14 +116,7 @@ public long getSize() { * Returns size in Bytes or negative num if there is no Quota. */ public long sizeInBytes() { - long sQuota = -1L; - for (Units quota : quotaList.getUnitQuotaArray()) { - if (quota == this.unit) { - sQuota = quotaList.getQuotaSize(quota); - break; - } - } - return this.getSize() * sQuota; + return this.getSize() * getUnit().getSize(); } @Override @@ -158,20 +184,21 @@ public static OzoneQuota parseSpaceQuota(String quotaInBytes) { String uppercase = quotaInBytes.toUpperCase() .replaceAll("\\s+", ""); String size = ""; - long nSize = 0; + final long nSize; Units currUnit = Units.B; try { - for (String quota : quotaList.getOzoneQuotaArray()) { + for (Units unit : PARSE_ORDER) { + final String quota = unit.name(); if (uppercase.endsWith((quota))) { size = uppercase .substring(0, uppercase.length() - quota.length()); - currUnit = quotaList.getUnits(quota); + currUnit = unit; break; } } // there might be no unit specified. - if (size.equals("")) { + if (size.isEmpty()) { size = uppercase; } nSize = Long.parseLong(size); @@ -240,15 +267,7 @@ public static OzoneQuota parseQuota(String quotaInBytes, */ public static OzoneQuota getOzoneQuota(long quotaInBytes, long quotaInNamespace) { - long size = 1L; - Units unit = Units.B; - for (Long quota : quotaList.getSizeQuotaArray()) { - if (quotaInBytes % quota == 0) { - size = quotaInBytes / quota; - unit = quotaList.getQuotaUnit(quota); - } - } - return new OzoneQuota(quotaInNamespace, new RawQuotaInBytes(unit, size)); + return new OzoneQuota(quotaInNamespace, RawQuotaInBytes.valueOf(quotaInBytes)); } public long getQuotaInNamespace() { diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/client/QuotaList.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/client/QuotaList.java deleted file mode 100644 index 230b825f4d45..000000000000 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/client/QuotaList.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * 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.hdds.client; - -import java.util.ArrayList; -import java.util.List; - -/** - *This class contains arraylist for storage constant used in OzoneQuota. - */ -public class QuotaList { - private final ArrayList ozoneQuota; - private final ArrayList unitQuota; - private final ArrayList sizeQuota; - - public QuotaList() { - ozoneQuota = new ArrayList<>(); - unitQuota = new ArrayList<>(); - sizeQuota = new ArrayList<>(); - } - - public void addQuotaList( - String oQuota, OzoneQuota.Units uQuota, Long sQuota) { - ozoneQuota.add(oQuota); - unitQuota.add(uQuota); - sizeQuota.add(sQuota); - } - - public List getOzoneQuotaArray() { - return this.ozoneQuota; - } - - public List getSizeQuotaArray() { - return this.sizeQuota; - } - - public List getUnitQuotaArray() { - return this.unitQuota; - } - - public OzoneQuota.Units getUnits(String oQuota) { - return unitQuota.get(ozoneQuota.indexOf(oQuota)); - } - - public Long getQuotaSize(OzoneQuota.Units uQuota) { - return sizeQuota.get(unitQuota.indexOf(uQuota)); - } - - public OzoneQuota.Units getQuotaUnit(Long sQuota) { - return unitQuota.get(sizeQuota.indexOf(sQuota)); - } - -} diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java index f3c08b252b1f..4e3f7e01cbea 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java @@ -119,6 +119,8 @@ public final class OzoneConsts { public static final long MB = KB * 1024L; public static final long GB = MB * 1024L; public static final long TB = GB * 1024L; + public static final long PB = TB * 1024L; + public static final long EB = PB * 1024L; /** * level DB names used by SCM and data nodes.