gtf.init(false, false, true, false);
final String k1 = k(m, 1), k2 = k(m, 2), k3 = k(m, 3), v1 = v(m, 1), v2 = v(m, 2), v3 = v(m, 3);
final AtomicInteger storeCount = new AtomicInteger();
final AtomicInteger removeCount = new AtomicInteger();
final AtomicInteger clearCount = new AtomicInteger();
final CyclicBarrier barrier = new CyclicBarrier(2);
DummyInMemoryCacheStore underlying = new DummyInMemoryCacheStore() {
@Override
public void store(InternalCacheEntry ed) {
super.store(ed);
storeCount.getAndIncrement();
}
@Override
public boolean remove(Object key) {
boolean ret = super.remove(key);
removeCount.getAndIncrement();
return ret;
}
@Override
public void clear() {
super.clear();
clearCount.getAndIncrement();
}
};
store = new AsyncStore(underlying, asyncConfig) {
@Override
protected void applyModificationsSync(List<Modification> mods)
throws CacheLoaderException {
super.applyModificationsSync(mods);
try {
log.tracef("Wait to apply modifications: %s", mods);
barrier.await(waitTimeout, waitUnit);
} catch (TimeoutException e) {
assert false : "Timed out applying for modifications";
} catch (Exception e) {
throw new CacheLoaderException("Barrier failed", e);
}
}
};
dummyCfg = new DummyInMemoryCacheStore.Cfg();
dummyCfg.setStoreName(m.getName());
store.init(dummyCfg, null, null);
store.start();
List<Modification> mods = new ArrayList<Modification>();
mods.add(new Store(TestInternalCacheEntryFactory.create(k1, v1)));
mods.add(new Store(TestInternalCacheEntryFactory.create(k1, v2)));
mods.add(new Store(TestInternalCacheEntryFactory.create(k2, v1)));
mods.add(new Store(TestInternalCacheEntryFactory.create(k2, v2)));
mods.add(new Remove(k1));
GlobalTransaction tx = gtf.newGlobalTransaction(null, false);
store.prepare(mods, tx, false);
Thread.sleep(200); //verify that work is not performed until commit
assert 0 == storeCount.get();
assert 0 == removeCount.get();
assert 0 == clearCount.get();
store.commit(tx);
log.tracef("Wait for modifications to be queued: %s", mods);
barrier.await(waitTimeout, waitUnit); // Wait for single store to be applied
barrier.await(waitTimeout, waitUnit); // Wait for single remove to be applied
assert 1 == storeCount.get() : "Store count was " + storeCount.get();
assert 1 == removeCount.get();
assert 0 == clearCount.get();
storeCount.set(0);
removeCount.set(0);
clearCount.set(0);
mods = new ArrayList<Modification>();
mods.add(new Store(TestInternalCacheEntryFactory.create(k1, v1)));
mods.add(new Remove(k1));
mods.add(new Clear());
mods.add(new Store(TestInternalCacheEntryFactory.create(k2, v2)));
mods.add(new Remove(k2));
tx = gtf.newGlobalTransaction(null, false);
store.prepare(mods, tx, false);
Thread.sleep(200); //verify that work is not performed until commit
assert 0 == storeCount.get();
assert 0 == removeCount.get();
assert 0 == clearCount.get();
store.commit(tx);
barrier.await(waitTimeout, waitUnit);
assert 0 == storeCount.get() : "Store count was " + storeCount.get();
assert 1 == removeCount.get();
assert 1 == clearCount.get();
storeCount.set(0);
removeCount.set(0);
clearCount.set(0);
mods = new ArrayList<Modification>();
mods.add(new Store(TestInternalCacheEntryFactory.create(k1, v1)));
mods.add(new Remove(k1));
mods.add(new Store(TestInternalCacheEntryFactory.create(k2, v2)));
mods.add(new Remove(k2));
mods.add(new Store(TestInternalCacheEntryFactory.create(k3, v3)));
tx = gtf.newGlobalTransaction(null, false);
store.prepare(mods, tx, false);
Thread.sleep(200);
assert 0 == storeCount.get();
assert 0 == removeCount.get();
assert 0 == clearCount.get();
store.commit(tx);
barrier.await(waitTimeout, waitUnit); // Wait for store to be applied
barrier.await(waitTimeout, waitUnit); // Wait for first removal to be applied
barrier.await(waitTimeout, waitUnit); // Wait for second removal to be applied
assert 1 == storeCount.get() : "Store count was " + storeCount.get();
assert 2 == removeCount.get();
assert 0 == clearCount.get();
storeCount.set(0);
removeCount.set(0);
clearCount.set(0);
mods = new ArrayList<Modification>();
mods.add(new Clear());
mods.add(new Remove(k1));
tx = gtf.newGlobalTransaction(null, false);
store.prepare(mods, tx, false);
Thread.sleep(200);
assert 0 == storeCount.get();
assert 0 == removeCount.get();
assert 0 == clearCount.get();
store.commit(tx);
barrier.await(waitTimeout, waitUnit);
assert 0 == storeCount.get() : "Store count was " + storeCount.get();
assert 1 == removeCount.get();
assert 1 == clearCount.get();
storeCount.set(0);
removeCount.set(0);
clearCount.set(0);
mods = new ArrayList<Modification>();
mods.add(new Clear());
mods.add(new Store(TestInternalCacheEntryFactory.create(k1, v1)));
tx = gtf.newGlobalTransaction(null, false);
store.prepare(mods, tx, false);
Thread.sleep(200);
assert 0 == storeCount.get();
assert 0 == removeCount.get();
assert 0 == clearCount.get();
store.commit(tx);
barrier.await(waitTimeout, waitUnit);
assert 1 == storeCount.get() : "Store count was " + storeCount.get();
assert 0 == removeCount.get();
assert 1 == clearCount.get();
} finally {
store.delegate.clear();