Commit | Line | Data |
---|---|---|
a52fde77 | 1 | /******************************************************************************* |
60ae41e1 | 2 | * Copyright (c) 2012, 2014 Ericsson |
a52fde77 AM |
3 | * Copyright (c) 2010, 2011 École Polytechnique de Montréal |
4 | * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com> | |
5df842b3 | 5 | * |
a52fde77 AM |
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 | |
5df842b3 | 10 | * |
a52fde77 AM |
11 | ******************************************************************************/ |
12 | ||
13 | package org.eclipse.linuxtools.tmf.core.statevalue; | |
14 | ||
77c2c2c9 | 15 | import org.eclipse.jdt.annotation.Nullable; |
6d08acca AM |
16 | import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; |
17 | ||
a52fde77 AM |
18 | /** |
19 | * This is the wrapper class that exposes the different types of 'state values' | |
20 | * available to use in the State System. | |
5df842b3 | 21 | * |
a52fde77 AM |
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 | |
24 | * 1-digit characters. | |
5df842b3 | 25 | * |
ec5fec10 | 26 | * The available types are Int, Long, Double and String. |
5df842b3 | 27 | * |
2cb26548 AM |
28 | * @version 1.0 |
29 | * @author Alexandre Montplaisir | |
a52fde77 AM |
30 | */ |
31 | public abstract class TmfStateValue implements ITmfStateValue { | |
44b69c99 EB |
32 | |
33 | // ------------------------------------------------------------------------ | |
34 | // State value caches (sizes must be powers of 2) | |
35 | // ------------------------------------------------------------------------ | |
36 | ||
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; | |
40 | ||
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]; | |
44 | ||
a9cdbafc AM |
45 | // ------------------------------------------------------------------------ |
46 | // Factory methods to instantiate new state values | |
47 | // ------------------------------------------------------------------------ | |
48 | ||
a52fde77 AM |
49 | /* |
50 | * Since all "null state values" are the same, we only need one copy in | |
51 | * memory. | |
52 | */ | |
53 | private static TmfStateValue nullValue = new NullStateValue(); | |
54 | ||
55 | /** | |
56 | * Return an instance of a "null" value. Only one copy exists in memory. | |
5df842b3 | 57 | * |
a52fde77 AM |
58 | * @return A null value |
59 | */ | |
cb42195c | 60 | public static final TmfStateValue nullValue() { |
a52fde77 AM |
61 | return nullValue; |
62 | } | |
63 | ||
64 | /** | |
65 | * Factory constructor for Integer state values | |
5df842b3 | 66 | * |
a9cdbafc AM |
67 | * @param intValue |
68 | * The integer value to contain | |
a52fde77 AM |
69 | * @return The newly-created TmfStateValue object |
70 | */ | |
71 | public static TmfStateValue newValueInt(int intValue) { | |
44b69c99 EB |
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) { | |
76 | return cached; | |
77 | } | |
78 | ||
79 | /* Not in cache, create a new value and cache it. */ | |
80 | IntegerStateValue newValue = new IntegerStateValue(intValue); | |
81 | intCache[offset] = newValue; | |
82 | return newValue; | |
a52fde77 AM |
83 | } |
84 | ||
85 | /** | |
a9cdbafc | 86 | * Factory constructor for Long state values |
5df842b3 | 87 | * |
a9cdbafc AM |
88 | * @param longValue |
89 | * The long value to contain | |
90 | * @return The newly-created TmfStateValue object | |
91 | * @since 2.0 | |
a52fde77 | 92 | */ |
a9cdbafc | 93 | public static TmfStateValue newValueLong(long longValue) { |
44b69c99 EB |
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) { | |
98 | return cached; | |
99 | } | |
100 | ||
101 | /* Not in cache, create a new value and cache it. */ | |
102 | LongStateValue newValue = new LongStateValue(longValue); | |
103 | longCache[offset] = newValue; | |
104 | return newValue; | |
a52fde77 AM |
105 | } |
106 | ||
a3c22e8e AM |
107 | /** |
108 | * Factory constructor for Double state values | |
109 | * | |
110 | * @param value | |
111 | * The double value to contain | |
112 | * @return The newly-created TmfStateValue object | |
c4767854 | 113 | * @since 3.0 |
a3c22e8e AM |
114 | */ |
115 | public static TmfStateValue newValueDouble(double value) { | |
44b69c99 EB |
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]; | |
119 | ||
120 | /* | |
121 | * We're using Double.compare() instead of .equals(), because .compare() | |
122 | * works when both values are Double.NaN. | |
123 | */ | |
124 | if (cached != null && Double.compare(cached.unboxDouble(), value) == 0) { | |
125 | return cached; | |
126 | } | |
127 | ||
128 | /* Not in cache, create a new value and cache it. */ | |
129 | DoubleStateValue newValue = new DoubleStateValue(value); | |
130 | doubleCache[offset] = newValue; | |
131 | return newValue; | |
a3c22e8e AM |
132 | } |
133 | ||
1cbf1a19 | 134 | /** |
a9cdbafc | 135 | * Factory constructor for String state values |
1cbf1a19 | 136 | * |
a9cdbafc AM |
137 | * @param strValue |
138 | * The string value to contain | |
139 | * @return The newly-created TmfStateValue object | |
1cbf1a19 | 140 | */ |
77c2c2c9 | 141 | public static TmfStateValue newValueString(@Nullable String strValue) { |
a9cdbafc | 142 | if (strValue == null) { |
1cbf1a19 FR |
143 | return nullValue(); |
144 | } | |
a9cdbafc | 145 | return new StringStateValue(strValue); |
1cbf1a19 FR |
146 | } |
147 | ||
a9cdbafc AM |
148 | // ------------------------------------------------------------------------ |
149 | // Default unboxing methods. | |
150 | // Subclasses can override those for the types they support. | |
151 | // ------------------------------------------------------------------------ | |
a52fde77 | 152 | |
a9cdbafc AM |
153 | private String unboxErrMsg(String targetType) { |
154 | return "Type " + getClass().getSimpleName() + //$NON-NLS-1$ | |
ec5fec10 | 155 | " cannot be unboxed into a " + targetType + " value."; //$NON-NLS-1$ //$NON-NLS-2$ |
a52fde77 AM |
156 | } |
157 | ||
158 | @Override | |
6dd46830 | 159 | public int unboxInt() { |
a9cdbafc | 160 | throw new StateValueTypeException(unboxErrMsg("Int")); //$NON-NLS-1$ |
a52fde77 | 161 | } |
1cbf1a19 | 162 | |
1cbf1a19 | 163 | @Override |
6dd46830 | 164 | public long unboxLong() { |
a9cdbafc AM |
165 | throw new StateValueTypeException(unboxErrMsg("Long")); //$NON-NLS-1$ |
166 | } | |
1cbf1a19 | 167 | |
c4767854 AM |
168 | /** |
169 | * @since 3.0 | |
170 | */ | |
a3c22e8e | 171 | @Override |
6dd46830 | 172 | public double unboxDouble() { |
a3c22e8e AM |
173 | throw new StateValueTypeException(unboxErrMsg("Double")); //$NON-NLS-1$ |
174 | } | |
175 | ||
a9cdbafc | 176 | @Override |
6dd46830 | 177 | public String unboxStr() { |
a9cdbafc | 178 | throw new StateValueTypeException(unboxErrMsg("String")); //$NON-NLS-1$ |
1cbf1a19 | 179 | } |
a52fde77 | 180 | } |