use of javax.cache.processor.EntryProcessor in project ignite by apache.
the class GridDhtAtomicCache method updateAll0.
/**
* Entry point for all public API put/transform methods.
*
* @param map Put map. Either {@code map}, {@code invokeMap} or {@code conflictPutMap} should be passed.
* @param invokeMap Invoke map. Either {@code map}, {@code invokeMap} or {@code conflictPutMap} should be passed.
* @param invokeArgs Optional arguments for EntryProcessor.
* @param conflictPutMap Conflict put map.
* @param conflictRmvMap Conflict remove map.
* @param retval Return value required flag.
* @param rawRetval Return {@code GridCacheReturn} instance.
* @param async Async operation flag.
* @return Completion future.
*/
@SuppressWarnings("ConstantConditions")
private IgniteInternalFuture updateAll0(@Nullable Map<? extends K, ? extends V> map, @Nullable Map<? extends K, ? extends EntryProcessor> invokeMap, @Nullable Object[] invokeArgs, @Nullable Map<KeyCacheObject, GridCacheDrInfo> conflictPutMap, @Nullable Map<KeyCacheObject, GridCacheVersion> conflictRmvMap, final boolean retval, final boolean rawRetval, final GridCacheOperation op, boolean async) {
assert ctx.updatesAllowed();
if (map != null && keyCheck)
validateCacheKeys(map.keySet());
ctx.checkSecurity(SecurityPermission.CACHE_PUT);
final CacheOperationContext opCtx = ctx.operationContextPerCall();
if (opCtx != null && opCtx.hasDataCenterId()) {
assert conflictPutMap == null : conflictPutMap;
assert conflictRmvMap == null : conflictRmvMap;
if (op == GridCacheOperation.TRANSFORM) {
assert invokeMap != null : invokeMap;
conflictPutMap = F.viewReadOnly((Map) invokeMap, new IgniteClosure<EntryProcessor, GridCacheDrInfo>() {
@Override
public GridCacheDrInfo apply(EntryProcessor o) {
return new GridCacheDrInfo(o, ctx.versions().next(opCtx.dataCenterId()));
}
});
invokeMap = null;
} else if (op == GridCacheOperation.DELETE) {
assert map != null : map;
conflictRmvMap = F.viewReadOnly((Map) map, new IgniteClosure<V, GridCacheVersion>() {
@Override
public GridCacheVersion apply(V o) {
return ctx.versions().next(opCtx.dataCenterId());
}
});
map = null;
} else {
assert map != null : map;
conflictPutMap = F.viewReadOnly((Map) map, new IgniteClosure<V, GridCacheDrInfo>() {
@Override
public GridCacheDrInfo apply(V o) {
return new GridCacheDrInfo(ctx.toCacheObject(o), ctx.versions().next(opCtx.dataCenterId()));
}
});
map = null;
}
}
UUID subjId = ctx.subjectIdPerCall(null, opCtx);
int taskNameHash = ctx.kernalContext().job().currentTaskNameHash();
final GridNearAtomicUpdateFuture updateFut = new GridNearAtomicUpdateFuture(ctx, this, ctx.config().getWriteSynchronizationMode(), op, map != null ? map.keySet() : invokeMap != null ? invokeMap.keySet() : conflictPutMap != null ? conflictPutMap.keySet() : conflictRmvMap.keySet(), map != null ? map.values() : invokeMap != null ? invokeMap.values() : null, invokeArgs, (Collection) (conflictPutMap != null ? conflictPutMap.values() : null), conflictRmvMap != null ? conflictRmvMap.values() : null, retval, rawRetval, opCtx != null ? opCtx.expiry() : null, CU.filterArray(null), subjId, taskNameHash, opCtx != null && opCtx.skipStore(), opCtx != null && opCtx.isKeepBinary(), opCtx != null && opCtx.recovery(), opCtx != null && opCtx.noRetries() ? 1 : MAX_RETRIES);
if (async) {
return asyncOp(new CO<IgniteInternalFuture<Object>>() {
@Override
public IgniteInternalFuture<Object> apply() {
updateFut.map();
return updateFut;
}
});
} else {
updateFut.map();
return updateFut;
}
}
use of javax.cache.processor.EntryProcessor in project ignite by apache.
the class GridNearAtomicFullUpdateRequest method addUpdateEntry.
/** {@inheritDoc} */
@Override
public void addUpdateEntry(KeyCacheObject key, @Nullable Object val, long conflictTtl, long conflictExpireTime, @Nullable GridCacheVersion conflictVer) {
EntryProcessor<Object, Object, Object> entryProcessor = null;
if (op == TRANSFORM) {
assert val instanceof EntryProcessor : val;
entryProcessor = (EntryProcessor<Object, Object, Object>) val;
}
assert val != null || op == DELETE;
keys.add(key);
if (entryProcessor != null) {
if (entryProcessors == null)
entryProcessors = new ArrayList<>(initSize);
entryProcessors.add(entryProcessor);
} else if (val != null) {
assert val instanceof CacheObject : val;
if (vals == null)
vals = new ArrayList<>(initSize);
vals.add((CacheObject) val);
}
// In case there is no conflict, do not create the list.
if (conflictVer != null) {
if (conflictVers == null) {
conflictVers = new ArrayList<>(initSize);
for (int i = 0; i < keys.size() - 1; i++) conflictVers.add(null);
}
conflictVers.add(conflictVer);
} else if (conflictVers != null)
conflictVers.add(null);
if (conflictTtl >= 0) {
if (conflictTtls == null) {
conflictTtls = new GridLongList(keys.size());
for (int i = 0; i < keys.size() - 1; i++) conflictTtls.add(CU.TTL_NOT_CHANGED);
}
conflictTtls.add(conflictTtl);
}
if (conflictExpireTime >= 0) {
if (conflictExpireTimes == null) {
conflictExpireTimes = new GridLongList(keys.size());
for (int i = 0; i < keys.size() - 1; i++) conflictExpireTimes.add(CU.EXPIRE_TIME_CALCULATE);
}
conflictExpireTimes.add(conflictExpireTime);
}
}
use of javax.cache.processor.EntryProcessor in project ignite by apache.
the class GridDhtTxPrepareFuture method onEntriesLocked.
/**
*
*/
private void onEntriesLocked() {
ret = new GridCacheReturn(null, tx.localResult(), true, null, true);
for (IgniteTxEntry writeEntry : writes) {
IgniteTxEntry txEntry = tx.entry(writeEntry.txKey());
assert txEntry != null : writeEntry;
GridCacheContext cacheCtx = txEntry.context();
GridCacheEntryEx cached = txEntry.cached();
ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
try {
if ((txEntry.op() == CREATE || txEntry.op() == UPDATE) && txEntry.conflictExpireTime() == CU.EXPIRE_TIME_CALCULATE) {
if (expiry != null) {
cached.unswap(true);
Duration duration = cached.hasValue() ? expiry.getExpiryForUpdate() : expiry.getExpiryForCreation();
txEntry.ttl(CU.toTtl(duration));
}
}
boolean hasFilters = !F.isEmptyOrNulls(txEntry.filters()) && !F.isAlwaysTrue(txEntry.filters());
CacheObject val;
CacheObject oldVal = null;
boolean readOld = hasFilters || retVal || txEntry.op() == DELETE || txEntry.op() == TRANSFORM || tx.nearOnOriginatingNode() || tx.hasInterceptor();
if (readOld) {
boolean readThrough = !txEntry.skipStore() && (txEntry.op() == TRANSFORM || ((retVal || hasFilters) && cacheCtx.config().isLoadPreviousValue()));
boolean evt = retVal || txEntry.op() == TRANSFORM;
EntryProcessor entryProc = null;
if (evt && txEntry.op() == TRANSFORM)
entryProc = F.first(txEntry.entryProcessors()).get1();
final boolean keepBinary = txEntry.keepBinary();
val = oldVal = cached.innerGet(null, tx, readThrough, /*metrics*/
retVal, /*event*/
evt, tx.subjectId(), entryProc, tx.resolveTaskName(), null, keepBinary);
if (retVal || txEntry.op() == TRANSFORM) {
if (!F.isEmpty(txEntry.entryProcessors())) {
invoke = true;
if (txEntry.hasValue())
val = txEntry.value();
KeyCacheObject key = txEntry.key();
Object procRes = null;
Exception err = null;
boolean modified = false;
txEntry.oldValueOnPrimary(val != null);
for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : txEntry.entryProcessors()) {
CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry<>(key, val, txEntry.cached().version(), keepBinary, txEntry.cached());
try {
EntryProcessor<Object, Object, Object> processor = t.get1();
procRes = processor.process(invokeEntry, t.get2());
val = cacheCtx.toCacheObject(invokeEntry.getValue(true));
} catch (Exception e) {
err = e;
break;
}
modified |= invokeEntry.modified();
}
if (modified)
val = cacheCtx.toCacheObject(cacheCtx.unwrapTemporary(val));
GridCacheOperation op = modified ? (val == null ? DELETE : UPDATE) : NOOP;
if (op == NOOP) {
if (expiry != null) {
long ttl = CU.toTtl(expiry.getExpiryForAccess());
txEntry.ttl(ttl);
if (ttl == CU.TTL_ZERO)
op = DELETE;
}
}
txEntry.entryProcessorCalculatedValue(new T2<>(op, op == NOOP ? null : val));
if (retVal) {
if (err != null || procRes != null)
ret.addEntryProcessResult(txEntry.context(), key, null, procRes, err, keepBinary);
else
ret.invokeResult(true);
}
} else if (retVal)
ret.value(cacheCtx, val, keepBinary);
}
if (hasFilters && !cacheCtx.isAll(cached, txEntry.filters())) {
if (expiry != null)
txEntry.ttl(CU.toTtl(expiry.getExpiryForAccess()));
txEntry.op(GridCacheOperation.NOOP);
if (filterFailedKeys == null)
filterFailedKeys = new ArrayList<>();
filterFailedKeys.add(cached.txKey());
ret.success(false);
} else
ret.success(txEntry.op() != DELETE || cached.hasValue());
}
// Send old value in case if rebalancing is not finished.
final boolean sndOldVal = !cacheCtx.isLocal() && !cacheCtx.topology().rebalanceFinished(tx.topologyVersion());
if (sndOldVal) {
if (oldVal == null && !readOld) {
oldVal = cached.innerGet(null, tx, /*readThrough*/
false, /*metrics*/
false, /*event*/
false, /*subjectId*/
tx.subjectId(), /*transformClo*/
null, /*taskName*/
null, /*expiryPlc*/
null, /*keepBinary*/
true);
}
if (oldVal != null)
oldVal.prepareMarshal(cacheCtx.cacheObjectContext());
txEntry.oldValue(oldVal);
}
} catch (IgniteCheckedException e) {
U.error(log, "Failed to get result value for cache entry: " + cached, e);
} catch (GridCacheEntryRemovedException e) {
assert false : "Got entry removed exception while holding transactional lock on entry [e=" + e + ", cached=" + cached + ']';
}
}
}
use of javax.cache.processor.EntryProcessor in project ignite by apache.
the class GridCacheMapEntry method innerUpdateLocal.
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public GridTuple3<Boolean, Object, EntryProcessorResult<Object>> innerUpdateLocal(GridCacheVersion ver, GridCacheOperation op, @Nullable Object writeObj, @Nullable Object[] invokeArgs, boolean writeThrough, boolean readThrough, boolean retval, boolean keepBinary, @Nullable ExpiryPolicy expiryPlc, boolean evt, boolean metrics, @Nullable CacheEntryPredicate[] filter, boolean intercept, @Nullable UUID subjId, String taskName) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert cctx.isLocal() && cctx.atomic();
CacheObject old;
boolean res = true;
IgniteBiTuple<Boolean, ?> interceptorRes = null;
EntryProcessorResult<Object> invokeRes = null;
synchronized (this) {
boolean internal = isInternal() || !context().userCache();
Map<UUID, CacheContinuousQueryListener> lsnrCol = cctx.continuousQueries().updateListeners(internal, false);
boolean needVal = retval || intercept || op == GridCacheOperation.TRANSFORM || !F.isEmpty(filter) || lsnrCol != null;
checkObsolete();
CacheDataRow oldRow = null;
// Load and remove from swap if it is new.
if (isNew())
oldRow = unswap(retval, false);
old = val;
boolean readFromStore = false;
Object old0 = null;
if (readThrough && needVal && old == null && (cctx.readThrough() && (op == GridCacheOperation.TRANSFORM || cctx.loadPreviousValue()))) {
old0 = readThrough(null, key, false, subjId, taskName);
old = cctx.toCacheObject(old0);
long ttl = CU.TTL_ETERNAL;
long expireTime = CU.EXPIRE_TIME_ETERNAL;
if (expiryPlc != null && old != null) {
ttl = CU.toTtl(expiryPlc.getExpiryForCreation());
if (ttl == CU.TTL_ZERO) {
ttl = CU.TTL_MINIMUM;
expireTime = CU.expireTimeInPast();
} else if (ttl == CU.TTL_NOT_CHANGED)
ttl = CU.TTL_ETERNAL;
else
expireTime = CU.toExpireTime(ttl);
}
// Detach value before index update.
old = cctx.kernalContext().cacheObjects().prepareForCache(old, cctx);
if (old != null)
storeValue(old, expireTime, ver, oldRow);
else
removeValue();
update(old, expireTime, ttl, ver, true);
}
// Apply metrics.
if (metrics && cctx.cache().configuration().isStatisticsEnabled() && needVal) {
// PutIfAbsent methods mustn't update hit/miss statistics
if (op != GridCacheOperation.UPDATE || F.isEmpty(filter) || !cctx.putIfAbsentFilter(filter))
cctx.cache().metrics0().onRead(old != null);
}
// Check filter inside of synchronization.
if (!F.isEmpty(filter)) {
boolean pass = cctx.isAllLocked(this, filter);
if (!pass) {
if (expiryPlc != null && !readFromStore && !cctx.putIfAbsentFilter(filter) && hasValueUnlocked())
updateTtl(expiryPlc);
Object val = retval ? cctx.cacheObjectContext().unwrapBinaryIfNeeded(CU.value(old, cctx, false), keepBinary, false) : null;
return new T3<>(false, val, null);
}
}
String transformCloClsName = null;
CacheObject updated;
Object key0 = null;
Object updated0 = null;
// Calculate new value.
if (op == GridCacheOperation.TRANSFORM) {
transformCloClsName = EntryProcessorResourceInjectorProxy.unwrap(writeObj).getClass().getName();
EntryProcessor<Object, Object, ?> entryProcessor = (EntryProcessor<Object, Object, ?>) writeObj;
assert entryProcessor != null;
CacheInvokeEntry<Object, Object> entry = new CacheInvokeEntry<>(key, old, version(), keepBinary, this);
try {
Object computed = entryProcessor.process(entry, invokeArgs);
if (entry.modified()) {
updated0 = cctx.unwrapTemporary(entry.getValue());
updated = cctx.toCacheObject(updated0);
} else
updated = old;
key0 = entry.key();
invokeRes = computed != null ? CacheInvokeResult.fromResult(cctx.unwrapTemporary(computed)) : null;
} catch (Exception e) {
updated = old;
invokeRes = CacheInvokeResult.fromError(e);
}
if (!entry.modified()) {
if (expiryPlc != null && !readFromStore && hasValueUnlocked())
updateTtl(expiryPlc);
return new GridTuple3<>(false, null, invokeRes);
}
} else
updated = (CacheObject) writeObj;
op = updated == null ? GridCacheOperation.DELETE : GridCacheOperation.UPDATE;
if (intercept) {
CacheLazyEntry e;
if (op == GridCacheOperation.UPDATE) {
updated0 = value(updated0, updated, keepBinary, false);
e = new CacheLazyEntry(cctx, key, key0, old, old0, keepBinary);
Object interceptorVal = cctx.config().getInterceptor().onBeforePut(e, updated0);
if (interceptorVal == null)
return new GridTuple3<>(false, cctx.unwrapTemporary(value(old0, old, keepBinary, false)), invokeRes);
else {
updated0 = cctx.unwrapTemporary(interceptorVal);
updated = cctx.toCacheObject(updated0);
}
} else {
e = new CacheLazyEntry(cctx, key, key0, old, old0, keepBinary);
interceptorRes = cctx.config().getInterceptor().onBeforeRemove(e);
if (cctx.cancelRemove(interceptorRes))
return new GridTuple3<>(false, cctx.unwrapTemporary(interceptorRes.get2()), invokeRes);
}
key0 = e.key();
old0 = e.value();
}
boolean hadVal = hasValueUnlocked();
long ttl = CU.TTL_ETERNAL;
long expireTime = CU.EXPIRE_TIME_ETERNAL;
if (op == GridCacheOperation.UPDATE) {
if (expiryPlc != null) {
ttl = CU.toTtl(hadVal ? expiryPlc.getExpiryForUpdate() : expiryPlc.getExpiryForCreation());
if (ttl == CU.TTL_NOT_CHANGED) {
ttl = ttlExtras();
expireTime = expireTimeExtras();
} else if (ttl != CU.TTL_ZERO)
expireTime = CU.toExpireTime(ttl);
} else {
ttl = ttlExtras();
expireTime = expireTimeExtras();
}
}
if (ttl == CU.TTL_ZERO)
op = GridCacheOperation.DELETE;
// Try write-through.
if (op == GridCacheOperation.UPDATE) {
// Detach value before index update.
updated = cctx.kernalContext().cacheObjects().prepareForCache(updated, cctx);
if (writeThrough)
// Must persist inside synchronization in non-tx mode.
cctx.store().put(null, key, updated, ver);
storeValue(updated, expireTime, ver, oldRow);
assert ttl != CU.TTL_ZERO;
update(updated, expireTime, ttl, ver, true);
if (evt) {
CacheObject evtOld = null;
if (transformCloClsName != null && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) {
evtOld = cctx.unwrapTemporary(old);
cctx.events().addEvent(partition(), key, cctx.localNodeId(), null, (GridCacheVersion) null, EVT_CACHE_OBJECT_READ, evtOld, evtOld != null || hadVal, evtOld, evtOld != null || hadVal, subjId, transformCloClsName, taskName, keepBinary);
}
if (cctx.events().isRecordable(EVT_CACHE_OBJECT_PUT)) {
if (evtOld == null)
evtOld = cctx.unwrapTemporary(old);
cctx.events().addEvent(partition(), key, cctx.localNodeId(), null, (GridCacheVersion) null, EVT_CACHE_OBJECT_PUT, updated, updated != null, evtOld, evtOld != null || hadVal, subjId, null, taskName, keepBinary);
}
}
} else {
if (writeThrough)
// Must persist inside synchronization in non-tx mode.
cctx.store().remove(null, key);
removeValue();
update(null, CU.TTL_ETERNAL, CU.EXPIRE_TIME_ETERNAL, ver, true);
if (evt) {
CacheObject evtOld = null;
if (transformCloClsName != null && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ))
cctx.events().addEvent(partition(), key, cctx.localNodeId(), null, (GridCacheVersion) null, EVT_CACHE_OBJECT_READ, evtOld, evtOld != null || hadVal, evtOld, evtOld != null || hadVal, subjId, transformCloClsName, taskName, keepBinary);
if (cctx.events().isRecordable(EVT_CACHE_OBJECT_REMOVED)) {
if (evtOld == null)
evtOld = cctx.unwrapTemporary(old);
cctx.events().addEvent(partition(), key, cctx.localNodeId(), null, (GridCacheVersion) null, EVT_CACHE_OBJECT_REMOVED, null, false, evtOld, evtOld != null || hadVal, subjId, null, taskName, keepBinary);
}
}
res = hadVal;
}
if (res)
updateMetrics(op, metrics);
if (lsnrCol != null) {
long updateCntr = nextPartCounter(AffinityTopologyVersion.NONE);
cctx.continuousQueries().onEntryUpdated(lsnrCol, key, val, old, internal, partition(), true, false, updateCntr, null, AffinityTopologyVersion.NONE);
onUpdateFinished(updateCntr);
}
cctx.dataStructures().onEntryUpdated(key, op == GridCacheOperation.DELETE, keepBinary);
if (intercept) {
if (op == GridCacheOperation.UPDATE)
cctx.config().getInterceptor().onAfterPut(new CacheLazyEntry(cctx, key, key0, updated, updated0, keepBinary, 0L));
else
cctx.config().getInterceptor().onAfterRemove(new CacheLazyEntry(cctx, key, key0, old, old0, keepBinary, 0L));
}
}
return new GridTuple3<>(res, cctx.unwrapTemporary(interceptorRes != null ? interceptorRes.get2() : cctx.cacheObjectContext().unwrapBinaryIfNeeded(old, keepBinary, false)), invokeRes);
}
use of javax.cache.processor.EntryProcessor in project ignite by apache.
the class GridCacheMessage method marshalTx.
/**
* @param txEntries Entries to marshal.
* @param ctx Context.
* @throws IgniteCheckedException If failed.
*/
protected final void marshalTx(Iterable<IgniteTxEntry> txEntries, GridCacheSharedContext ctx) throws IgniteCheckedException {
assert ctx != null;
if (txEntries != null) {
boolean transferExpiry = transferExpiryPolicy();
boolean p2pEnabled = ctx.deploymentEnabled();
for (IgniteTxEntry e : txEntries) {
e.marshal(ctx, transferExpiry);
GridCacheContext cctx = e.context();
if (addDepInfo) {
if (e.key() != null)
prepareObject(e.key().value(cctx.cacheObjectContext(), false), cctx);
if (e.value() != null)
prepareObject(e.value().value(cctx.cacheObjectContext(), false), cctx);
if (e.entryProcessors() != null) {
for (T2<EntryProcessor<Object, Object, Object>, Object[]> entProc : e.entryProcessors()) prepareObject(entProc.get1(), cctx);
}
} else if (p2pEnabled && e.entryProcessors() != null) {
if (!forceAddDepInfo)
forceAddDepInfo = true;
for (T2<EntryProcessor<Object, Object, Object>, Object[]> entProc : e.entryProcessors()) prepareObject(entProc.get1(), cctx);
}
}
}
}
Aggregations