2 * Copyright (c) 2015 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.common;
10 import static com.google.common.base.Preconditions.checkArgument;
12 import com.google.common.annotations.Beta;
13 import com.google.common.cache.CacheBuilder;
14 import com.google.common.cache.CacheLoader;
15 import com.google.common.cache.LoadingCache;
16 import com.google.common.primitives.UnsignedLong;
17 import java.math.BigInteger;
18 import org.opendaylight.yangtools.concepts.Immutable;
21 * Dedicated type for YANG's 'type uint64' type.
23 * @author Robert Varga
26 public final class Uint64 extends Number implements Comparable<Uint64>, Immutable {
27 private static final long serialVersionUID = 1L;
28 private static final long MIN_VALUE = 0;
31 * Cache of first 256 values.
33 private static final Uint64[] CACHE = new Uint64[Uint8.MAX_VALUE];
35 * Commonly encountered values.
37 private static final Uint64[] COMMON = {
38 new Uint64(Short.MAX_VALUE + 1L),
42 new Uint64(Integer.MAX_VALUE),
43 new Uint64(Integer.MAX_VALUE + 1L),
44 new Uint64(Long.MAX_VALUE),
48 * Tunable weak LRU cache for other values. By default it holds {@value #DEFAULT_LRU_SIZE} entries. This can be
49 * changed via {@value #LRU_SIZE_PROPERTY} system property.
51 private static final int DEFAULT_LRU_SIZE = 1024;
52 private static final String LRU_SIZE_PROPERTY = "org.opendaylight.yangtools.yang.common.Uint64.LRU.size";
53 private static final int MAX_LRU_SIZE = 0xffffff;
54 private static final int LRU_SIZE;
57 final int p = Integer.getInteger(LRU_SIZE_PROPERTY, DEFAULT_LRU_SIZE);
58 LRU_SIZE = p >= 0 ? Math.min(p, MAX_LRU_SIZE) : DEFAULT_LRU_SIZE;
61 private static final LoadingCache<Long, Uint64> LRU = CacheBuilder.newBuilder().weakValues().maximumSize(LRU_SIZE)
62 .build(new CacheLoader<Long, Uint64>() {
64 public Uint64 load(final Long key) {
65 return new Uint64(key);
69 private final long value;
71 private Uint64(final long value) {
75 private static Uint64 instanceFor(final long value) {
76 final int slot = (int)value;
77 if (value < 0 || slot >= CACHE.length) {
78 for (Uint64 c : COMMON) {
79 if (c.value == value) {
84 return LRU.getUnchecked(value);
87 Uint64 ret = CACHE[slot];
89 synchronized (CACHE) {
92 ret = new Uint64(value);
101 public static Uint64 fromLongBits(final long bits) {
102 return instanceFor(bits);
105 public static Uint64 fromUnsignedLong(final UnsignedLong ulong) {
106 return instanceFor(ulong.longValue());
109 public static Uint64 valueOf(final byte byteVal) {
110 checkArgument(byteVal >= MIN_VALUE, "Negative values are not allowed");
111 return instanceFor(byteVal);
114 public static Uint64 valueOf(final short shortVal) {
115 checkArgument(shortVal >= MIN_VALUE, "Negative values are not allowed");
116 return instanceFor(shortVal);
119 public static Uint64 valueOf(final int intVal) {
120 checkArgument(intVal >= MIN_VALUE, "Value %s is outside of allowed range", intVal);
121 return instanceFor(intVal);
124 public static Uint64 valueOf(final long longVal) {
125 checkArgument(longVal >= MIN_VALUE, "Value %s is outside of allowed range", longVal);
126 return instanceFor(longVal);
129 public static Uint64 valueOf(final Uint8 uint) {
130 return instanceFor(uint.shortValue());
133 public static Uint64 valueOf(final Uint16 uint) {
134 return instanceFor(uint.intValue());
137 public static Uint64 valueOf(final Uint32 uint) {
138 return instanceFor(uint.longValue());
141 public static Uint64 valueOf(final String string) {
142 return valueOf(string, 10);
145 public static Uint64 valueOf(final String string, final int radix) {
146 return instanceFor(Long.parseUnsignedLong(string, radix));
149 public static Uint64 valueOf(final BigInteger bigInt) {
150 checkArgument(bigInt.signum() >= 0, "Negative values not allowed");
151 checkArgument(bigInt.bitLength() <= Long.SIZE, "Value %s is outside of allowed range", bigInt);
153 return instanceFor(bigInt.longValue());
157 public int intValue() {
162 public long longValue() {
167 public float floatValue() {
169 return UnsignedLong.fromLongBits(value).floatValue();
173 public double doubleValue() {
175 return UnsignedLong.fromLongBits(value).doubleValue();
178 public UnsignedLong toUnsignedLong() {
179 return UnsignedLong.fromLongBits(value);
183 @SuppressWarnings("checkstyle:parameterName")
184 public int compareTo(final Uint64 o) {
185 return Long.compareUnsigned(value, o.value);
189 public int hashCode() {
190 return Long.hashCode(value);
194 public boolean equals(final Object obj) {
199 return obj instanceof Uint64 && value == ((Uint64)obj).value;
203 public String toString() {
204 return Long.toUnsignedString(value);
207 private Object readResolve() {
208 return instanceFor(value);