pcap: Move plugins to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.statesystem.core / src / org / eclipse / linuxtools / statesystem / core / statevalue / TmfStateValue.java
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>
5 *
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
10 *
11 ******************************************************************************/
12
13 package org.eclipse.linuxtools.statesystem.core.statevalue;
14
15 import org.eclipse.jdt.annotation.Nullable;
16 import org.eclipse.linuxtools.internal.statesystem.core.Activator;
17 import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException;
18
19 /**
20 * This is the wrapper class that exposes the different types of 'state values'
21 * available to use in the State System.
22 *
23 * This also defines how these values are to be stored in the History Tree. For
24 * example, we can save numerical values as integers instead of arrays of
25 * 1-digit characters.
26 *
27 * The available types are Int, Long, Double and String.
28 *
29 * @author Alexandre Montplaisir
30 * @since 3.0
31 */
32 public abstract class TmfStateValue implements ITmfStateValue {
33
34 // ------------------------------------------------------------------------
35 // State value caches (sizes must be powers of 2)
36 // ------------------------------------------------------------------------
37
38 private static final int INT_CACHE_SIZE = 128;
39 private static final int LONG_CACHE_SIZE = 128;
40 private static final int DOUBLE_CACHE_SIZE = 128;
41
42 private static final IntegerStateValue intCache[] = new IntegerStateValue[INT_CACHE_SIZE];
43 private static final LongStateValue longCache[] = new LongStateValue[LONG_CACHE_SIZE];
44 private static final DoubleStateValue doubleCache[] = new DoubleStateValue[DOUBLE_CACHE_SIZE];
45
46 // ------------------------------------------------------------------------
47 // Factory methods to instantiate new state values
48 // ------------------------------------------------------------------------
49
50 /*
51 * Since all "null state values" are the same, we only need one copy in
52 * memory.
53 */
54 private static TmfStateValue nullValue = new NullStateValue();
55
56 /**
57 * Return an instance of a "null" value. Only one copy exists in memory.
58 *
59 * @return A null value
60 */
61 public static final TmfStateValue nullValue() {
62 return nullValue;
63 }
64
65 /**
66 * Factory constructor for Integer state values
67 *
68 * @param intValue
69 * The integer value to contain
70 * @return The newly-created TmfStateValue object
71 */
72 public static TmfStateValue newValueInt(int intValue) {
73 /* Lookup in cache for the existence of the same value. */
74 int offset = intValue & (INT_CACHE_SIZE - 1);
75 IntegerStateValue cached = intCache[offset];
76 if (cached != null && cached.unboxInt() == intValue) {
77 return cached;
78 }
79
80 /* Not in cache, create a new value and cache it. */
81 IntegerStateValue newValue = new IntegerStateValue(intValue);
82 intCache[offset] = newValue;
83 return newValue;
84 }
85
86 /**
87 * Factory constructor for Long state values
88 *
89 * @param longValue
90 * The long value to contain
91 * @return The newly-created TmfStateValue object
92 * @since 2.0
93 */
94 public static TmfStateValue newValueLong(long longValue) {
95 /* Lookup in cache for the existence of the same value. */
96 int offset = (int) longValue & (LONG_CACHE_SIZE - 1);
97 LongStateValue cached = longCache[offset];
98 if (cached != null && cached.unboxLong() == longValue) {
99 return cached;
100 }
101
102 /* Not in cache, create a new value and cache it. */
103 LongStateValue newValue = new LongStateValue(longValue);
104 longCache[offset] = newValue;
105 return newValue;
106 }
107
108 /**
109 * Factory constructor for Double state values
110 *
111 * @param value
112 * The double value to contain
113 * @return The newly-created TmfStateValue object
114 * @since 3.0
115 */
116 public static TmfStateValue newValueDouble(double value) {
117 /* Lookup in cache for the existence of the same value. */
118 int offset = (int) Double.doubleToLongBits(value) & (DOUBLE_CACHE_SIZE - 1);
119 DoubleStateValue cached = doubleCache[offset];
120
121 /*
122 * We're using Double.compare() instead of .equals(), because .compare()
123 * works when both values are Double.NaN.
124 */
125 if (cached != null && Double.compare(cached.unboxDouble(), value) == 0) {
126 return cached;
127 }
128
129 /* Not in cache, create a new value and cache it. */
130 DoubleStateValue newValue = new DoubleStateValue(value);
131 doubleCache[offset] = newValue;
132 return newValue;
133 }
134
135 /**
136 * Factory constructor for String state values
137 *
138 * @param strValue
139 * The string value to contain
140 * @return The newly-created TmfStateValue object
141 */
142 public static TmfStateValue newValueString(@Nullable String strValue) {
143 if (strValue == null) {
144 return nullValue();
145 }
146 /*
147 * Make sure the String does not contain "weird" things, like ISO
148 * control characters.
149 */
150 for (char c : strValue.toCharArray()) {
151 if (Character.isISOControl(c)) {
152 Activator.getDefault().logError("Trying to use invalid string: " + strValue); //$NON-NLS-1$
153 throw new IllegalArgumentException();
154 }
155 }
156 return new StringStateValue(strValue);
157 }
158
159 // ------------------------------------------------------------------------
160 // Default unboxing methods.
161 // Subclasses can override those for the types they support.
162 // ------------------------------------------------------------------------
163
164 private String unboxErrMsg(String targetType) {
165 return "Type " + getClass().getSimpleName() + //$NON-NLS-1$
166 " cannot be unboxed into a " + targetType + " value."; //$NON-NLS-1$ //$NON-NLS-2$
167 }
168
169 @Override
170 public int unboxInt() {
171 throw new StateValueTypeException(unboxErrMsg("Int")); //$NON-NLS-1$
172 }
173
174 @Override
175 public long unboxLong() {
176 throw new StateValueTypeException(unboxErrMsg("Long")); //$NON-NLS-1$
177 }
178
179 /**
180 * @since 3.0
181 */
182 @Override
183 public double unboxDouble() {
184 throw new StateValueTypeException(unboxErrMsg("Double")); //$NON-NLS-1$
185 }
186
187 @Override
188 public String unboxStr() {
189 throw new StateValueTypeException(unboxErrMsg("String")); //$NON-NLS-1$
190 }
191 }
This page took 0.036154 seconds and 5 git commands to generate.