use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.
the class GridNearTxLocal method loadMissing.
/**
* @param cacheCtx Cache context.
* @param keys Keys to load.
* @param filter Filter.
* @param ret Return value.
* @param needReadVer Read version flag.
* @param singleRmv {@code True} for single remove operation.
* @param hasFilters {@code True} if filters not empty.
* @param readThrough Read through flag.
* @param retval Return value flag.
* @param expiryPlc Expiry policy.
* @return Load future.
*/
private IgniteInternalFuture<Void> loadMissing(final GridCacheContext cacheCtx, final AffinityTopologyVersion topVer, final Set<KeyCacheObject> keys, final CacheEntryPredicate[] filter, final GridCacheReturn ret, final boolean needReadVer, final boolean singleRmv, final boolean hasFilters, final boolean readThrough, final boolean retval, final boolean keepBinary, final boolean recovery, final ExpiryPolicy expiryPlc) {
GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c = new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
@Override
public void apply(KeyCacheObject key, @Nullable Object val, @Nullable GridCacheVersion loadVer) {
if (log.isDebugEnabled())
log.debug("Loaded value from remote node [key=" + key + ", val=" + val + ']');
IgniteTxEntry e = entry(new IgniteTxKey(key, cacheCtx.cacheId()));
assert e != null;
if (needReadVer) {
assert loadVer != null;
e.entryReadVersion(singleRmv && val != null ? SER_READ_NOT_EMPTY_VER : loadVer);
}
if (singleRmv) {
assert !hasFilters && !retval;
assert val == null || Boolean.TRUE.equals(val) : val;
ret.set(cacheCtx, null, val != null, keepBinary);
} else {
CacheObject cacheVal = cacheCtx.toCacheObject(val);
if (e.op() == TRANSFORM) {
GridCacheVersion ver;
e.readValue(cacheVal);
try {
ver = e.cached().version();
} catch (GridCacheEntryRemovedException ex) {
assert optimistic() : e;
if (log.isDebugEnabled())
log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
ver = null;
}
addInvokeResult(e, cacheVal, ret, ver);
} else {
boolean success;
if (hasFilters) {
success = isAll(e.context(), key, cacheVal, filter);
if (!success) {
e.value(cacheVal, false, false);
e.op(READ);
}
} else
success = true;
ret.set(cacheCtx, cacheVal, success, keepBinary);
}
}
}
};
return loadMissing(cacheCtx, topVer, readThrough, /*async*/
true, keys, /*skipVals*/
singleRmv, needReadVer, keepBinary, recovery, expiryPlc, c);
}
use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.
the class GridNearTxLocal method getAllAsync.
/**
* @param cacheCtx Cache context.
* @param keys Keys to get.
* @param deserializeBinary Deserialize binary flag.
* @param skipVals Skip values flag.
* @param keepCacheObjects Keep cache objects
* @param skipStore Skip store flag.
* @return Future for this get.
*/
@SuppressWarnings("unchecked")
public <K, V> IgniteInternalFuture<Map<K, V>> getAllAsync(final GridCacheContext cacheCtx, @Nullable final AffinityTopologyVersion entryTopVer, Collection<KeyCacheObject> keys, final boolean deserializeBinary, final boolean skipVals, final boolean keepCacheObjects, final boolean skipStore, final boolean recovery, final boolean needVer) {
if (F.isEmpty(keys))
return new GridFinishedFuture<>(Collections.<K, V>emptyMap());
init();
int keysCnt = keys.size();
boolean single = keysCnt == 1;
try {
checkValid();
final Map<K, V> retMap = new GridLeanMap<>(keysCnt);
final Map<KeyCacheObject, GridCacheVersion> missed = new GridLeanMap<>(pessimistic() ? keysCnt : 0);
CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
ExpiryPolicy expiryPlc = opCtx != null ? opCtx.expiry() : null;
final Collection<KeyCacheObject> lockKeys = enlistRead(cacheCtx, entryTopVer, keys, expiryPlc, retMap, missed, keysCnt, deserializeBinary, skipVals, keepCacheObjects, skipStore, recovery, needVer);
if (single && missed.isEmpty())
return new GridFinishedFuture<>(retMap);
// Handle locks.
if (pessimistic() && !readCommitted() && !skipVals) {
if (expiryPlc == null)
expiryPlc = cacheCtx.expiry();
long accessTtl = expiryPlc != null ? CU.toTtl(expiryPlc.getExpiryForAccess()) : CU.TTL_NOT_CHANGED;
long createTtl = expiryPlc != null ? CU.toTtl(expiryPlc.getExpiryForCreation()) : CU.TTL_NOT_CHANGED;
long timeout = remainingTime();
if (timeout == -1)
return new GridFinishedFuture<>(timeoutException());
IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(lockKeys, timeout, this, true, true, isolation, isInvalidate(), createTtl, accessTtl);
final ExpiryPolicy expiryPlc0 = expiryPlc;
PLC2<Map<K, V>> plc2 = new PLC2<Map<K, V>>() {
@Override
public IgniteInternalFuture<Map<K, V>> postLock() throws IgniteCheckedException {
if (log.isDebugEnabled())
log.debug("Acquired transaction lock for read on keys: " + lockKeys);
// Load keys only after the locks have been acquired.
for (KeyCacheObject cacheKey : lockKeys) {
K keyVal = (K) (keepCacheObjects ? cacheKey : cacheCtx.cacheObjectContext().unwrapBinaryIfNeeded(cacheKey, !deserializeBinary, true));
if (retMap.containsKey(keyVal))
// We already have a return value.
continue;
IgniteTxKey txKey = cacheCtx.txKey(cacheKey);
IgniteTxEntry txEntry = entry(txKey);
assert txEntry != null;
// Check if there is cached value.
while (true) {
GridCacheEntryEx cached = txEntry.cached();
CacheObject val = null;
GridCacheVersion readVer = null;
EntryGetResult getRes = null;
try {
Object transformClo = (!F.isEmpty(txEntry.entryProcessors()) && cctx.gridEvents().isRecordable(EVT_CACHE_OBJECT_READ)) ? F.first(txEntry.entryProcessors()) : null;
if (needVer) {
getRes = cached.innerGetVersioned(null, GridNearTxLocal.this, /*update-metrics*/
true, /*event*/
!skipVals, CU.subjectId(GridNearTxLocal.this, cctx), transformClo, resolveTaskName(), null, txEntry.keepBinary(), null);
if (getRes != null) {
val = getRes.value();
readVer = getRes.version();
}
} else {
val = cached.innerGet(null, GridNearTxLocal.this, /*read through*/
false, /*metrics*/
true, /*events*/
!skipVals, CU.subjectId(GridNearTxLocal.this, cctx), transformClo, resolveTaskName(), null, txEntry.keepBinary());
}
// If value is in cache and passed the filter.
if (val != null) {
missed.remove(cacheKey);
txEntry.setAndMarkValid(val);
if (!F.isEmpty(txEntry.entryProcessors()))
val = txEntry.applyEntryProcessors(val);
cacheCtx.addResult(retMap, cacheKey, val, skipVals, keepCacheObjects, deserializeBinary, false, getRes, readVer, 0, 0, needVer);
if (readVer != null)
txEntry.entryReadVersion(readVer);
}
// While.
break;
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed exception in get postLock (will retry): " + cached);
txEntry.cached(entryEx(cacheCtx, txKey, topologyVersion()));
}
}
}
if (!missed.isEmpty() && cacheCtx.isLocal()) {
AffinityTopologyVersion topVer = topologyVersionSnapshot();
if (topVer == null)
topVer = entryTopVer;
return checkMissed(cacheCtx, topVer != null ? topVer : topologyVersion(), retMap, missed, deserializeBinary, skipVals, keepCacheObjects, skipStore, recovery, needVer, expiryPlc0);
}
return new GridFinishedFuture<>(Collections.<K, V>emptyMap());
}
};
FinishClosure<Map<K, V>> finClos = new FinishClosure<Map<K, V>>() {
@Override
Map<K, V> finish(Map<K, V> loaded) {
retMap.putAll(loaded);
return retMap;
}
};
if (fut.isDone()) {
try {
IgniteInternalFuture<Map<K, V>> fut1 = plc2.apply(fut.get(), null);
return fut1.isDone() ? new GridFinishedFuture<>(finClos.apply(fut1.get(), null)) : new GridEmbeddedFuture<>(finClos, fut1);
} catch (GridClosureException e) {
return new GridFinishedFuture<>(e.unwrap());
} catch (IgniteCheckedException e) {
try {
return plc2.apply(false, e);
} catch (Exception e1) {
return new GridFinishedFuture<>(e1);
}
}
} else {
return new GridEmbeddedFuture<>(fut, plc2, finClos);
}
} else {
assert optimistic() || readCommitted() || skipVals;
if (!missed.isEmpty()) {
if (!readCommitted())
for (Iterator<KeyCacheObject> it = missed.keySet().iterator(); it.hasNext(); ) {
KeyCacheObject cacheKey = it.next();
K keyVal = (K) (keepCacheObjects ? cacheKey : cacheCtx.cacheObjectContext().unwrapBinaryIfNeeded(cacheKey, !deserializeBinary, false));
if (retMap.containsKey(keyVal))
it.remove();
}
if (missed.isEmpty())
return new GridFinishedFuture<>(retMap);
AffinityTopologyVersion topVer = topologyVersionSnapshot();
if (topVer == null)
topVer = entryTopVer;
return checkMissed(cacheCtx, topVer != null ? topVer : topologyVersion(), retMap, missed, deserializeBinary, skipVals, keepCacheObjects, skipStore, recovery, needVer, expiryPlc);
}
return new GridFinishedFuture<>(retMap);
}
} catch (IgniteCheckedException e) {
setRollbackOnly();
return new GridFinishedFuture<>(e);
}
}
use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.
the class GridNearTxLocal method updateExplicitVersion.
/**
* {@inheritDoc}
*/
@Override
protected void updateExplicitVersion(IgniteTxEntry txEntry, GridCacheEntryEx entry) throws GridCacheEntryRemovedException {
if (entry.detached()) {
GridCacheMvccCandidate cand = cctx.mvcc().explicitLock(threadId(), entry.txKey());
if (cand != null && !xidVersion().equals(cand.version())) {
GridCacheVersion candVer = cand.version();
txEntry.explicitVersion(candVer);
if (candVer.compareTo(minVer) < 0)
minVer = candVer;
}
} else
super.updateExplicitVersion(txEntry, entry);
}
use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.
the class IgniteCacheClientNodeChangingTopologyTest method checkData.
/**
* @param map Expected data.
* @param keys Expected keys (if expected data is not specified).
* @param clientCache Client cache.
* @param expNodes Expected nodes number.
* @throws Exception If failed.
*/
private void checkData(final Map<Integer, Integer> map, final Set<Integer> keys, IgniteCache<?, ?> clientCache, final int expNodes) throws Exception {
final List<Ignite> nodes = G.allGrids();
final Affinity<Integer> aff = nodes.get(0).affinity(DEFAULT_CACHE_NAME);
assertEquals(expNodes, nodes.size());
boolean hasNearCache = clientCache.getConfiguration(CacheConfiguration.class).getNearConfiguration() != null;
final Ignite nearCacheNode = hasNearCache ? clientCache.unwrap(Ignite.class) : null;
boolean wait = GridTestUtils.waitForCondition(new PA() {
@Override
public boolean apply() {
try {
Set<Integer> keys0 = map != null ? map.keySet() : keys;
assertNotNull(keys0);
for (Integer key : keys0) {
GridCacheVersion ver = null;
Object val = null;
for (Ignite node : nodes) {
IgniteCache<Integer, Integer> cache = node.cache(DEFAULT_CACHE_NAME);
boolean affNode = aff.isPrimaryOrBackup(node.cluster().localNode(), key);
Object val0 = cache.localPeek(key);
if (affNode || node == nearCacheNode) {
if (map != null)
assertEquals("Unexpected value for " + node.name(), map.get(key), val0);
else
assertNotNull("Unexpected value for " + node.name(), val0);
GridCacheAdapter cache0 = ((IgniteKernal) node).internalCache(DEFAULT_CACHE_NAME);
if (affNode && cache0.isNear())
cache0 = ((GridNearCacheAdapter) cache0).dht();
GridCacheEntryEx entry = cache0.entryEx(key);
try {
entry.unswap(true);
assertNotNull("No entry [node=" + node.name() + ", key=" + key + ']', entry);
GridCacheVersion ver0 = entry instanceof GridNearCacheEntry ? ((GridNearCacheEntry) entry).dhtVersion() : entry.version();
assertNotNull("Null version [node=" + node.name() + ", key=" + key + ']', ver0);
if (ver == null) {
ver = ver0;
val = val0;
} else {
assertEquals("Version check failed [node=" + node.name() + ", key=" + key + ", affNode=" + affNode + ", primary=" + aff.isPrimary(node.cluster().localNode(), key) + ']', ver0, ver);
assertEquals("Value check failed [node=" + node.name() + ", key=" + key + ", affNode=" + affNode + ", primary=" + aff.isPrimary(node.cluster().localNode(), key) + ']', val0, val);
}
} finally {
cache0.context().evicts().touch(entry, cache0.context().affinity().affinityTopologyVersion());
}
} else
assertNull("Unexpected non-null value for " + node.name(), val0);
}
}
} catch (AssertionError e) {
log.info("Check failed, will retry: " + e);
return false;
} catch (Exception e) {
fail("Unexpected exception: " + e);
}
return true;
}
}, 10_000);
assertTrue("Data check failed.", wait);
}
use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.
the class IgniteTxManager method lockMultiple.
/**
* @param tx Transaction.
* @param entries Entries to lock.
* @return {@code True} if all keys were locked.
* @throws IgniteCheckedException If lock has been cancelled.
*/
private boolean lockMultiple(IgniteInternalTx tx, Iterable<IgniteTxEntry> entries) throws IgniteCheckedException {
assert tx.optimistic() || !tx.local();
long remainingTime = tx.remainingTime();
// For serializable transactions, failure to acquire lock means
// that there is a serializable conflict. For all other isolation levels,
// we wait for the lock.
long timeout = remainingTime < 0 ? 0 : remainingTime;
GridCacheVersion serOrder = (tx.serializable() && tx.optimistic()) ? tx.nearXidVersion() : null;
for (IgniteTxEntry txEntry1 : entries) {
// Check if this entry was prepared before.
if (!txEntry1.markPrepared() || txEntry1.explicitVersion() != null)
continue;
GridCacheContext cacheCtx = txEntry1.context();
while (true) {
cctx.database().checkpointReadLock();
try {
GridCacheEntryEx entry1 = txEntry1.cached();
assert entry1 != null : txEntry1;
assert !entry1.detached() : "Expected non-detached entry for near transaction " + "[locNodeId=" + cctx.localNodeId() + ", entry=" + entry1 + ']';
GridCacheVersion serReadVer = txEntry1.entryReadVersion();
assert serReadVer == null || (tx.optimistic() && tx.serializable()) : txEntry1;
boolean read = serOrder != null && txEntry1.op() == READ;
entry1.unswap();
if (!entry1.tmLock(tx, timeout, serOrder, serReadVer, read)) {
// Unlock locks locked so far.
for (IgniteTxEntry txEntry2 : entries) {
if (txEntry2 == txEntry1)
break;
txUnlock(tx, txEntry2);
}
return false;
}
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Got removed entry in TM lockMultiple(..) method (will retry): " + txEntry1);
try {
// Renew cache entry.
txEntry1.cached(cacheCtx.cache().entryEx(txEntry1.key(), tx.topologyVersion()));
} catch (GridDhtInvalidPartitionException e) {
assert tx.dht() : "Received invalid partition for non DHT transaction [tx=" + tx + ", invalidPart=" + e.partition() + ']';
// If partition is invalid, we ignore this entry.
tx.addInvalidPartition(cacheCtx, e.partition());
break;
}
} catch (GridDistributedLockCancelledException ignore) {
tx.setRollbackOnly();
throw new IgniteCheckedException("Entry lock has been cancelled for transaction: " + tx);
} finally {
cctx.database().checkpointReadUnlock();
}
}
}
return true;
}
Aggregations