diff --git hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/FastNumberFormat.java hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/FastNumberFormat.java index e69de29bb2d..81e1bdb8fab 100644 --- hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/FastNumberFormat.java +++ hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/FastNumberFormat.java @@ -0,0 +1,55 @@ +/** + * 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.util; + +public class FastNumberFormat { + + public static final int MAX_COUNT = 19; + private final char[] digits = new char[MAX_COUNT]; + private int minimumIntegerDigits; + + public static FastNumberFormat getInstance() { + return new FastNumberFormat(); + } + + public void setMinimumIntegerDigits(int minimumIntegerDigits) { + this.minimumIntegerDigits = minimumIntegerDigits; + } + + public StringBuilder format(long source, StringBuilder sb) { + int left = MAX_COUNT; + if (source < 0) { + sb.append('-'); + source = - source; + } + while (source > 0) { + digits[--left] = (char)('0' + (source % 10)); + source /= 10; + } + while (MAX_COUNT - left < minimumIntegerDigits) { + digits[--left] = '0'; + } + sb.append(digits, left, MAX_COUNT - left); + return sb; + } + + public String format(long source) { + return format(source, new StringBuilder()).toString(); + } +} diff --git hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestFastNumberFormat.java hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestFastNumberFormat.java index e69de29bb2d..879982e5da8 100644 --- hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestFastNumberFormat.java +++ hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestFastNumberFormat.java @@ -0,0 +1,39 @@ +/** + * 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.util; + +import org.junit.Assert; +import org.junit.Test; + +import java.text.NumberFormat; + +public class TestFastNumberFormat { + + @Test(timeout = 1000) + public void testLongWithPadding() throws Exception { + FastNumberFormat fastNumberFormat = FastNumberFormat.getInstance(); + fastNumberFormat.setMinimumIntegerDigits(6); + NumberFormat numberFormat = NumberFormat.getInstance(); + numberFormat.setGroupingUsed(false); + numberFormat.setMinimumIntegerDigits(6); + long[] testLongs = {1, 23, 456, 7890, 12345, 678901, 2345689, 0, -0, -1, -23, -456, -7890, -12345, -678901, -2345689}; + for (long l: testLongs) { + Assert.assertEquals("Number formats should be equal", numberFormat.format(l), fastNumberFormat.format(l)); + } + } +} diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ApplicationAttemptId.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ApplicationAttemptId.java index 5f3a68ebe1a..32f8791a9eb 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ApplicationAttemptId.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ApplicationAttemptId.java @@ -18,7 +18,6 @@ package org.apache.hadoop.yarn.api.records; -import java.text.NumberFormat; import java.util.Iterator; import java.util.NoSuchElementException; @@ -26,6 +25,7 @@ import org.apache.hadoop.classification.InterfaceAudience.Public; import org.apache.hadoop.classification.InterfaceStability.Stable; import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.util.FastNumberFormat; import org.apache.hadoop.yarn.util.Records; import com.google.common.base.Splitter; @@ -84,12 +84,11 @@ public static ApplicationAttemptId newInstance(ApplicationId appId, @Unstable protected abstract void setAttemptId(int attemptId); - static final ThreadLocal attemptIdFormat = - new ThreadLocal() { + static final ThreadLocal attemptIdFormat = + new ThreadLocal() { @Override - public NumberFormat initialValue() { - NumberFormat fmt = NumberFormat.getInstance(); - fmt.setGroupingUsed(false); + public FastNumberFormat initialValue() { + FastNumberFormat fmt = FastNumberFormat.getInstance(); fmt.setMinimumIntegerDigits(6); return fmt; } @@ -138,9 +137,9 @@ public String toString() { StringBuilder sb = new StringBuilder(appAttemptIdStrPrefix); sb.append("_"); sb.append(this.getApplicationId().getClusterTimestamp()).append("_"); - sb.append(ApplicationId.appIdFormat.get().format( - this.getApplicationId().getId())); - sb.append("_").append(attemptIdFormat.get().format(getAttemptId())); + ApplicationId.appIdFormat.get().format( + this.getApplicationId().getId(), sb).append("_"); + attemptIdFormat.get().format(getAttemptId(), sb); return sb.toString(); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ApplicationId.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ApplicationId.java index 03a77ce309f..e5aa31525d5 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ApplicationId.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ApplicationId.java @@ -18,7 +18,6 @@ package org.apache.hadoop.yarn.api.records; -import java.text.NumberFormat; import java.util.Iterator; import java.util.NoSuchElementException; @@ -26,6 +25,7 @@ import org.apache.hadoop.classification.InterfaceAudience.Public; import org.apache.hadoop.classification.InterfaceStability.Stable; import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.util.FastNumberFormat; import org.apache.hadoop.yarn.util.Records; import com.google.common.base.Splitter; @@ -87,12 +87,11 @@ public static ApplicationId newInstance(long clusterTimestamp, int id) { protected abstract void build(); - static final ThreadLocal appIdFormat = - new ThreadLocal() { + static final ThreadLocal appIdFormat = + new ThreadLocal() { @Override - public NumberFormat initialValue() { - NumberFormat fmt = NumberFormat.getInstance(); - fmt.setGroupingUsed(false); + public FastNumberFormat initialValue() { + FastNumberFormat fmt = FastNumberFormat.getInstance(); fmt.setMinimumIntegerDigits(4); return fmt; } @@ -110,8 +109,12 @@ public int compareTo(ApplicationId other) { @Override public String toString() { - return appIdStrPrefix + "_" + this.getClusterTimestamp() + "_" + appIdFormat - .get().format(getId()); + StringBuilder sb = new StringBuilder(appIdStrPrefix); + sb.append("_"); + sb.append(this.getClusterTimestamp()); + sb.append("_"); + appIdFormat.get().format(getId(), sb); + return sb.toString(); } private static ApplicationId toApplicationId( diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerId.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerId.java index feddeca9e70..0ec438a7534 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerId.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ContainerId.java @@ -20,7 +20,6 @@ import com.google.common.base.Splitter; -import java.text.NumberFormat; import java.util.Iterator; import java.util.NoSuchElementException; @@ -28,6 +27,7 @@ import org.apache.hadoop.classification.InterfaceAudience.Public; import org.apache.hadoop.classification.InterfaceStability.Stable; import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.util.FastNumberFormat; import org.apache.hadoop.yarn.util.Records; /** @@ -116,24 +116,22 @@ public static ContainerId newInstance(ApplicationAttemptId appAttemptId, // TODO: fail the app submission if attempts are more than 10 or something - private static final ThreadLocal appAttemptIdAndEpochFormat = - new ThreadLocal() { + private static final ThreadLocal appAttemptIdAndEpochFormat = + new ThreadLocal() { @Override - public NumberFormat initialValue() { - NumberFormat fmt = NumberFormat.getInstance(); - fmt.setGroupingUsed(false); + public FastNumberFormat initialValue() { + FastNumberFormat fmt = FastNumberFormat.getInstance(); fmt.setMinimumIntegerDigits(2); return fmt; } }; // TODO: Why thread local? // ^ NumberFormat instances are not threadsafe - private static final ThreadLocal containerIdFormat = - new ThreadLocal() { + private static final ThreadLocal containerIdFormat = + new ThreadLocal() { @Override - public NumberFormat initialValue() { - NumberFormat fmt = NumberFormat.getInstance(); - fmt.setGroupingUsed(false); + public FastNumberFormat initialValue() { + FastNumberFormat fmt = FastNumberFormat.getInstance(); fmt.setMinimumIntegerDigits(6); return fmt; } @@ -189,18 +187,17 @@ public String toString() { sb.append(CONTAINER_PREFIX + "_"); long epoch = getContainerId() >> 40; if (epoch > 0) { - sb.append(EPOCH_PREFIX) - .append(appAttemptIdAndEpochFormat.get().format(epoch)).append("_");; + sb.append(EPOCH_PREFIX); + appAttemptIdAndEpochFormat.get().format(epoch, sb).append("_"); } ApplicationId appId = getApplicationAttemptId().getApplicationId(); sb.append(appId.getClusterTimestamp()).append("_"); - sb.append(ApplicationId.appIdFormat.get().format(appId.getId())) + ApplicationId.appIdFormat.get().format(appId.getId(), sb) .append("_"); - sb.append( - appAttemptIdAndEpochFormat.get().format( - getApplicationAttemptId().getAttemptId())).append("_"); - sb.append(containerIdFormat.get() - .format(CONTAINER_ID_BITMASK & getContainerId())); + appAttemptIdAndEpochFormat.get().format( + getApplicationAttemptId().getAttemptId(), sb).append("_"); + containerIdFormat.get() + .format(CONTAINER_ID_BITMASK & getContainerId(), sb); return sb.toString(); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationId.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationId.java index 71474b14b88..97956b7421f 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationId.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationId.java @@ -19,11 +19,11 @@ package org.apache.hadoop.yarn.api.records; import java.io.IOException; -import java.text.NumberFormat; import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceAudience.Public; import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.util.FastNumberFormat; import org.apache.hadoop.yarn.util.Records; /** @@ -89,12 +89,11 @@ public static ReservationId newInstance(long clusterTimestamp, long id) { protected abstract void build(); - static final ThreadLocal reservIdFormat = - new ThreadLocal() { + static final ThreadLocal reservIdFormat = + new ThreadLocal() { @Override - public NumberFormat initialValue() { - NumberFormat fmt = NumberFormat.getInstance(); - fmt.setGroupingUsed(false); + public FastNumberFormat initialValue() { + FastNumberFormat fmt = FastNumberFormat.getInstance(); fmt.setMinimumIntegerDigits(4); return fmt; }