1 /*******************************************************************************
2 * Copyright (c) 2012, 2014 Ericsson
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
6 * All rights reserved. This program and the accompanying materials are
7 * made available under the terms of the Eclipse Public License v1.0 which
8 * accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
11 ******************************************************************************/
13 package org
.eclipse
.linuxtools
.statesystem
.core
.statevalue
;
15 import org
.eclipse
.jdt
.annotation
.Nullable
;
16 import org
.eclipse
.linuxtools
.statesystem
.core
.exceptions
.StateValueTypeException
;
19 * This is the wrapper class that exposes the different types of 'state values'
20 * available to use in the State System.
22 * This also defines how these values are to be stored in the History Tree. For
23 * example, we can save numerical values as integers instead of arrays of
26 * The available types are Int, Long, Double and String.
28 * @author Alexandre Montplaisir
31 public abstract class TmfStateValue
implements ITmfStateValue
{
33 // ------------------------------------------------------------------------
34 // State value caches (sizes must be powers of 2)
35 // ------------------------------------------------------------------------
37 private static final int INT_CACHE_SIZE
= 128;
38 private static final int LONG_CACHE_SIZE
= 128;
39 private static final int DOUBLE_CACHE_SIZE
= 128;
41 private static final IntegerStateValue intCache
[] = new IntegerStateValue
[INT_CACHE_SIZE
];
42 private static final LongStateValue longCache
[] = new LongStateValue
[LONG_CACHE_SIZE
];
43 private static final DoubleStateValue doubleCache
[] = new DoubleStateValue
[DOUBLE_CACHE_SIZE
];
45 // ------------------------------------------------------------------------
46 // Factory methods to instantiate new state values
47 // ------------------------------------------------------------------------
50 * Since all "null state values" are the same, we only need one copy in
53 private static TmfStateValue nullValue
= new NullStateValue();
56 * Return an instance of a "null" value. Only one copy exists in memory.
58 * @return A null value
60 public static final TmfStateValue
nullValue() {
65 * Factory constructor for Integer state values
68 * The integer value to contain
69 * @return The newly-created TmfStateValue object
71 public static TmfStateValue
newValueInt(int intValue
) {
72 /* Lookup in cache for the existence of the same value. */
73 int offset
= intValue
& (INT_CACHE_SIZE
- 1);
74 IntegerStateValue cached
= intCache
[offset
];
75 if (cached
!= null && cached
.unboxInt() == intValue
) {
79 /* Not in cache, create a new value and cache it. */
80 IntegerStateValue newValue
= new IntegerStateValue(intValue
);
81 intCache
[offset
] = newValue
;
86 * Factory constructor for Long state values
89 * The long value to contain
90 * @return The newly-created TmfStateValue object
93 public static TmfStateValue
newValueLong(long longValue
) {
94 /* Lookup in cache for the existence of the same value. */
95 int offset
= (int) longValue
& (LONG_CACHE_SIZE
- 1);
96 LongStateValue cached
= longCache
[offset
];
97 if (cached
!= null && cached
.unboxLong() == longValue
) {
101 /* Not in cache, create a new value and cache it. */
102 LongStateValue newValue
= new LongStateValue(longValue
);
103 longCache
[offset
] = newValue
;
108 * Factory constructor for Double state values
111 * The double value to contain
112 * @return The newly-created TmfStateValue object
115 public static TmfStateValue
newValueDouble(double value
) {
116 /* Lookup in cache for the existence of the same value. */
117 int offset
= (int) Double
.doubleToLongBits(value
) & (DOUBLE_CACHE_SIZE
- 1);
118 DoubleStateValue cached
= doubleCache
[offset
];
121 * We're using Double.compare() instead of .equals(), because .compare()
122 * works when both values are Double.NaN.
124 if (cached
!= null && Double
.compare(cached
.unboxDouble(), value
) == 0) {
128 /* Not in cache, create a new value and cache it. */
129 DoubleStateValue newValue
= new DoubleStateValue(value
);
130 doubleCache
[offset
] = newValue
;
135 * Factory constructor for String state values
138 * The string value to contain
139 * @return The newly-created TmfStateValue object
141 public static TmfStateValue
newValueString(@Nullable String strValue
) {
142 if (strValue
== null) {
145 return new StringStateValue(strValue
);
148 // ------------------------------------------------------------------------
149 // Default unboxing methods.
150 // Subclasses can override those for the types they support.
151 // ------------------------------------------------------------------------
153 private String
unboxErrMsg(String targetType
) {
154 return "Type " + getClass().getSimpleName() + //$NON-NLS-1$
155 " cannot be unboxed into a " + targetType
+ " value."; //$NON-NLS-1$ //$NON-NLS-2$
159 public int unboxInt() {
160 throw new StateValueTypeException(unboxErrMsg("Int")); //$NON-NLS-1$
164 public long unboxLong() {
165 throw new StateValueTypeException(unboxErrMsg("Long")); //$NON-NLS-1$
172 public double unboxDouble() {
173 throw new StateValueTypeException(unboxErrMsg("Double")); //$NON-NLS-1$
177 public String
unboxStr() {
178 throw new StateValueTypeException(unboxErrMsg("String")); //$NON-NLS-1$