/*******************************************************************************
* Copyright 2014 Analog Devices, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
package com.analog.lyric.collect.tests;
import static org.junit.Assert.*;
import java.util.concurrent.CountDownLatch;
import org.junit.Test;
import com.analog.lyric.collect.AtomicStampedDouble;
import com.analog.lyric.util.test.SerializationTester;
public class TestAtomicStampedDouble
{
@Test
public void test()
{
int[] stampHolder = new int[1];
//
// Single threaded tests
//
// Construction
AtomicStampedDouble d1 = new AtomicStampedDouble();
assertEquals(0.0, d1.get(), 0.0);
assertEquals(0, d1.getStamp());
stampHolder[0] = -1;
assertEquals(0.0, d1.get(stampHolder), 0.0);
assertEquals(0, stampHolder[0]);
d1 = new AtomicStampedDouble(3.145);
assertEquals(3.145, d1.get(), 0.0);
assertEquals(0, d1.getStamp());
stampHolder[0] = -1;
assertEquals(3.145, d1.get(stampHolder), 0.0);
assertEquals(0, stampHolder[0]);
d1 = new AtomicStampedDouble(42, 23);
assertEquals(42, d1.get(), 0.0);
assertEquals(23, d1.getStamp());
stampHolder[0] = -1;
assertEquals(42, d1.get(stampHolder), 0.0);
assertEquals(23, stampHolder[0]);
// Copying
AtomicStampedDouble d2 = new AtomicStampedDouble(d1);
assertEquals(d1.get(), d2.get(), 0.0);
assertEquals(d1.getStamp(), d2.getStamp());
// Serialization
d2 = SerializationTester.clone(d1);
assertEquals(d1.get(), d2.get(), 0.0);
assertEquals(d1.getStamp(), d2.getStamp());
// set
d1.set(1.2, 2);
assertEquals(1.2, d1.get(), 0.0);
assertEquals(2, d1.getStamp());
d1.set(1.2, 2);
assertEquals(1.2, d1.get(), 0.0);
assertEquals(2, d1.getStamp());
d1.set(1.2, 3);
assertEquals(1.2, d1.get(), 0.0);
assertEquals(3, d1.getStamp());
d1.set(1.3, 3);
assertEquals(1.3, d1.get(), 0.0);
assertEquals(3, d1.getStamp());
// setAndIncrementStamp
d1.setAndIncrementStamp(123);
assertEquals(123, d1.get(), 0.0);
assertEquals(4, d1.getStamp());
// attemptStamp
assertFalse(d1.attemptStamp(42, 9));
assertEquals(123, d1.get(), 0.0);
assertEquals(4, d1.getStamp());
assertTrue(d1.attemptStamp(123, 9));
assertEquals(123, d1.get(), 0.0);
assertEquals(9, d1.getStamp());
// compareAndSet
assertFalse(d1.compareAndSet(1.23, 1.45, 9, 11));
assertEquals(123, d1.get(), 0.0);
assertEquals(9, d1.getStamp());
assertFalse(d1.compareAndSet(123, 1.45, 3, 11));
assertEquals(123, d1.get(), 0.0);
assertEquals(9, d1.getStamp());
assertTrue(d1.compareAndSet(123, 1.45, 9, 11));
assertEquals(1.45, d1.get(), 0.0);
assertEquals(11, d1.getStamp());
//
// Multithreaded tests
//
final int nThreads = Runtime.getRuntime().availableProcessors();
int iterations = 10000;
CountDownLatch startRandomSet = new CountDownLatch(1);
RandomSetTester[] setTesters = new RandomSetTester[nThreads];
for (int i = 0; i < nThreads; ++i)
{
setTesters[i] = new RandomSetTester(d1, i * iterations, iterations, startRandomSet);
setTesters[i].start();
}
startRandomSet.countDown(); // Wave the start flag for the test threads
for (int i = 0; i < nThreads; ++i)
{
try
{
setTesters[i].join();
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
private static class RandomSetTester extends Thread
{
private final AtomicStampedDouble _d;
private final int _iterations;
private final CountDownLatch _startLatch;
private final int _startValue;
RandomSetTester(AtomicStampedDouble d, int value, int iterations, CountDownLatch startLatch)
{
_d = d;
_iterations = iterations;
_startLatch = startLatch;
_startValue = value;
}
@Override
public void run()
{
try
{
_startLatch.await();
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
int[] stampHolder = new int[1];
for (int i = _iterations, val = _startValue; --i>=0; ++val)
{
_d.set(val, val);
double val2 = _d.get(stampHolder);
assertEquals((int)val2, stampHolder[0]);
_d.compareAndSet(val, val, val-1, val-1);
val2 = _d.get(stampHolder);
assertEquals((int)val2, stampHolder[0]);
}
}
}
}