tmf: buf 495911 Fix timestamp transform fast for small timestamps
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core.tests / src / org / eclipse / tracecompass / tmf / core / tests / synchronization / TsTransformFastTest.java
CommitLineData
5745c0a3
FG
1/*******************************************************************************
2 * Copyright (c) 2015 École Polytechnique de Montréal
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Francis Giraldeau - Initial implementation and API
11 * Geneviève Bastien - Fixes and improvements
12 *******************************************************************************/
13
14package org.eclipse.tracecompass.tmf.core.tests.synchronization;
15
16import static org.junit.Assert.assertEquals;
17import static org.junit.Assert.assertNotNull;
18import static org.junit.Assert.assertTrue;
c338f3eb
GB
19import static org.junit.Assert.fail;
20
21import java.io.File;
22import java.io.FileInputStream;
23import java.io.FileOutputStream;
24import java.io.IOException;
25import java.io.ObjectInputStream;
26import java.io.ObjectOutputStream;
27import java.util.Arrays;
5745c0a3
FG
28
29import org.eclipse.tracecompass.internal.tmf.core.synchronization.TmfTimestampTransformLinear;
30import org.eclipse.tracecompass.internal.tmf.core.synchronization.TmfTimestampTransformLinearFast;
31import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform;
32import org.junit.Test;
c338f3eb
GB
33import org.junit.runner.RunWith;
34import org.junit.runners.Parameterized;
35import org.junit.runners.Parameterized.Parameters;
5745c0a3
FG
36
37/**
38 * Tests for {@link TmfTimestampTransformLinearFast}
39 *
40 * @author Geneviève Bastien
41 */
c338f3eb 42@RunWith(Parameterized.class)
5745c0a3
FG
43public class TsTransformFastTest {
44
45 private static final long ts = 1361657893526374091L;
46
c338f3eb
GB
47 private static interface IFastTransformFactory {
48 public TmfTimestampTransformLinearFast create(double alpha, double beta);
49 }
50
51 private static final IFastTransformFactory fNewObject = (a, b) -> {
52 return new TmfTimestampTransformLinearFast(a, b);
53 };
54
55 private static final IFastTransformFactory fDeserialized = (a, b) -> {
56 TmfTimestampTransformLinearFast tt = new TmfTimestampTransformLinearFast(a, b);
57 /* Serialize the object */
58 String filePath = null;
59 try {
60 File temp = File.createTempFile("serialSyncAlgo", ".tmp");
61 filePath = temp.getAbsolutePath();
62 } catch (IOException e) {
63 fail("Could not create temporary file for serialization");
64 }
65 assertNotNull(filePath);
66
67 try (FileOutputStream fileOut = new FileOutputStream(filePath);
68 ObjectOutputStream out = new ObjectOutputStream(fileOut);) {
69 out.writeObject(tt);
70 } catch (IOException e) {
71 fail("Error serializing the synchronization algorithm " + e.getMessage());
72 }
73
74 TmfTimestampTransformLinearFast deserialTt = null;
75 /* De-Serialize the object */
76 try (FileInputStream fileIn = new FileInputStream(filePath);
77 ObjectInputStream in = new ObjectInputStream(fileIn);) {
78 deserialTt = (TmfTimestampTransformLinearFast) in.readObject();
79 } catch (IOException | ClassNotFoundException e) {
80 fail("Error de-serializing the synchronization algorithm " + e.getMessage());
81 }
82 return deserialTt;
83 };
84
85 private final IFastTransformFactory fTransformFactory;
86
87 /**
88 * Constructor
89 *
90 * @param name
91 * The name of this parameterized test
92 * @param factory
93 * Factory to create the timestamp transform
94 */
95 public TsTransformFastTest(String name, IFastTransformFactory factory) {
96 fTransformFactory = factory;
97 }
98
99 /**
100 * @return the test parameters
101 */
102 @Parameters(name = "Factory={0}")
103 public static Iterable<Object[]> parameters() {
104 return Arrays.asList(new Object[][] {
105 { "Object", fNewObject },
106 { "Deserialized", fDeserialized }
107 });
108 }
109
5745c0a3
FG
110 /**
111 * Test whether the fast linear transform always yields the same value for
112 * the same timestamp
113 */
114 @Test
115 public void testFLTRepeatability() {
c338f3eb 116 TmfTimestampTransformLinearFast fast = fTransformFactory.create(Math.PI, 0);
5745c0a3
FG
117 // Access fDeltaMax to compute the cache range boundaries
118 long deltaMax = fast.getDeltaMax();
119 // Initialize the transform
120 long timestamp = ts - (ts % deltaMax);
121 fast.transform(timestamp);
122 long tsMiss = timestamp + deltaMax;
123 long tsNoMiss = timestamp + deltaMax - 1;
124
125 // Get the transformed value to a timestamp without cache miss
126 long tsTNoMiss = fast.transform(tsNoMiss);
127 assertEquals(1, fast.getCacheMisses());
128
129 // Cause a cache miss
130 fast.transform(tsMiss);
131 assertEquals(2, fast.getCacheMisses());
132
133 /*
134 * Get the transformed value of the same previous timestamp after the
135 * miss
136 */
137 long tsTAfterMiss = fast.transform(tsNoMiss);
138 assertEquals(tsTNoMiss, tsTAfterMiss);
139 }
140
141 /**
142 * Test that 2 equal fast transform always give the same results for the
143 * same values
144 */
145 @Test
146 public void testFLTEquivalence() {
c338f3eb
GB
147 TmfTimestampTransformLinearFast fast = fTransformFactory.create(Math.PI, 0);
148 TmfTimestampTransformLinearFast fast2 = fTransformFactory.create(Math.PI, 0);
5745c0a3
FG
149
150 long deltaMax = fast.getDeltaMax();
151
152 long start = (ts - (ts % deltaMax) - 10);
153 checkTime(fast, fast2, 20, start, 1);
154 }
155
156 /**
157 * Test the precision of the fast timestamp transform compared to the
158 * original transform.
159 */
160 @Test
161 public void testFastTransformPrecision() {
162 TmfTimestampTransformLinear precise = new TmfTimestampTransformLinear(Math.PI, 0);
c338f3eb 163 TmfTimestampTransformLinearFast fast = fTransformFactory.create(Math.PI, 0);
5745c0a3
FG
164 int samples = 100;
165 long start = (long) Math.pow(10, 18);
166 long end = Long.MAX_VALUE;
167 int step = (int) ((end - start) / (samples * Math.PI));
168 checkTime(precise, fast, samples, start, step);
169 assertEquals(samples, fast.getCacheMisses());
170
171 // check that rescale is done only when required
172 // assumes tsBitWidth == 30
173 // test forward and backward timestamps
174 samples = 1000;
175 int[] directions = new int[] { 1, -1 };
176 for (Integer direction : directions) {
177 for (int i = 0; i <= 30; i++) {
178 fast.resetScaleStats();
179 step = (1 << i) * direction;
180 checkTime(precise, fast, samples, start, step);
181 assertTrue(String.format("samples: %d scale misses: %d",
182 samples, fast.getCacheMisses()), samples >= fast.getCacheMisses());
183 }
184 }
5745c0a3
FG
185 }
186
187 /**
c338f3eb
GB
188 * Test that fast transform produces the same result for small and large
189 * slopes.
5745c0a3
FG
190 */
191 @Test
192 public void testFastTransformSlope() {
193 int[] dir = new int[] { 1, -1 };
194 long start = (1 << 30);
195 for (int ex = -9; ex <= 9; ex++) {
196 for (int d = 0; d < dir.length; d++) {
197 double slope = Math.pow(10.0, ex);
198 TmfTimestampTransformLinear precise = new TmfTimestampTransformLinear(slope, 0);
c338f3eb 199 TmfTimestampTransformLinearFast fast = fTransformFactory.create(slope, 0);
5745c0a3
FG
200 checkTime(precise, fast, 1000, start, dir[d]);
201 }
202 }
203 }
204
c338f3eb
GB
205 /**
206 * Test that fast transform produces the same result with a slope and
207 * offset, for small and large values
208 */
209 @Test
210 public void testFastTransformSlopeAndOffset() {
211 double offset = 54321.0;
212 double slope = Math.pow(10.0, 4);
213 for (int ex = 0; ex <= Long.SIZE - 1; ex++) {
214 long start = 1 << ex;
215 TmfTimestampTransformLinear precise = new TmfTimestampTransformLinear(slope, offset);
216 TmfTimestampTransformLinearFast fast = fTransformFactory.create(slope, offset);
217 checkTime(precise, fast, 5, start, 1);
218 }
219 }
220
5745c0a3
FG
221 /**
222 * Check that the proper exception are raised for illegal slopes
223 */
224 @Test
225 public void testFastTransformArguments() {
c338f3eb
GB
226 double[] slopes = new double[] { -1.0, ((double) Integer.MAX_VALUE) + 1, 1e-10 };
227 for (double slope : slopes) {
5745c0a3
FG
228 Exception exception = null;
229 try {
c338f3eb 230 fTransformFactory.create(slope, 0.0);
5745c0a3
FG
231 } catch (IllegalArgumentException e) {
232 exception = e;
233 }
234 assertNotNull(exception);
235 }
236 }
237
238 private static void checkTime(ITmfTimestampTransform precise, ITmfTimestampTransform fast,
239 int samples, long start, long step) {
240 long prev = 0;
241 for (int i = 0; i < samples; i++) {
242 long time = start + i * step;
243 long exp = precise.transform(time);
244 long act = fast.transform(time);
245 long err = act - exp;
246 // allow only two ns of error
c338f3eb 247 assertTrue("start: " + start + " [" + err + "]", Math.abs(err) < 3);
5745c0a3
FG
248 if (i > 0) {
249 if (step > 0) {
250 assertTrue("monotonic error" + act + " " + prev, act >= prev);
251 } else if (step < 0) {
252 assertTrue("monotonic ", act <= prev);
253 }
254 }
255 prev = act;
256 }
257 }
258
259}
This page took 0.07193 seconds and 5 git commands to generate.