use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearTxLocal method mvccRemoveAllAsync0.
/**
* Internal method for remove operations in Mvcc mode.
*
* @param cacheCtx Cache context.
* @param keys Keys to remove.
* @param retval Flag indicating whether a value should be returned.
* @param filter Filter.
* @return Future for asynchronous remove.
*/
@SuppressWarnings("unchecked")
private <K, V> IgniteInternalFuture<GridCacheReturn> mvccRemoveAllAsync0(final GridCacheContext cacheCtx, @Nullable final Collection<? extends K> keys, final boolean retval, @Nullable final CacheEntryPredicate filter) {
try {
MvccUtils.requestSnapshot(this);
beforeRemove(cacheCtx, retval, true);
} catch (IgniteCheckedException e) {
return new GridFinishedFuture(e);
}
if (F.isEmpty(keys)) {
if (implicit()) {
try {
commit();
} catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(e);
}
}
return new GridFinishedFuture<>(new GridCacheReturn(localResult(), true));
}
init();
Set<KeyCacheObject> enlisted = new HashSet<>(keys.size());
try {
for (Object key : keys) {
if (isRollbackOnly())
return new GridFinishedFuture<>(timedOut() ? timeoutException() : rollbackException());
if (key == null) {
rollback();
throw new NullPointerException("Null key.");
}
KeyCacheObject cacheKey = cacheCtx.toCacheKeyObject(key);
enlisted.add(cacheKey);
}
} catch (IgniteCheckedException e) {
return new GridFinishedFuture(e);
}
return updateAsync(cacheCtx, new UpdateSourceIterator<KeyCacheObject>() {
private final Iterator<KeyCacheObject> it = enlisted.iterator();
@Override
public EnlistOperation operation() {
return EnlistOperation.DELETE;
}
@Override
public boolean hasNextX() throws IgniteCheckedException {
return it.hasNext();
}
@Override
public KeyCacheObject nextX() throws IgniteCheckedException {
return it.next();
}
}, retval, filter, remainingTime(), true);
}
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.
* @param recovery Recovery flag..
* @return Enlisted keys.
* @throws IgniteCheckedException If failed.
*/
@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, ReadRepairStrategy readRepairStrategy, final boolean needVer) throws IgniteCheckedException {
assert !F.isEmpty(keys);
assert keysCnt == keys.size();
try (TraceSurroundings ignored2 = MTC.support(context().kernalContext().tracing().create(TX_NEAR_ENLIST_READ, MTC.span()))) {
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 (isRollbackOnly())
throw timedOut() ? timeoutException() : rollbackException();
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, U.deploymentClassLoader(cctx.kernalContext(), deploymentLdrId));
}
} 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, 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, 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, U.deploymentClassLoader(cctx.kernalContext(), deploymentLdrId));
} 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)) && readRepairStrategy == null) {
IgniteCacheExpiryPolicy accessPlc = optimistic() ? accessPolicy(cacheCtx, txKey, expiryPlc) : null;
if (needReadVer) {
getRes = primaryLocal(entry) ? entry.innerGetVersioned(null, this, /*metrics*/
true, /*event*/
true, 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, null, resolveTaskName(), accessPlc, !deserializeBinary);
}
if (val != null) {
cacheCtx.addResult(map, key, val, skipVals, keepCacheObjects, deserializeBinary, false, getRes, readVer, 0, 0, needVer, U.deploymentClassLoader(cctx.kernalContext(), deploymentLdrId));
} 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, CU.isNearEnabled(cacheCtx));
// 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.touch();
}
}
}
}
}
return lockKeys != null ? lockKeys : Collections.<KeyCacheObject>emptyList();
}
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearTxEnlistRequest method prepareMarshal.
/**
* {@inheritDoc}
*/
@Override
public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
super.prepareMarshal(ctx);
GridCacheContext cctx = ctx.cacheContext(cacheId);
CacheObjectContext objCtx = cctx.cacheObjectContext();
if (rows != null && keys == null) {
if (!addDepInfo && ctx.deploymentEnabled())
addDepInfo = true;
keys = new KeyCacheObject[rows.size()];
int i = 0;
boolean keysOnly = op.isDeleteOrLock();
values = keysOnly ? null : new Message[keys.length];
for (Object row : rows) {
Object key, val = null;
if (keysOnly)
key = row;
else {
key = ((IgniteBiTuple) row).getKey();
val = ((IgniteBiTuple) row).getValue();
}
assert key != null && (keysOnly || val != null) : "key=" + key + ", val=" + val;
KeyCacheObject key0 = cctx.toCacheKeyObject(key);
assert key0 != null;
key0.prepareMarshal(objCtx);
keys[i] = key0;
if (!keysOnly) {
if (op.isInvoke()) {
GridInvokeValue val0 = (GridInvokeValue) val;
prepareInvokeValue(cctx, val0);
values[i] = val0;
} else {
if (addDepInfo)
prepareObject(val, cctx);
CacheObject val0 = cctx.toCacheObject(val);
assert val0 != null;
val0.prepareMarshal(objCtx);
values[i] = val0;
}
}
i++;
}
}
if (filter != null)
filter.prepareMarshal(cctx);
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearTxLocal method enlistWrite.
/**
* Internal routine for <tt>putAll(..)</tt>
*
* @param cacheCtx Cache context.
* @param keys Keys to enlist.
* @param expiryPlc Explicitly specified expiry policy for entry.
* @param lookup Value lookup map ({@code null} for remove).
* @param invokeMap Map with entry processors for invoke operation.
* @param invokeArgs Optional arguments for EntryProcessor.
* @param retval Flag indicating whether a value should be returned.
* @param lockOnly If {@code true}, then entry will be enlisted as noop.
* @param filter User filters.
* @param ret Return value.
* @param enlisted Collection of keys enlisted into this transaction.
* @param drPutMap DR put map (optional).
* @param drRmvMap DR remove map (optional).
* @param skipStore Skip store flag.
* @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
* @param keepBinary Keep binary flag.
* @param recovery Recovery flag.
* @param dataCenterId Optional data center ID.
* @return Future for enlisting writes.
*/
private <K, V> IgniteInternalFuture<Void> enlistWrite(final GridCacheContext cacheCtx, @Nullable AffinityTopologyVersion entryTopVer, Collection<?> keys, @Nullable ExpiryPolicy expiryPlc, @Nullable Map<?, ?> lookup, @Nullable Map<?, EntryProcessor<K, V, Object>> invokeMap, @Nullable Object[] invokeArgs, final boolean retval, boolean lockOnly, final CacheEntryPredicate[] filter, final GridCacheReturn ret, Collection<KeyCacheObject> enlisted, @Nullable Map<KeyCacheObject, GridCacheDrInfo> drPutMap, @Nullable Map<KeyCacheObject, GridCacheVersion> drRmvMap, boolean skipStore, final boolean singleRmv, final boolean keepBinary, final boolean recovery, Byte dataCenterId) {
assert retval || invokeMap == null;
try (TraceSurroundings ignored2 = MTC.support(context().kernalContext().tracing().create(TX_NEAR_ENLIST_WRITE, MTC.span()))) {
GridFutureAdapter<Void> enlistFut = new GridFutureAdapter<>();
if (!updateLockFuture(null, enlistFut))
return finishFuture(enlistFut, timedOut() ? timeoutException() : rollbackException(), false);
try {
addActiveCache(cacheCtx, recovery);
} catch (IgniteCheckedException e) {
return finishFuture(enlistFut, e, false);
}
boolean rmv = lookup == null && invokeMap == null;
final boolean hasFilters = !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter);
final boolean needVal = singleRmv || retval || hasFilters;
final boolean needReadVer = needVal && (serializable() && optimistic());
try {
// Set transform flag for transaction.
if (invokeMap != null)
transform = true;
Set<KeyCacheObject> missedForLoad = null;
for (Object key : keys) {
if (isRollbackOnly())
return finishFuture(enlistFut, timedOut() ? timeoutException() : rollbackException(), false);
if (key == null) {
rollback();
throw new NullPointerException("Null key.");
}
Object val = rmv || lookup == null ? null : lookup.get(key);
EntryProcessor entryProcessor = invokeMap == null ? null : invokeMap.get(key);
GridCacheVersion drVer;
long drTtl;
long drExpireTime;
if (drPutMap != null) {
GridCacheDrInfo info = drPutMap.get(key);
assert info != null;
drVer = info.version();
drTtl = info.ttl();
drExpireTime = info.expireTime();
} else if (drRmvMap != null) {
assert drRmvMap.get(key) != null;
drVer = drRmvMap.get(key);
drTtl = -1L;
drExpireTime = -1L;
} else if (dataCenterId != null) {
drVer = cacheCtx.cache().nextVersion(dataCenterId);
drTtl = -1L;
drExpireTime = -1L;
} else {
drVer = null;
drTtl = -1L;
drExpireTime = -1L;
}
if (!rmv && val == null && entryProcessor == null) {
setRollbackOnly();
throw new NullPointerException("Null value.");
}
KeyCacheObject cacheKey = cacheCtx.toCacheKeyObject(key);
boolean loadMissed = enlistWriteEntry(cacheCtx, entryTopVer, cacheKey, val, entryProcessor, invokeArgs, expiryPlc, retval, lockOnly, filter, drVer, drTtl, drExpireTime, ret, enlisted, skipStore, singleRmv, hasFilters, needVal, needReadVer, keepBinary, recovery);
if (loadMissed) {
if (missedForLoad == null)
missedForLoad = new HashSet<>();
missedForLoad.add(cacheKey);
}
}
if (missedForLoad != null) {
AffinityTopologyVersion topVer = topologyVersionSnapshot();
if (topVer == null)
topVer = entryTopVer;
IgniteInternalFuture<Void> loadFut = loadMissing(cacheCtx, topVer != null ? topVer : topologyVersion(), missedForLoad, filter, ret, needReadVer, singleRmv, hasFilters, /*read through*/
(invokeMap != null || cacheCtx.config().isLoadPreviousValue()) && !skipStore, retval, keepBinary, recovery, expiryPlc);
loadFut.listen(new IgniteInClosure<IgniteInternalFuture<Void>>() {
@Override
public void apply(IgniteInternalFuture<Void> fut) {
try {
fut.get();
finishFuture(enlistFut, null, true);
} catch (IgniteCheckedException e) {
finishFuture(enlistFut, e, true);
}
}
});
return enlistFut;
}
return finishFuture(enlistFut, null, true);
} catch (IgniteCheckedException e) {
return finishFuture(enlistFut, e, true);
}
}
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearTxLocal method removeAllAsync0.
/**
* @param cacheCtx Cache context.
* @param keys Keys to remove.
* @param drMap DR map.
* @param retval Flag indicating whether a value should be returned.
* @param filter Filter.
* @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
* @return Future for asynchronous remove.
*/
@SuppressWarnings("unchecked")
private <K, V> IgniteInternalFuture<GridCacheReturn> removeAllAsync0(final GridCacheContext cacheCtx, @Nullable AffinityTopologyVersion entryTopVer, @Nullable final Collection<? extends K> keys, @Nullable Map<KeyCacheObject, GridCacheVersion> drMap, final boolean retval, @Nullable final CacheEntryPredicate filter, boolean singleRmv) {
if (cacheCtx.mvccEnabled())
return mvccRemoveAllAsync0(cacheCtx, keys, retval, filter);
try {
checkUpdatesAllowed(cacheCtx);
} catch (IgniteCheckedException e) {
return new GridFinishedFuture(e);
}
cacheCtx.checkSecurity(SecurityPermission.CACHE_REMOVE);
if (retval)
needReturnValue(true);
final Collection<?> keys0;
if (drMap != null) {
assert keys == null;
keys0 = drMap.keySet();
} else
keys0 = keys;
CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
final Byte dataCenterId;
if (opCtx != null && opCtx.hasDataCenterId()) {
assert drMap == null : drMap;
dataCenterId = opCtx.dataCenterId();
} else
dataCenterId = null;
assert keys0 != null;
if (log.isDebugEnabled())
log.debug(S.toString("Called removeAllAsync(...)", "tx", this, false, "keys", keys0, true, "implicit", implicit, false, "retval", retval, false));
try {
checkValid();
} catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(e);
}
final GridCacheReturn ret = new GridCacheReturn(localResult(), false);
if (F.isEmpty(keys0)) {
if (implicit()) {
try {
commit();
} catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(e);
}
}
return new GridFinishedFuture<>(ret.success(true));
}
init();
final Collection<KeyCacheObject> enlisted = new ArrayList<>();
ExpiryPolicy plc;
final CacheEntryPredicate[] filters = CU.filterArray(filter);
if (!F.isEmpty(filters))
plc = opCtx != null ? opCtx.expiry() : null;
else
plc = null;
final boolean keepBinary = opCtx != null && opCtx.isKeepBinary();
final IgniteInternalFuture<Void> loadFut = enlistWrite(cacheCtx, entryTopVer, keys0, plc, /*lookup map*/
null, /*invoke map*/
null, /*invoke arguments*/
null, retval, /*lock only*/
false, filters, ret, enlisted, null, drMap, opCtx != null && opCtx.skipStore(), singleRmv, keepBinary, opCtx != null && opCtx.recovery(), dataCenterId);
try {
loadFut.get();
} catch (IgniteCheckedException e) {
return new GridFinishedFuture(e);
}
long timeout = remainingTime();
if (timeout == -1)
return new GridFinishedFuture<>(timeoutException());
if (isRollbackOnly())
return new GridFinishedFuture<>(rollbackException());
if (log.isDebugEnabled())
log.debug("Remove keys: " + enlisted);
// to be rolled back.
if (pessimistic()) {
if (log.isDebugEnabled())
log.debug("Before acquiring transaction lock for remove on keys: " + enlisted);
IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(enlisted, timeout, this, false, retval, isolation, isInvalidate(), -1L, -1L);
PLC1<GridCacheReturn> plc1 = new PLC1<GridCacheReturn>(ret) {
/**
* {@inheritDoc}
*/
@Override
protected GridCacheReturn postLock(GridCacheReturn ret) throws IgniteCheckedException {
if (log.isDebugEnabled())
log.debug("Acquired transaction lock for remove on keys: " + enlisted);
postLockWrite(cacheCtx, enlisted, ret, /*remove*/
true, retval, /*read*/
false, -1L, filters, /*computeInvoke*/
false);
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 {
if (implicit()) {
// with prepare response, if required.
assert loadFut.isDone();
return nonInterruptable(commitNearTxLocalAsync().chain(new CX1<IgniteInternalFuture<IgniteInternalTx>, GridCacheReturn>() {
@Override
public GridCacheReturn applyx(IgniteInternalFuture<IgniteInternalTx> txFut) throws IgniteCheckedException {
try {
txFut.get();
return new GridCacheReturn(cacheCtx, true, keepBinary, U.deploymentClassLoader(cctx.kernalContext(), deploymentLdrId), implicitRes.value(), implicitRes.success());
} catch (IgniteCheckedException | RuntimeException e) {
rollbackNearTxLocalAsync();
throw e;
}
}
}));
} else {
return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Void>, GridCacheReturn>() {
@Override
public GridCacheReturn applyx(IgniteInternalFuture<Void> f) throws IgniteCheckedException {
f.get();
return ret;
}
}));
}
}
}
Aggregations