use of com.google.common.reflect.TypeToken in project CorfuDB by CorfuDB.
the class SMRMultiLogunitTest method transactionalManyWritesThenRead.
/**
* Multi Threaded.
* Verify reads after multiple transactional writes done concurrently (using 2 threads)
*
* @throws TransactionAbortedException
*/
@Test(expected = TransactionAbortedException.class)
public void transactionalManyWritesThenRead() throws TransactionAbortedException {
int numKeys = ONE_THOUSAND;
ObjectsView view = getRuntime().getObjectsView();
final CountDownLatch barrier = new CountDownLatch(2);
Map<String, String> testMap = getRuntime().getObjectsView().build().setStreamName("test").setTypeToken(new TypeToken<SMRMap<String, String>>() {
}).open();
// concurrently run two conflicting transactions: one or the other should succeed without overlap
scheduleConcurrently((ignored_step) -> {
view.TXBegin();
for (int i = 0; i < numKeys; i++) {
String key = "key" + String.valueOf(i);
String val = "value0_" + String.valueOf(i);
testMap.put(key, val);
if (i == 0) {
barrier.countDown();
barrier.await();
}
if (i % ONE_HUNDRED == 0) {
Thread.yield();
}
}
view.TXEnd();
});
scheduleConcurrently((ignored_step) -> {
view.TXBegin();
for (int i = 0; i < numKeys; i++) {
String key = "key" + String.valueOf(i);
String val = "value1_" + String.valueOf(i);
testMap.put(key, val);
if (i == 0) {
barrier.countDown();
barrier.await();
}
if (i % ONE_HUNDRED == 0) {
Thread.yield();
}
}
view.TXEnd();
});
try {
executeScheduled(2, PARAMETERS.TIMEOUT_NORMAL);
} catch (TransactionAbortedException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
}
// check that all the values are either value0_ or value1_ not a mix
String base = "invalid";
for (int i = 0; i < numKeys; i++) {
String key = "key" + String.valueOf(i);
String val = testMap.get(key);
if (val != null) {
if (i == 0) {
int underscore = val.indexOf("_");
assertNotEquals(-1, underscore);
base = val.substring(0, underscore);
System.out.println("base is " + base);
}
}
assertEquals(true, val.contains(base));
}
}
use of com.google.common.reflect.TypeToken in project CorfuDB by CorfuDB.
the class CompileProxyTest method testObjectCounterCASConcurrency.
/**
* test serializability guarantee of mutatorAccessor methods.
* The test invokes CorfuSharedCounter::CAS by 'concurrency' number of concurrent threads.
* @throws Exception
*/
@Test
public void testObjectCounterCASConcurrency() throws Exception {
CorfuSharedCounter sharedCounter = getDefaultRuntime().getObjectsView().build().setStreamName("my stream").setTypeToken(new TypeToken<CorfuSharedCounter>() {
}).open();
int concurrency = PARAMETERS.CONCURRENCY_LOTS;
final int INITIAL = -1;
sharedCounter.setValue(INITIAL);
// concurrency invoke CAS by multiple threads
AtomicInteger casSucceeded = new AtomicInteger(0);
scheduleConcurrently(concurrency, t -> {
if (sharedCounter.CAS(INITIAL, t) == INITIAL)
casSucceeded.incrementAndGet();
});
executeScheduled(concurrency, PARAMETERS.TIMEOUT_SHORT);
// check that exactly one CAS succeeded
assertThat(sharedCounter.getValue()).isBetween(0, concurrency);
assertThat(casSucceeded.get()).isEqualTo(1);
}
use of com.google.common.reflect.TypeToken in project CorfuDB by CorfuDB.
the class CompileProxyTest method testObjectCounterConcurrencyStream.
/**
* the test is similar to the interleaved read/append above to a shared counter.
* in addition to checking read/append values, it tracks the raw stream state between updates and syncs.
*
* The test uses the interleaving engine to interleave numTasks*threads state machines.
* A simple state-machine is built. It randomly chooses to either read or append the counter.
* On a read, the last written value is expected.
*
* @throws Exception
*/
@Test
public void testObjectCounterConcurrencyStream() throws Exception {
CorfuSharedCounter sharedCounter = getDefaultRuntime().getObjectsView().build().setStreamName("my stream").setTypeToken(new TypeToken<CorfuSharedCounter>() {
}).open();
ICorfuSMR<CorfuSharedCounter> compiledSharedCounter = (ICorfuSMR<CorfuSharedCounter>) sharedCounter;
ICorfuSMRProxyInternal<CorfuSharedCounter> proxy_CORFUSMR = (ICorfuSMRProxyInternal<CorfuSharedCounter>) compiledSharedCounter.getCorfuSMRProxy();
// IStreamView objStream = proxy_CORFUSMR.getUnderlyingObject().getStreamViewUnsafe();
int numTasks = PARAMETERS.NUM_ITERATIONS_LOW;
Random r = new Random(PARAMETERS.SEED);
final int INITIAL = -1;
sharedCounter.setValue(INITIAL);
AtomicInteger lastUpdate = new AtomicInteger(INITIAL);
AtomicLong lastUpdateStreamPosition = new AtomicLong(0);
assertThat(sharedCounter.getValue()).isEqualTo(lastUpdate.get());
AtomicInteger lastRead = new AtomicInteger(INITIAL);
// build a state-machine:
// only one step: randomly choose between read/append of the shared counter
addTestStep((task_num) -> {
if (r.nextBoolean()) {
sharedCounter.setValue(task_num);
// remember the last written value
lastUpdate.set(task_num);
// advance the expected stream position
lastUpdateStreamPosition.incrementAndGet();
} else {
// before sync'ing the in-memory object, the in-memory copy does not get updated
// check that the in-memory copy is only as up-to-date as the latest 'get()'
assertThat(proxy_CORFUSMR.getUnderlyingObject().object.getValue()).isEqualTo(lastRead.get());
// now read, expect to get the latest written
assertThat(sharedCounter.getValue()).isEqualTo(lastUpdate.get());
// remember the last read
lastRead.set(lastUpdate.get());
}
});
// invoke the interleaving engine
scheduleInterleaved(PARAMETERS.CONCURRENCY_SOME, PARAMETERS.CONCURRENCY_SOME * numTasks);
}
use of com.google.common.reflect.TypeToken in project CorfuDB by CorfuDB.
the class ObjectsViewTest method canCopyObject.
@Test
@SuppressWarnings("unchecked")
public void canCopyObject() throws Exception {
//begin tests
CorfuRuntime r = getDefaultRuntime();
Map<String, String> smrMap = r.getObjectsView().build().setStreamName("map a").setTypeToken(new TypeToken<SMRMap<String, String>>() {
}).open();
smrMap.put("a", "a");
Map<String, String> smrMapCopy = r.getObjectsView().copy(smrMap, "map a copy");
smrMapCopy.put("b", "b");
assertThat(smrMapCopy).containsEntry("a", "a").containsEntry("b", "b");
assertThat(smrMap).containsEntry("a", "a").doesNotContainEntry("b", "b");
}
use of com.google.common.reflect.TypeToken in project CorfuDB by CorfuDB.
the class ObjectsViewTest method abortedTransactionDoesNotConflict.
@Test
@SuppressWarnings("unchecked")
public void abortedTransactionDoesNotConflict() throws Exception {
final String mapA = "map a";
//Enbale transaction logging
CorfuRuntime r = getDefaultRuntime().setTransactionLogging(true);
SMRMap<String, String> map = getDefaultRuntime().getObjectsView().build().setStreamName(mapA).setTypeToken(new TypeToken<SMRMap<String, String>>() {
}).open();
// TODO: fix so this does not require mapCopy.
SMRMap<String, String> mapCopy = getDefaultRuntime().getObjectsView().build().setStreamName(mapA).setTypeToken(new TypeToken<SMRMap<String, String>>() {
}).addOption(ObjectOpenOptions.NO_CACHE).open();
map.put("initial", "value");
Semaphore s1 = new Semaphore(0);
Semaphore s2 = new Semaphore(0);
// Schedule two threads, the first starts a transaction and reads,
// then waits for the second thread to finish.
// the second starts a transaction, waits for the first tx to read
// and commits.
// The first thread then resumes and attempts to commit. It should abort.
scheduleConcurrently(1, t -> {
assertThatThrownBy(() -> {
getRuntime().getObjectsView().TXBegin();
map.get("k");
s1.release();
s2.acquire();
map.put("k", "v1");
getRuntime().getObjectsView().TXEnd();
}).isInstanceOf(TransactionAbortedException.class);
});
scheduleConcurrently(1, t -> {
s1.acquire();
getRuntime().getObjectsView().TXBegin();
mapCopy.put("k", "v2");
getRuntime().getObjectsView().TXEnd();
s2.release();
});
executeScheduled(2, PARAMETERS.TIMEOUT_LONG);
// The result should contain T2s modification.
assertThat(map).containsEntry("k", "v2");
IStreamView txStream = r.getStreamsView().get(ObjectsView.TRANSACTION_STREAM_ID);
List<ILogData> txns = txStream.remainingUpTo(Long.MAX_VALUE);
assertThat(txns).hasSize(1);
assertThat(txns.get(0).getLogEntry(getRuntime()).getType()).isEqualTo(LogEntry.LogEntryType.MULTIOBJSMR);
MultiObjectSMREntry tx1 = (MultiObjectSMREntry) txns.get(0).getLogEntry(getRuntime());
MultiSMREntry entryMap = tx1.getEntryMap().get(CorfuRuntime.getStreamID(mapA));
assertThat(entryMap).isNotNull();
assertThat(entryMap.getUpdates().size()).isEqualTo(1);
SMREntry smrEntry = entryMap.getUpdates().get(0);
Object[] args = smrEntry.getSMRArguments();
assertThat(smrEntry.getSMRMethod()).isEqualTo("put");
assertThat((String) args[0]).isEqualTo("k");
assertThat((String) args[1]).isEqualTo("v2");
}
Aggregations