use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearTxLocal method checkMissed.
/**
* @param cacheCtx Cache context.
* @param topVer Topology version.
* @param map Return map.
* @param missedMap Missed keys.
* @param deserializeBinary Deserialize binary flag.
* @param skipVals Skip values flag.
* @param keepCacheObjects Keep cache objects flag.
* @param skipStore Skip store flag.
* @param expiryPlc Expiry policy.
* @return Loaded key-value pairs.
*/
private <K, V> IgniteInternalFuture<Map<K, V>> checkMissed(final GridCacheContext cacheCtx, final AffinityTopologyVersion topVer, final Map<K, V> map, final Map<KeyCacheObject, GridCacheVersion> missedMap, final boolean deserializeBinary, final boolean skipVals, final boolean keepCacheObjects, final boolean skipStore, final boolean recovery, final boolean needVer, final ExpiryPolicy expiryPlc) {
if (log.isDebugEnabled())
log.debug("Loading missed values for missed map: " + missedMap);
final boolean needReadVer = (serializable() && optimistic()) || needVer;
return new GridEmbeddedFuture<>(new C2<Void, Exception, Map<K, V>>() {
@Override
public Map<K, V> apply(Void v, Exception e) {
if (e != null) {
setRollbackOnly();
throw new GridClosureException(e);
}
return map;
}
}, loadMissing(cacheCtx, topVer, !skipStore, false, missedMap.keySet(), skipVals, needReadVer, !deserializeBinary, recovery, expiryPlc, new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
@Override
public void apply(KeyCacheObject key, Object val, GridCacheVersion loadVer) {
if (isRollbackOnly()) {
if (log.isDebugEnabled())
log.debug("Ignoring loaded value for read because transaction was rolled back: " + GridNearTxLocal.this);
return;
}
CacheObject cacheVal = cacheCtx.toCacheObject(val);
CacheObject visibleVal = cacheVal;
IgniteTxKey txKey = cacheCtx.txKey(key);
IgniteTxEntry txEntry = entry(txKey);
if (txEntry != null) {
if (!readCommitted())
txEntry.readValue(cacheVal);
if (!F.isEmpty(txEntry.entryProcessors()))
visibleVal = txEntry.applyEntryProcessors(visibleVal);
}
assert txEntry != null || readCommitted() || skipVals;
GridCacheEntryEx e = txEntry == null ? entryEx(cacheCtx, txKey, topVer) : txEntry.cached();
if (readCommitted() || skipVals) {
cacheCtx.evicts().touch(e, topologyVersion());
if (visibleVal != null) {
cacheCtx.addResult(map, key, visibleVal, skipVals, keepCacheObjects, deserializeBinary, false, needVer ? loadVer : null, 0, 0);
}
} else {
assert txEntry != null;
txEntry.setAndMarkValid(cacheVal);
if (needReadVer) {
assert loadVer != null;
txEntry.entryReadVersion(loadVer);
}
if (visibleVal != null) {
cacheCtx.addResult(map, key, visibleVal, skipVals, keepCacheObjects, deserializeBinary, false, needVer ? loadVer : null, 0, 0);
}
}
}
}));
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearTxLocal method putAllAsync0.
/**
* Internal method for all put and transform operations. Only one of {@code map}, {@code transformMap}
* maps must be non-null.
*
* @param cacheCtx Context.
* @param map Key-value map to store.
* @param invokeMap Invoke map.
* @param invokeArgs Optional arguments for EntryProcessor.
* @param drMap DR map.
* @param retval Key-transform value map to store.
* @return Operation future.
*/
@SuppressWarnings("unchecked")
private <K, V> IgniteInternalFuture putAllAsync0(final GridCacheContext cacheCtx, @Nullable AffinityTopologyVersion entryTopVer, @Nullable Map<? extends K, ? extends V> map, @Nullable Map<? extends K, ? extends EntryProcessor<K, V, Object>> invokeMap, @Nullable final Object[] invokeArgs, @Nullable Map<KeyCacheObject, GridCacheDrInfo> drMap, final boolean retval) {
try {
beforePut(cacheCtx, retval);
} catch (IgniteCheckedException e) {
return new GridFinishedFuture(e);
}
final CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
final Byte dataCenterId;
if (opCtx != null && opCtx.hasDataCenterId()) {
assert drMap == null : drMap;
assert map != null || invokeMap != null;
dataCenterId = opCtx.dataCenterId();
} else
dataCenterId = null;
// Cached entry may be passed only from entry wrapper.
final Map<?, ?> map0 = map;
final Map<?, EntryProcessor<K, V, Object>> invokeMap0 = (Map<K, EntryProcessor<K, V, Object>>) invokeMap;
if (log.isDebugEnabled())
log.debug("Called putAllAsync(...) [tx=" + this + ", map=" + map0 + ", retval=" + retval + "]");
assert map0 != null || invokeMap0 != null;
final GridCacheReturn ret = new GridCacheReturn(localResult(), false);
if (F.isEmpty(map0) && F.isEmpty(invokeMap0)) {
if (implicit())
try {
commit();
} catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(e);
}
return new GridFinishedFuture<>(ret.success(true));
}
try {
Set<?> keySet = map0 != null ? map0.keySet() : invokeMap0.keySet();
final Collection<KeyCacheObject> enlisted = new ArrayList<>(keySet.size());
final boolean keepBinary = opCtx != null && opCtx.isKeepBinary();
final IgniteInternalFuture<Void> loadFut = enlistWrite(cacheCtx, entryTopVer, keySet, opCtx != null ? opCtx.expiry() : null, map0, invokeMap0, invokeArgs, retval, false, CU.filterArray(null), ret, enlisted, drMap, null, opCtx != null && opCtx.skipStore(), false, keepBinary, opCtx != null && opCtx.recovery(), dataCenterId);
if (pessimistic()) {
assert loadFut == null || loadFut.isDone() : loadFut;
if (loadFut != null) {
try {
loadFut.get();
} catch (IgniteCheckedException e) {
return new GridFinishedFuture(e);
}
}
if (log.isDebugEnabled())
log.debug("Before acquiring transaction lock for put on keys: " + enlisted);
long timeout = remainingTime();
if (timeout == -1)
return new GridFinishedFuture<>(timeoutException());
IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(enlisted, timeout, this, // Needed to force load from store.
invokeMap != null, /*read*/
retval, isolation, isInvalidate(), -1L, -1L);
PLC1<GridCacheReturn> plc1 = new PLC1<GridCacheReturn>(ret) {
@Override
public GridCacheReturn postLock(GridCacheReturn ret) throws IgniteCheckedException {
if (log.isDebugEnabled())
log.debug("Acquired transaction lock for put on keys: " + enlisted);
postLockWrite(cacheCtx, enlisted, ret, /*remove*/
false, retval, /*read*/
false, -1L, CU.filterArray(null), /*computeInvoke*/
true);
return ret;
}
};
if (fut.isDone()) {
try {
return nonInterruptable(plc1.apply(fut.get(), null));
} catch (GridClosureException e) {
return new GridFinishedFuture<>(e.unwrap());
} catch (IgniteCheckedException e) {
try {
return nonInterruptable(plc1.apply(false, e));
} catch (Exception e1) {
return new GridFinishedFuture<>(e1);
}
}
} else {
return nonInterruptable(new GridEmbeddedFuture<>(fut, plc1));
}
} else
return optimisticPutFuture(cacheCtx, loadFut, ret, keepBinary);
} catch (RuntimeException e) {
onException();
throw e;
}
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearTxLocal method putAsync0.
/**
* Internal method for single update operation.
*
* @param cacheCtx Cache context.
* @param key Key.
* @param val Value.
* @param entryProcessor Entry processor.
* @param invokeArgs Optional arguments for EntryProcessor.
* @param retval Return value flag.
* @param filter Filter.
* @return Operation future.
*/
private <K, V> IgniteInternalFuture putAsync0(final GridCacheContext cacheCtx, @Nullable AffinityTopologyVersion entryTopVer, K key, @Nullable V val, @Nullable EntryProcessor<K, V, Object> entryProcessor, @Nullable final Object[] invokeArgs, final boolean retval, @Nullable final CacheEntryPredicate filter) {
assert key != null;
try {
beforePut(cacheCtx, retval);
final GridCacheReturn ret = new GridCacheReturn(localResult(), false);
CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
final Byte dataCenterId = opCtx != null ? opCtx.dataCenterId() : null;
KeyCacheObject cacheKey = cacheCtx.toCacheKeyObject(key);
boolean keepBinary = opCtx != null && opCtx.isKeepBinary();
final CacheEntryPredicate[] filters = CU.filterArray(filter);
final IgniteInternalFuture<Void> loadFut = enlistWrite(cacheCtx, entryTopVer, cacheKey, val, opCtx != null ? opCtx.expiry() : null, entryProcessor, invokeArgs, retval, /*lockOnly*/
false, filters, ret, opCtx != null && opCtx.skipStore(), /*singleRmv*/
false, keepBinary, opCtx != null && opCtx.recovery(), dataCenterId);
if (pessimistic()) {
assert loadFut == null || loadFut.isDone() : loadFut;
if (loadFut != null)
loadFut.get();
final Collection<KeyCacheObject> enlisted = Collections.singleton(cacheKey);
if (log.isDebugEnabled())
log.debug("Before acquiring transaction lock for put on key: " + enlisted);
long timeout = remainingTime();
if (timeout == -1)
return new GridFinishedFuture<>(timeoutException());
IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(enlisted, timeout, this, // Needed to force load from store.
entryProcessor != null, /*read*/
retval, isolation, isInvalidate(), -1L, -1L);
PLC1<GridCacheReturn> plc1 = new PLC1<GridCacheReturn>(ret) {
@Override
public GridCacheReturn postLock(GridCacheReturn ret) throws IgniteCheckedException {
if (log.isDebugEnabled())
log.debug("Acquired transaction lock for put on keys: " + enlisted);
postLockWrite(cacheCtx, enlisted, ret, /*remove*/
false, retval, /*read*/
false, -1L, filters, /*computeInvoke*/
true);
return ret;
}
};
if (fut.isDone()) {
try {
return nonInterruptable(plc1.apply(fut.get(), null));
} catch (GridClosureException e) {
return new GridFinishedFuture<>(e.unwrap());
} catch (IgniteCheckedException e) {
try {
return nonInterruptable(plc1.apply(false, e));
} catch (Exception e1) {
return new GridFinishedFuture<>(e1);
}
}
} else {
return nonInterruptable(new GridEmbeddedFuture<>(fut, plc1));
}
} else
return optimisticPutFuture(cacheCtx, loadFut, ret, keepBinary);
} catch (IgniteCheckedException e) {
return new GridFinishedFuture(e);
} catch (RuntimeException e) {
onException();
throw e;
}
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearTxLocal method loadMissing.
/**
* @param cacheCtx Cache context.
* @param readThrough Read through flag.
* @param async if {@code True}, then loading will happen in a separate thread.
* @param keys Keys.
* @param skipVals Skip values flag.
* @param needVer If {@code true} version is required for loaded values.
* @param c Closure to be applied for loaded values.
* @param expiryPlc Expiry policy.
* @return Future with {@code True} value if loading took place.
*/
public IgniteInternalFuture<Void> loadMissing(final GridCacheContext cacheCtx, AffinityTopologyVersion topVer, boolean readThrough, boolean async, final Collection<KeyCacheObject> keys, final boolean skipVals, final boolean needVer, boolean keepBinary, boolean recovery, final ExpiryPolicy expiryPlc, final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c) {
IgniteCacheExpiryPolicy expiryPlc0 = optimistic() ? accessPolicy(cacheCtx, keys) : cacheCtx.cache().expiryPolicy(expiryPlc);
if (cacheCtx.isNear()) {
return cacheCtx.nearTx().txLoadAsync(this, topVer, keys, readThrough, /*deserializeBinary*/
false, recovery, expiryPlc0, skipVals, needVer).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
@Override
public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
try {
Map<Object, Object> map = f.get();
processLoaded(map, keys, needVer, c);
return null;
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
}
});
} else if (cacheCtx.isColocated()) {
if (keys.size() == 1) {
final KeyCacheObject key = F.first(keys);
return cacheCtx.colocated().loadAsync(key, readThrough, /*force primary*/
needVer || !cacheCtx.config().isReadFromBackup(), topVer, CU.subjectId(this, cctx), resolveTaskName(), /*deserializeBinary*/
false, expiryPlc0, skipVals, /*can remap*/
true, needVer, /*keepCacheObject*/
true, recovery).chain(new C1<IgniteInternalFuture<Object>, Void>() {
@Override
public Void apply(IgniteInternalFuture<Object> f) {
try {
Object val = f.get();
processLoaded(key, val, needVer, skipVals, c);
return null;
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
}
});
} else {
return cacheCtx.colocated().loadAsync(keys, readThrough, /*force primary*/
needVer || !cacheCtx.config().isReadFromBackup(), topVer, CU.subjectId(this, cctx), resolveTaskName(), /*deserializeBinary*/
false, recovery, expiryPlc0, skipVals, /*can remap*/
true, needVer, /*keepCacheObject*/
true).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
@Override
public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
try {
Map<Object, Object> map = f.get();
processLoaded(map, keys, needVer, c);
return null;
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
}
});
}
} else {
assert cacheCtx.isLocal();
return localCacheLoadMissing(cacheCtx, topVer, readThrough, async, keys, skipVals, needVer, keepBinary, recovery, expiryPlc, c);
}
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearTxLocal method enlistRead.
/**
* @param cacheCtx Cache context.
* @param keys Key to enlist.
* @param expiryPlc Explicitly specified expiry policy for entry.
* @param map Return map.
* @param missed Map of missed keys.
* @param keysCnt Keys count (to avoid call to {@code Collection.size()}).
* @param deserializeBinary Deserialize binary flag.
* @param skipVals Skip values flag.
* @param keepCacheObjects Keep cache objects flag.
* @param skipStore Skip store flag.
* @throws IgniteCheckedException If failed.
* @return Enlisted keys.
*/
@SuppressWarnings({ "RedundantTypeArguments" })
private <K, V> Collection<KeyCacheObject> enlistRead(final GridCacheContext cacheCtx, @Nullable AffinityTopologyVersion entryTopVer, Collection<KeyCacheObject> keys, @Nullable ExpiryPolicy expiryPlc, Map<K, V> map, Map<KeyCacheObject, GridCacheVersion> missed, int keysCnt, boolean deserializeBinary, boolean skipVals, boolean keepCacheObjects, boolean skipStore, boolean recovery, final boolean needVer) throws IgniteCheckedException {
assert !F.isEmpty(keys);
assert keysCnt == keys.size();
cacheCtx.checkSecurity(SecurityPermission.CACHE_READ);
boolean single = keysCnt == 1;
Collection<KeyCacheObject> lockKeys = null;
AffinityTopologyVersion topVer = entryTopVer != null ? entryTopVer : topologyVersion();
boolean needReadVer = (serializable() && optimistic()) || needVer;
// outside of this loop.
for (KeyCacheObject key : keys) {
if ((pessimistic() || needReadVer) && !readCommitted() && !skipVals)
addActiveCache(cacheCtx, recovery);
IgniteTxKey txKey = cacheCtx.txKey(key);
// Check write map (always check writes first).
IgniteTxEntry txEntry = entry(txKey);
// Either non-read-committed or there was a previous write.
if (txEntry != null) {
CacheObject val = txEntry.value();
if (txEntry.hasValue()) {
if (!F.isEmpty(txEntry.entryProcessors()))
val = txEntry.applyEntryProcessors(val);
if (val != null) {
GridCacheVersion ver = null;
if (needVer) {
if (txEntry.op() != READ)
ver = IgniteTxEntry.GET_ENTRY_INVALID_VER_UPDATED;
else {
ver = txEntry.entryReadVersion();
if (ver == null && pessimistic()) {
while (true) {
try {
GridCacheEntryEx cached = txEntry.cached();
ver = cached.isNear() ? ((GridNearCacheEntry) cached).dhtVersion() : cached.version();
break;
} catch (GridCacheEntryRemovedException ignored) {
txEntry.cached(entryEx(cacheCtx, txEntry.txKey(), topVer));
}
}
}
if (ver == null) {
assert optimistic() && repeatableRead() : this;
ver = IgniteTxEntry.GET_ENTRY_INVALID_VER_AFTER_GET;
}
}
assert ver != null;
}
cacheCtx.addResult(map, key, val, skipVals, keepCacheObjects, deserializeBinary, false, ver, 0, 0);
}
} else {
assert txEntry.op() == TRANSFORM;
while (true) {
try {
GridCacheVersion readVer = null;
EntryGetResult getRes = null;
Object transformClo = (txEntry.op() == TRANSFORM && cctx.gridEvents().isRecordable(EVT_CACHE_OBJECT_READ)) ? F.first(txEntry.entryProcessors()) : null;
if (needVer) {
getRes = txEntry.cached().innerGetVersioned(null, this, /*update-metrics*/
true, /*event*/
!skipVals, CU.subjectId(this, cctx), transformClo, resolveTaskName(), null, txEntry.keepBinary(), null);
if (getRes != null) {
val = getRes.value();
readVer = getRes.version();
}
} else {
val = txEntry.cached().innerGet(null, this, /*read-through*/
false, /*metrics*/
true, /*event*/
!skipVals, CU.subjectId(this, cctx), transformClo, resolveTaskName(), null, txEntry.keepBinary());
}
if (val != null) {
if (!readCommitted() && !skipVals)
txEntry.readValue(val);
if (!F.isEmpty(txEntry.entryProcessors()))
val = txEntry.applyEntryProcessors(val);
cacheCtx.addResult(map, key, val, skipVals, keepCacheObjects, deserializeBinary, false, getRes, readVer, 0, 0, needVer);
} else
missed.put(key, txEntry.cached().version());
break;
} catch (GridCacheEntryRemovedException ignored) {
txEntry.cached(entryEx(cacheCtx, txEntry.txKey(), topVer));
}
}
}
} else // First time access within transaction.
{
if (lockKeys == null && !skipVals)
lockKeys = single ? Collections.singleton(key) : new ArrayList<KeyCacheObject>(keysCnt);
if (!single && !skipVals)
lockKeys.add(key);
while (true) {
GridCacheEntryEx entry = entryEx(cacheCtx, txKey, topVer);
try {
GridCacheVersion ver = entry.version();
CacheObject val = null;
GridCacheVersion readVer = null;
EntryGetResult getRes = null;
if (!pessimistic() || readCommitted() && !skipVals) {
IgniteCacheExpiryPolicy accessPlc = optimistic() ? accessPolicy(cacheCtx, txKey, expiryPlc) : null;
if (needReadVer) {
getRes = primaryLocal(entry) ? entry.innerGetVersioned(null, this, /*metrics*/
true, /*event*/
true, CU.subjectId(this, cctx), null, resolveTaskName(), accessPlc, !deserializeBinary, null) : null;
if (getRes != null) {
val = getRes.value();
readVer = getRes.version();
}
} else {
val = entry.innerGet(null, this, /*read-through*/
false, /*metrics*/
true, /*event*/
!skipVals, CU.subjectId(this, cctx), null, resolveTaskName(), accessPlc, !deserializeBinary);
}
if (val != null) {
cacheCtx.addResult(map, key, val, skipVals, keepCacheObjects, deserializeBinary, false, getRes, readVer, 0, 0, needVer);
} else
missed.put(key, ver);
} else
// We must wait for the lock in pessimistic mode.
missed.put(key, ver);
if (!readCommitted() && !skipVals) {
txEntry = addEntry(READ, val, null, null, entry, expiryPlc, null, true, -1L, -1L, null, skipStore, !deserializeBinary);
// for non-pessimistic if value is not null.
if (val != null && !pessimistic()) {
txEntry.markValid();
if (needReadVer) {
assert readVer != null;
txEntry.entryReadVersion(readVer);
}
}
}
// While.
break;
} catch (GridCacheEntryRemovedException ignored) {
if (log.isDebugEnabled())
log.debug("Got removed entry in transaction getAllAsync(..) (will retry): " + key);
} finally {
if (entry != null && readCommitted()) {
if (cacheCtx.isNear()) {
if (cacheCtx.affinity().partitionBelongs(cacheCtx.localNode(), entry.partition(), topVer)) {
if (entry.markObsolete(xidVer))
cacheCtx.cache().removeEntry(entry);
}
} else
entry.context().evicts().touch(entry, topVer);
}
}
}
}
}
return lockKeys != null ? lockKeys : Collections.<KeyCacheObject>emptyList();
}
Aggregations