1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.util;
18
19 /***
20 * Memory size parser using the letter k or K to indicate kilobytes, the letter m or M to indicate megabytes,
21 * the letter g or G to indicate gigabytes and the letter t or T to indicate terabytes.
22 *
23 * @author Ludovic Orban
24 */
25 public class MemorySizeParser {
26 private static final long BYTE = 1;
27 private static final long KILOBYTE = 1024;
28 private static final long MEGABYTE = 1024 * KILOBYTE;
29 private static final long GIGABYTE = 1024 * MEGABYTE;
30 private static final long TERABYTE = 1024 * GIGABYTE;
31
32 /***
33 * Parse a String containing a human-readable memory size.
34 *
35 * @param configuredMemorySize the String containing a human-readable memory size.
36 * @return the memory size in bytes.
37 * @throws IllegalArgumentException thrown when the configured memory size cannot be parsed.
38 */
39 public static long parse(String configuredMemorySize) throws IllegalArgumentException {
40 MemorySize size = parseIncludingUnit(configuredMemorySize);
41 return size.calculateMemorySizeInBytes();
42 }
43
44 private static MemorySize parseIncludingUnit(String configuredMemorySize) throws IllegalArgumentException {
45 if (configuredMemorySize == null || "".equals(configuredMemorySize)) {
46 return new MemorySize("0", BYTE);
47 }
48
49 char unit = configuredMemorySize.charAt(configuredMemorySize.length() - 1);
50 MemorySize memorySize;
51
52 switch (unit) {
53 case 'k':
54 case 'K':
55 memorySize = toMemorySize(configuredMemorySize, KILOBYTE);
56 break;
57 case 'm':
58 case 'M':
59 memorySize = toMemorySize(configuredMemorySize, MEGABYTE);
60 break;
61 case 'g':
62 case 'G':
63 memorySize = toMemorySize(configuredMemorySize, GIGABYTE);
64 break;
65 case 't':
66 case 'T':
67 memorySize = toMemorySize(configuredMemorySize, TERABYTE);
68 break;
69 default:
70 try {
71 Integer.parseInt("" + unit);
72 } catch (NumberFormatException e) {
73 throw new IllegalArgumentException("invalid format for memory size [" + configuredMemorySize + "]");
74 }
75 memorySize = new MemorySize(configuredMemorySize, BYTE);
76 }
77
78 return memorySize;
79 }
80
81 private static MemorySize toMemorySize(String configuredMemorySize, long unitMultiplier) {
82 if (configuredMemorySize.length() < 2) {
83 throw new IllegalArgumentException("invalid format for memory size [" + configuredMemorySize + "]");
84 }
85 return new MemorySize(configuredMemorySize.substring(0, configuredMemorySize.length() - 1), unitMultiplier);
86 }
87
88 /***
89 * Memory size calculator.
90 */
91 private static final class MemorySize {
92 private String configuredMemorySizeWithoutUnit;
93 private long multiplicationFactor;
94
95 private MemorySize(String configuredMemorySizeWithoutUnit, long multiplicationFactor) {
96 this.configuredMemorySizeWithoutUnit = configuredMemorySizeWithoutUnit;
97 this.multiplicationFactor = multiplicationFactor;
98 }
99
100 public long calculateMemorySizeInBytes() throws IllegalArgumentException {
101 try {
102 long memorySizeLong = Long.parseLong(configuredMemorySizeWithoutUnit);
103 long result = memorySizeLong * multiplicationFactor;
104 if (result < 0) {
105 throw new IllegalArgumentException("memory size cannot be negative");
106 }
107 return result;
108 } catch (NumberFormatException e) {
109 throw new IllegalArgumentException("invalid format for memory size");
110 }
111 }
112 }
113
114 }