use of org.apache.ignite.internal.util.lang.GridInClosure3 in project ignite by apache.
the class CacheMvccSqlQueriesAbstractTest method updateSingleValue.
/**
* @param singleNode {@code True} for test with single node.
* @param locQry Local query flag.
* @throws Exception If failed.
*/
private void updateSingleValue(boolean singleNode, final boolean locQry) throws Exception {
final int VALS = 100;
final int writers = 4;
final int readers = 4;
final int INC_BY = 110;
final IgniteInClosure<IgniteCache<Object, Object>> init = new IgniteInClosure<IgniteCache<Object, Object>>() {
@Override
public void apply(IgniteCache<Object, Object> cache) {
Map<Integer, MvccTestSqlIndexValue> vals = new HashMap<>();
for (int i = 0; i < VALS; i++) vals.put(i, new MvccTestSqlIndexValue(i));
cache.putAll(vals);
}
};
GridInClosure3<Integer, List<TestCache>, AtomicBoolean> writer = new GridInClosure3<Integer, List<TestCache>, AtomicBoolean>() {
@Override
public void apply(Integer idx, List<TestCache> caches, AtomicBoolean stop) {
ThreadLocalRandom rnd = ThreadLocalRandom.current();
int cnt = 0;
while (!stop.get()) {
TestCache<Integer, MvccTestSqlIndexValue> cache = randomCache(caches, rnd);
try {
Integer key = rnd.nextInt(VALS);
while (true) {
try {
cache.cache.invoke(key, new CacheEntryProcessor<Integer, MvccTestSqlIndexValue, Object>() {
@Override
public Object process(MutableEntry<Integer, MvccTestSqlIndexValue> e, Object... args) {
Integer key = e.getKey();
MvccTestSqlIndexValue val = e.getValue();
int newIdxVal;
if (val.idxVal1 < INC_BY) {
assertEquals(key.intValue(), val.idxVal1);
newIdxVal = val.idxVal1 + INC_BY;
} else {
assertEquals(INC_BY + key, val.idxVal1);
newIdxVal = key;
}
e.setValue(new MvccTestSqlIndexValue(newIdxVal));
return null;
}
});
break;
} catch (CacheException e) {
MvccFeatureChecker.assertMvccWriteConflict(e);
}
}
} finally {
cache.readUnlock();
}
}
info("Writer finished, updates: " + cnt);
}
};
GridInClosure3<Integer, List<TestCache>, AtomicBoolean> reader = new GridInClosure3<Integer, List<TestCache>, AtomicBoolean>() {
@Override
public void apply(Integer idx, List<TestCache> caches, AtomicBoolean stop) {
ThreadLocalRandom rnd = ThreadLocalRandom.current();
List<SqlFieldsQuery> fieldsQrys = new ArrayList<>();
fieldsQrys.add(new SqlFieldsQuery("select _key, idxVal1 from MvccTestSqlIndexValue where idxVal1=?").setLocal(locQry));
fieldsQrys.add(new SqlFieldsQuery("select _key, idxVal1 from MvccTestSqlIndexValue where idxVal1=? or idxVal1=?").setLocal(locQry));
fieldsQrys.add(new SqlFieldsQuery("select _key, idxVal1 from MvccTestSqlIndexValue where _key=?").setLocal(locQry));
List<SqlQuery<Integer, MvccTestSqlIndexValue>> sqlQrys = new ArrayList<>();
sqlQrys.add(new SqlQuery<Integer, MvccTestSqlIndexValue>(MvccTestSqlIndexValue.class, "idxVal1=?").setLocal(locQry));
sqlQrys.add(new SqlQuery<Integer, MvccTestSqlIndexValue>(MvccTestSqlIndexValue.class, "idxVal1=? or idxVal1=?").setLocal(locQry));
sqlQrys.add(new SqlQuery<Integer, MvccTestSqlIndexValue>(MvccTestSqlIndexValue.class, "_key=?").setLocal(locQry));
while (!stop.get()) {
Integer key = rnd.nextInt(VALS);
int qryIdx = rnd.nextInt(3);
TestCache<Integer, MvccTestSqlIndexValue> cache = randomCache(caches, rnd);
List<List<?>> res;
try {
if (rnd.nextBoolean()) {
SqlFieldsQuery qry = fieldsQrys.get(qryIdx);
if (qryIdx == 1)
qry.setArgs(key, key + INC_BY);
else
qry.setArgs(key);
res = cache.cache.query(qry).getAll();
} else {
SqlQuery<Integer, MvccTestSqlIndexValue> qry = sqlQrys.get(qryIdx);
if (qryIdx == 1)
qry.setArgs(key, key + INC_BY);
else
qry.setArgs(key);
res = new ArrayList<>();
for (IgniteCache.Entry<Integer, MvccTestSqlIndexValue> e : cache.cache.query(qry).getAll()) {
List<Object> row = new ArrayList<>(2);
row.add(e.getKey());
row.add(e.getValue().idxVal1);
res.add(row);
}
}
} finally {
cache.readUnlock();
}
assertTrue(qryIdx == 0 || !res.isEmpty());
if (!res.isEmpty()) {
assertEquals(1, res.size());
List<?> resVals = res.get(0);
Integer key0 = (Integer) resVals.get(0);
Integer val0 = (Integer) resVals.get(1);
assertEquals(key, key0);
assertTrue(val0.equals(key) || val0.equals(key + INC_BY));
}
}
if (idx == 0) {
SqlFieldsQuery qry = new SqlFieldsQuery("select _key, idxVal1 from MvccTestSqlIndexValue");
TestCache<Integer, MvccTestSqlIndexValue> cache = randomCache(caches, rnd);
List<List<?>> res;
try {
res = cache.cache.query(qry).getAll();
} finally {
cache.readUnlock();
}
assertEquals(VALS, res.size());
for (List<?> vals : res) info("Value: " + vals);
}
}
};
int srvs;
int clients;
if (singleNode) {
srvs = 1;
clients = 0;
} else {
srvs = 4;
clients = 2;
}
readWriteTest(null, srvs, clients, 0, DFLT_PARTITION_COUNT, writers, readers, DFLT_TEST_TIME, new InitIndexing(Integer.class, MvccTestSqlIndexValue.class), init, writer, reader);
for (Ignite node : G.allGrids()) checkActiveQueriesCleanup(node);
}
use of org.apache.ignite.internal.util.lang.GridInClosure3 in project ignite by apache.
the class CacheMvccSqlUpdateCountersTest method testUpdateCountersMultithreaded.
/**
* @throws Exception If failed.
*/
@Test
public void testUpdateCountersMultithreaded() throws Exception {
final int writers = 4;
final int readers = 0;
int parts = 8;
int keys = 20;
final Map<Integer, AtomicLong> tracker = new ConcurrentHashMap<>();
for (int i = 0; i < keys; i++) tracker.put(i, new AtomicLong(1));
final IgniteInClosure<IgniteCache<Object, Object>> init = new IgniteInClosure<IgniteCache<Object, Object>>() {
@Override
public void apply(IgniteCache<Object, Object> cache) {
final IgniteTransactions txs = cache.unwrap(Ignite.class).transactions();
try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) {
SqlFieldsQuery qry = new SqlFieldsQuery("INSERT INTO MvccTestAccount(_key, val, updateCnt) VALUES " + "(?, 0, 1)");
for (int i = 0; i < keys; i++) {
try (FieldsQueryCursor<List<?>> cur = cache.query(qry.setArgs(i))) {
assertEquals(1L, cur.iterator().next().get(0));
}
tx.commit();
}
}
}
};
GridInClosure3<Integer, List<TestCache>, AtomicBoolean> writer = new GridInClosure3<Integer, List<TestCache>, AtomicBoolean>() {
@Override
public void apply(Integer idx, List<TestCache> caches, AtomicBoolean stop) {
ThreadLocalRandom rnd = ThreadLocalRandom.current();
Map<Integer, AtomicLong> acc = new HashMap<>();
int v = 0;
while (!stop.get()) {
int cnt = rnd.nextInt(keys / 3);
if (cnt == 0)
cnt = 2;
// Generate key set to be changed in tx.
while (acc.size() < cnt) acc.put(rnd.nextInt(cnt), new AtomicLong());
TestCache<Integer, Integer> cache = randomCache(caches, rnd);
boolean success = true;
try {
IgniteTransactions txs = cache.cache.unwrap(Ignite.class).transactions();
try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) {
Map<Integer, MvccTestAccount> allVals = readAllByMode(cache.cache, tracker.keySet(), SQL, ACCOUNT_CODEC);
boolean rmv = allVals.size() > keys * 2 / 3;
for (Map.Entry<Integer, AtomicLong> e : acc.entrySet()) {
int key = e.getKey();
AtomicLong accCntr = e.getValue();
boolean exists = allVals.containsKey(key);
int delta = 0;
boolean createdInTx = false;
if (rmv && rnd.nextBoolean()) {
if (exists)
delta = 1;
SqlFieldsQuery qry = new SqlFieldsQuery("DELETE FROM MvccTestAccount WHERE _key=" + key);
cache.cache.query(qry).getAll();
} else {
delta = 1;
if (!exists)
createdInTx = true;
SqlFieldsQuery qry = new SqlFieldsQuery("MERGE INTO MvccTestAccount " + "(_key, val, updateCnt) VALUES (" + key + ", " + rnd.nextInt(100) + ", 1)");
cache.cache.query(qry).getAll();
}
if (rnd.nextBoolean()) {
if (createdInTx)
// Do not count cases when key created and removed in the same tx.
delta = 0;
SqlFieldsQuery qry = new SqlFieldsQuery("DELETE FROM MvccTestAccount WHERE _key=" + key);
cache.cache.query(qry).getAll();
} else {
delta = 1;
SqlFieldsQuery qry = new SqlFieldsQuery("MERGE INTO MvccTestAccount " + "(_key, val, updateCnt) VALUES (" + key + ", " + rnd.nextInt(100) + ", 1)");
cache.cache.query(qry).getAll();
}
accCntr.addAndGet(delta);
}
tx.commit();
}
} catch (Exception e) {
handleTxException(e);
success = false;
int r = 0;
for (Map.Entry<Integer, AtomicLong> en : acc.entrySet()) {
if (((IgniteCacheProxy) cache.cache).context().affinity().partition(en.getKey()) == 0)
r += en.getValue().intValue();
}
} finally {
cache.readUnlock();
if (success) {
v++;
for (Map.Entry<Integer, AtomicLong> e : acc.entrySet()) {
int k = e.getKey();
long updCntr = e.getValue().get();
tracker.get(k).addAndGet(updCntr);
}
int r = 0;
for (Map.Entry<Integer, AtomicLong> en : acc.entrySet()) {
if (((IgniteCacheProxy) cache.cache).context().affinity().partition(en.getKey()) == 0)
r += en.getValue().intValue();
}
}
acc.clear();
}
}
info("Writer done, updates: " + v);
}
};
GridInClosure3<Integer, List<TestCache>, AtomicBoolean> reader = new GridInClosure3<Integer, List<TestCache>, AtomicBoolean>() {
@Override
public void apply(Integer idx, List<TestCache> caches, AtomicBoolean stop) {
// No-op.
}
};
readWriteTest(null, 4, 1, 2, parts, writers, readers, DFLT_TEST_TIME, new InitIndexing(Integer.class, MvccTestAccount.class), init, writer, reader);
Map<Integer, AtomicLong> updPerParts = new HashMap<>(parts);
Affinity aff = grid(1).cachex(DEFAULT_CACHE_NAME).affinity();
for (Map.Entry<Integer, AtomicLong> e : tracker.entrySet()) {
int k = e.getKey();
long updCntr = e.getValue().get();
int p = aff.partition(k);
AtomicLong cntr = updPerParts.get(p);
if (cntr == null) {
cntr = new AtomicLong();
updPerParts.putIfAbsent(p, cntr);
}
cntr.addAndGet(updCntr);
}
for (Map.Entry<Integer, AtomicLong> e : updPerParts.entrySet()) checkUpdateCounters(DEFAULT_CACHE_NAME, e.getKey(), e.getValue().get());
}
Aggregations