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.UnsignedInteger;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.kohsuke.MetaInfServices;
20 import org.opendaylight.yangtools.concepts.Variant;
23 * Dedicated type for YANG's 'type uint32' type.
25 * @author Robert Varga
29 public class Uint32 extends Number implements CanonicalValue<Uint32> {
30 @MetaInfServices(value = CanonicalValueSupport.class)
31 public static final class Support extends AbstractCanonicalValueSupport<Uint32> {
37 public Variant<Uint32, CanonicalValueViolation> fromString(final String str) {
39 return Variant.ofFirst(Uint32.valueOf(str));
40 } catch (IllegalArgumentException e) {
41 return CanonicalValueViolation.variantOf(e);
46 private static final CanonicalValueSupport<Uint32> SUPPORT = new Support();
47 private static final long serialVersionUID = 1L;
48 private static final long MIN_VALUE = 0;
49 private static final long MAX_VALUE = 0xffffffffL;
52 * Cache of first 256 values.
54 private static final Uint32[] CACHE = new Uint32[Uint8.MAX_VALUE];
56 * Commonly encountered values.
58 private static final Uint32[] COMMON = {
59 new Uint32(Short.MAX_VALUE),
63 new Uint32(Integer.MAX_VALUE),
67 * Tunable weak LRU cache for other values. By default it holds {@value #DEFAULT_LRU_SIZE} entries. This can be
68 * changed via {@value #LRU_SIZE_PROPERTY} system property.
70 private static final int DEFAULT_LRU_SIZE = 1024;
71 private static final String LRU_SIZE_PROPERTY = "org.opendaylight.yangtools.yang.common.Uint32.LRU.size";
72 private static final int MAX_LRU_SIZE = 0xffffff;
73 private static final int LRU_SIZE;
76 final int p = Integer.getInteger(LRU_SIZE_PROPERTY, DEFAULT_LRU_SIZE);
77 LRU_SIZE = p >= 0 ? Math.min(p, MAX_LRU_SIZE) : DEFAULT_LRU_SIZE;
80 private static final LoadingCache<Integer, Uint32> LRU = CacheBuilder.newBuilder().weakValues()
81 .maximumSize(LRU_SIZE).build(new CacheLoader<Integer, Uint32>() {
83 public Uint32 load(final Integer key) {
84 return new Uint32(key);
88 private final int value;
90 Uint32(final int value) {
94 protected Uint32(final Uint32 other) {
95 this.value = other.value;
98 private static Uint32 instanceFor(final int value) {
99 final long longSlot = Integer.toUnsignedLong(value);
100 if (longSlot >= CACHE.length) {
101 for (Uint32 c : COMMON) {
102 if (c.value == value) {
107 return LRU.getUnchecked(value);
110 final int slot = (int)longSlot;
111 Uint32 ret = CACHE[slot];
113 synchronized (CACHE) {
116 ret = new Uint32(value);
125 public static Uint32 fromIntBits(final int bits) {
126 return instanceFor(bits);
129 public static Uint32 fromUnsignedInteger(final UnsignedInteger uint) {
130 return instanceFor(uint.intValue());
133 public static Uint32 valueOf(final byte byteVal) {
134 checkArgument(byteVal >= MIN_VALUE, "Negative values are not allowed");
135 return instanceFor(byteVal);
138 public static Uint32 valueOf(final short shortVal) {
139 checkArgument(shortVal >= MIN_VALUE, "Negative values are not allowed");
140 return instanceFor(shortVal);
143 public static Uint32 valueOf(final int intVal) {
144 checkArgument(intVal >= MIN_VALUE, "Value %s is outside of allowed range", intVal);
145 return instanceFor(intVal);
148 public static Uint32 valueOf(final long longVal) {
149 checkArgument(longVal >= MIN_VALUE && longVal <= MAX_VALUE, "Value %s is outside of allowed range", longVal);
150 return instanceFor((int)longVal);
153 public static Uint32 valueOf(final Uint8 uint) {
154 return instanceFor(uint.shortValue());
157 public static Uint32 valueOf(final Uint16 uint) {
158 return instanceFor(uint.intValue());
161 public static Uint32 valueOf(final Uint64 uint) {
162 return valueOf(uint.longValue());
165 public static Uint32 valueOf(final String string) {
166 return valueOf(string, 10);
169 public static Uint32 valueOf(final String string, final int radix) {
170 return instanceFor(Integer.parseUnsignedInt(string, radix));
174 public final int intValue() {
179 public final long longValue() {
180 return Integer.toUnsignedLong(value);
184 public final float floatValue() {
189 public final double doubleValue() {
193 public final UnsignedInteger toUnsignedInteger() {
194 return UnsignedInteger.fromIntBits(value);
198 @SuppressWarnings("checkstyle:parameterName")
199 public final int compareTo(final Uint32 o) {
200 return Integer.compareUnsigned(value, o.value);
204 public final String toCanonicalString() {
205 return Integer.toUnsignedString(value);
209 public final CanonicalValueSupport<Uint32> support() {
214 public final int hashCode() {
215 return Integer.hashCode(value);
219 public final boolean equals(final @Nullable Object obj) {
220 return this == obj || obj instanceof Uint32 && value == ((Uint32)obj).value;
224 public final String toString() {
225 return toCanonicalString();
228 private Object readResolve() {
229 return instanceFor(value);