diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/HColumnDescriptor.java hbase-client/src/main/java/org/apache/hadoop/hbase/HColumnDescriptor.java index e888e6a..94cd263 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/HColumnDescriptor.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/HColumnDescriptor.java @@ -39,6 +39,8 @@ import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ColumnFamilySchema import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameStringPair; import org.apache.hadoop.hbase.regionserver.BloomType; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.PrettyPrinter; +import org.apache.hadoop.hbase.util.PrettyPrinter.Unit; import org.apache.hadoop.io.Text; import org.apache.hadoop.io.WritableComparable; @@ -929,6 +931,7 @@ public class HColumnDescriptor implements WritableComparable @Override public String toString() { StringBuilder s = new StringBuilder(); + s.append('{'); s.append(HConstants.NAME); s.append(" => '"); @@ -973,7 +976,7 @@ public class HColumnDescriptor implements WritableComparable s.append(", "); s.append(key); s.append(" => "); - s.append('\'').append(value).append('\''); + s.append('\'').append(PrettyPrinter.format(value, getUnit(key))).append('\''); } } @@ -995,7 +998,7 @@ public class HColumnDescriptor implements WritableComparable printComma = true; s.append('\'').append(key).append('\''); s.append(" => "); - s.append('\'').append(value).append('\''); + s.append('\'').append(PrettyPrinter.format(value, getUnit(key))).append('\''); } s.append('}'); } @@ -1010,13 +1013,24 @@ public class HColumnDescriptor implements WritableComparable printCommaForConfiguration = true; s.append('\'').append(e.getKey()).append('\''); s.append(" => "); - s.append('\'').append(e.getValue()).append('\''); + s.append('\'').append(PrettyPrinter.format(e.getValue(), getUnit(e.getKey()))).append('\''); } s.append("}"); } return s; } + public static Unit getUnit(String key) { + Unit unit; + /* TTL for now, we can add more as we neeed */ + if (key.equals(HColumnDescriptor.TTL)) { + unit = Unit.TIME_INTERVAL; + } else { + unit = Unit.NONE; + } + return unit; + } + public static Map getDefaultValues() { return Collections.unmodifiableMap(DEFAULT_VALUES); } diff --git hbase-client/src/test/java/org/apache/hadoop/hbase/util/TestPrettyPrinter.java hbase-client/src/test/java/org/apache/hadoop/hbase/util/TestPrettyPrinter.java new file mode 100644 index 0000000..1ba39f8 --- /dev/null +++ hbase-client/src/test/java/org/apache/hadoop/hbase/util/TestPrettyPrinter.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.hbase.util; + +import junit.framework.TestCase; + +import org.apache.hadoop.hbase.HColumnDescriptor; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.hadoop.hbase.SmallTests; + +@Category(SmallTests.class) +public class TestPrettyPrinter extends TestCase { + + @Test + public void testPrettyPrinterTTL() { + String out; + Long[] values = + { 0L, 1L, 1000L, 86400L, 259200L, 259203L, 90059L, Integer.MAX_VALUE - 1L, + Long.valueOf(Integer.MAX_VALUE) }; + String[] messages = + { "0 SECONDS", "1 SECOND", "1000 SECONDS (16 MINUTES 40 SECONDS)", "86400 SECONDS (1 DAY)", + "259200 SECONDS (3 DAYS)", "259203 SECONDS (3 DAYS 3 SECONDS)", + "90059 SECONDS (1 DAY 1 HOUR 59 SECONDS)", + "2147483646 SECONDS (24855 DAYS 3 HOURS 14 MINUTES 6 SECONDS)", + "FOREVER" }; + + for (int i = 0; i < values.length; i++) { + out = PrettyPrinter.format(Long.toString(values[i]), HColumnDescriptor.getUnit( + HColumnDescriptor.TTL)); + assertEquals( + String.format( + "Expected <%s> ", messages[i]), messages[i], out); + } + } +} diff --git hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java index 1b15770..31aebcb 100644 --- hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java +++ hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java @@ -507,6 +507,13 @@ public final class HConstants { */ public static final int WEEK_IN_SECONDS = 7 * 24 * 3600; + /** + * Seconds in a day, hour and minute + */ + public static final int DAY_IN_SECONDS = 24 * 60 * 60; + public static final int HOUR_IN_SECONDS = 60 * 60; + public static final int MINUTE_IN_SECONDS = 60; + //TODO: although the following are referenced widely to format strings for // the shell. They really aren't a part of the public API. It would be // nice if we could put them somewhere where they did not need to be diff --git hbase-common/src/main/java/org/apache/hadoop/hbase/util/PrettyPrinter.java hbase-common/src/main/java/org/apache/hadoop/hbase/util/PrettyPrinter.java new file mode 100644 index 0000000..702bda6 --- /dev/null +++ hbase-common/src/main/java/org/apache/hadoop/hbase/util/PrettyPrinter.java @@ -0,0 +1,101 @@ +/** + * + * 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.hbase.util; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.hbase.HConstants; + +@InterfaceAudience.Public +@InterfaceStability.Evolving +public class PrettyPrinter { + + public enum Unit { + TIME_INTERVAL, + NONE + } + + public static String format(final String value, final Unit unit) { + StringBuilder human = new StringBuilder(); + switch (unit) { + case TIME_INTERVAL: + human.append(humanReadableTTL(Long.valueOf(value))); + break; + default: + human.append(value); + } + return human.toString(); + } + + + private static String humanReadableTTL(final long interval){ + StringBuilder sb = new StringBuilder(); + int days, hours, minutes, seconds; + + // edge cases first + if (interval == Integer.MAX_VALUE) { + sb.append("FOREVER"); + return sb.toString(); + } + if (interval < HConstants.MINUTE_IN_SECONDS) { + sb.append(interval); + sb.append(" SECOND").append(interval == 1 ? "" : "S"); + return sb.toString(); + } + + days = (int) (interval / HConstants.DAY_IN_SECONDS); + hours = (int) (interval - HConstants.DAY_IN_SECONDS * days) / HConstants.HOUR_IN_SECONDS; + minutes = (int) (interval - HConstants.DAY_IN_SECONDS * days + - HConstants.HOUR_IN_SECONDS * hours) / HConstants.MINUTE_IN_SECONDS; + seconds = (int) (interval - HConstants.DAY_IN_SECONDS * days + - HConstants.HOUR_IN_SECONDS * hours - HConstants.MINUTE_IN_SECONDS * minutes); + + sb.append(interval); + sb.append(" SECONDS ("); + + if (days > 0) { + sb.append(days); + sb.append(" DAY").append(days == 1 ? "" : "S"); + } + + if (hours > 0 ) { + sb.append(days > 0 ? " " : ""); + sb.append(hours); + sb.append(" HOUR").append(hours == 1 ? "" : "S"); + } + + if (minutes > 0) { + sb.append(days + hours > 0 ? " " : ""); + sb.append(minutes); + sb.append(" MINUTE").append(minutes == 1 ? "" : "S"); + } + + if (seconds > 0) { + sb.append(days + hours + minutes > 0 ? " " : ""); + sb.append(seconds); + sb.append(" SECOND").append(minutes == 1 ? "" : "S"); + } + + sb.append(")"); + + return sb.toString(); + } + +}