256 lines
7.7 KiB
Java
256 lines
7.7 KiB
Java
package net.reslate.islandsurvivalcraft.utilities.caching;
|
|
|
|
import static org.junit.Assert.assertSame;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
import java.util.Random;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import org.junit.jupiter.api.AfterEach;
|
|
import org.junit.jupiter.api.BeforeAll;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.TestInstance;
|
|
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
|
|
|
@TestInstance(Lifecycle.PER_CLASS)
|
|
public class CacheTest {
|
|
private volatile Cache<Integer, String> integerCache;
|
|
private final int LARGE_CACHE_SIZE = 262144;
|
|
private final int[] answers = new int[LARGE_CACHE_SIZE];
|
|
private final Random rand = new Random();
|
|
Cache<Integer, Integer> lCache = new Cache<>(LARGE_CACHE_SIZE);
|
|
|
|
@BeforeAll
|
|
public void setUp() {
|
|
integerCache = new Cache<>(3);
|
|
|
|
for (int i = 0; i < answers.length; i++) {
|
|
answers[i] = rand.nextInt();
|
|
}
|
|
}
|
|
|
|
@AfterEach
|
|
public void cleanUp() {
|
|
lCache.clearCache();
|
|
integerCache.clearCache();
|
|
}
|
|
|
|
@Test
|
|
public void testBasicCaching() {
|
|
String val = integerCache.get(0);
|
|
assertTrue(val == null);
|
|
val = "first";
|
|
integerCache.set(0, val);
|
|
assertTrue(integerCache.get(0) != null);
|
|
assertSame(val, integerCache.get(0));
|
|
|
|
val = integerCache.get(1);
|
|
assertTrue(val == null);
|
|
val = "second";
|
|
integerCache.set(1, val);
|
|
assertTrue(integerCache.get(1) != null);
|
|
assertSame(val, integerCache.get(1));
|
|
}
|
|
|
|
@Test
|
|
public void testUsageBasedClean() {
|
|
integerCache.set(0, "first");
|
|
integerCache.set(1, "second");
|
|
integerCache.set(2, "third");
|
|
|
|
assertEquals("first", integerCache.get(0));
|
|
|
|
integerCache.set(3, "fourth");
|
|
assertEquals("first", integerCache.get(0));
|
|
|
|
integerCache.set(4, "fifth");
|
|
assertTrue(integerCache.get(3) != null);
|
|
assertTrue(integerCache.get(0) != null);
|
|
}
|
|
|
|
@Test
|
|
public void testUsageLargeData() {
|
|
int amount = 1024;
|
|
Random random = new Random();
|
|
|
|
Cache<Integer, Integer> largeCache = new Cache<>(amount / 2);
|
|
|
|
int[] values = new int[amount];
|
|
for (int i = 0; i < amount; i++) {
|
|
values[i] = random.nextInt();
|
|
largeCache.set(i, values[i]);
|
|
}
|
|
|
|
for (int i = 0; i < amount / 2; i++) {
|
|
assertEquals(null, largeCache.get(i), "Current accessor: " + i);
|
|
}
|
|
|
|
for (int i = amount / 2; i < amount; i++) {
|
|
assertEquals(values[i], largeCache.get(i), "Current accessor: " + i);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testUsageLargeDataImportance() {
|
|
int amount = 1024;
|
|
Random random = new Random();
|
|
|
|
Cache<Integer, Integer> largeCache = new Cache<>(amount / 2);
|
|
|
|
int[] values = new int[amount];
|
|
for (int i = 0; i < amount; i++) {
|
|
values[i] = random.nextInt();
|
|
largeCache.set(i, values[i]);
|
|
largeCache.get(0);
|
|
}
|
|
|
|
for (int i = 1; i < (amount / 2) + 1; i++) {
|
|
assertEquals(null, largeCache.get(i), "Current accessor: " + i);
|
|
}
|
|
|
|
for (int i = (amount / 2) + 1; i < amount; i++) {
|
|
assertEquals(values[i], largeCache.get(i), "Current accessor: " + i);
|
|
}
|
|
|
|
assertEquals(values[0], largeCache.get(0));
|
|
}
|
|
|
|
@Test
|
|
public void testMultithreadingWriteConsistency() {
|
|
Runnable write = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
|
lCache.set(i, answers[i]);
|
|
}
|
|
}
|
|
};
|
|
|
|
Thread firstThread = new Thread(write);
|
|
firstThread.start();
|
|
Thread secondThread = new Thread(write);
|
|
secondThread.start();
|
|
Thread thirdThread = new Thread(write);
|
|
thirdThread.start();
|
|
|
|
try {
|
|
firstThread.join();
|
|
secondThread.join();
|
|
thirdThread.join();
|
|
} catch (InterruptedException e) {
|
|
assertFalse(false, e.getCause().getMessage());
|
|
}
|
|
|
|
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
|
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testMultithreadingReadConsistency() {
|
|
for (int i = 0; i < answers.length; i++) {
|
|
lCache.set(i, answers[i]);
|
|
}
|
|
|
|
Runnable read = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
|
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
|
}
|
|
}
|
|
};
|
|
|
|
Thread firstThread = new Thread(read);
|
|
firstThread.start();
|
|
Thread secondThread = new Thread(read);
|
|
secondThread.start();
|
|
Thread thirdThread = new Thread(read);
|
|
thirdThread.start();
|
|
|
|
try {
|
|
firstThread.join();
|
|
secondThread.join();
|
|
thirdThread.join();
|
|
} catch (InterruptedException e) {
|
|
assertFalse(false, e.getCause().getMessage());
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testMulthreadedReadWrite() {
|
|
Runnable readWrite = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
|
if (lCache.get(i) == null) {
|
|
lCache.set(i, answers[i]);
|
|
} else {
|
|
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
Runnable readAll = new Runnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
|
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
|
}
|
|
}
|
|
};
|
|
|
|
Thread firstThread = new Thread(readWrite);
|
|
firstThread.start();
|
|
Thread secondThread = new Thread(readWrite);
|
|
secondThread.start();
|
|
Thread thirdThread = new Thread(readAll);
|
|
|
|
try {
|
|
firstThread.join();
|
|
secondThread.join();
|
|
thirdThread.start();
|
|
thirdThread.join();
|
|
} catch (InterruptedException e) {
|
|
assertFalse(false, e.getCause().getMessage());
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testMultiThreadConsistency() {
|
|
Runnable readWriteCheck = new Runnable(){
|
|
|
|
@Override
|
|
public void run() {
|
|
for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
|
|
if (lCache.get(i) != null) {
|
|
assertEquals(answers[i], lCache.get(i), "Accessor at: " + i);
|
|
} else {
|
|
lCache.set(i, answers[i]);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
ExecutorService executorService = Executors.newFixedThreadPool(6);
|
|
executorService.submit(readWriteCheck);
|
|
executorService.submit(readWriteCheck);
|
|
executorService.submit(readWriteCheck);
|
|
executorService.submit(readWriteCheck);
|
|
executorService.submit(readWriteCheck);
|
|
executorService.submit(readWriteCheck);
|
|
|
|
try {
|
|
executorService.shutdown();
|
|
assertTrue(executorService.awaitTermination(1, TimeUnit.MINUTES), "Timed out.");
|
|
} catch (InterruptedException e) {
|
|
assertFalse(false, e.getCause().getMessage());
|
|
}
|
|
}
|
|
} |