use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class IgniteTxAdapter method conflictResolve.
/**
* Resolve DR conflict.
*
* @param op Initially proposed operation.
* @param txEntry TX entry being updated.
* @param newVal New value.
* @param newVer New version.
* @param old Old entry.
* @return Tuple with adjusted operation type and conflict context.
* @throws IgniteCheckedException In case of eny exception.
* @throws GridCacheEntryRemovedException If entry got removed.
*/
@SuppressWarnings({ "unchecked", "ConstantConditions" })
protected IgniteBiTuple<GridCacheOperation, GridCacheVersionConflictContext> conflictResolve(GridCacheOperation op, IgniteTxEntry txEntry, CacheObject newVal, GridCacheVersion newVer, GridCacheEntryEx old) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert newVer != null;
// 1. Calculate TTL and expire time.
long newTtl = txEntry.ttl();
long newExpireTime = txEntry.conflictExpireTime();
// 1.1. If TTL is not changed, then calculate it based on expiry.
if (newTtl == CU.TTL_NOT_CHANGED) {
ExpiryPolicy expiry = txEntry.context().expiryForTxEntry(txEntry);
if (expiry != null) {
if (op == CREATE)
newTtl = CU.toTtl(expiry.getExpiryForCreation());
else if (op == UPDATE)
newTtl = CU.toTtl(expiry.getExpiryForUpdate());
}
}
// 1.2. If TTL is set to zero, then mark operation as "DELETE".
if (newTtl == CU.TTL_ZERO) {
op = DELETE;
newTtl = CU.TTL_ETERNAL;
}
// 1.3. If TTL is still not changed, then either use old entry TTL or set it to "ETERNAL".
if (newTtl == CU.TTL_NOT_CHANGED) {
if (old.isNewLocked())
newTtl = CU.TTL_ETERNAL;
else {
newTtl = old.rawTtl();
newExpireTime = old.rawExpireTime();
}
}
// TTL must be resolved at this point.
assert newTtl != CU.TTL_ZERO && newTtl != CU.TTL_NOT_CHANGED;
// 1.4 If expire time was not set explicitly, then calculate it.
if (newExpireTime == CU.EXPIRE_TIME_CALCULATE)
newExpireTime = CU.toExpireTime(newTtl);
// Expire time must be resolved at this point.
assert newExpireTime != CU.EXPIRE_TIME_CALCULATE;
// Construct old entry info.
GridCacheVersionedEntryEx oldEntry = old.versionedEntry(txEntry.keepBinary());
// Construct new entry info.
GridCacheContext entryCtx = txEntry.context();
GridCacheVersionedEntryEx newEntry = new GridCacheLazyPlainVersionedEntry(entryCtx, txEntry.key(), newVal, newTtl, newExpireTime, newVer, false, txEntry.keepBinary());
GridCacheVersionConflictContext ctx = old.context().conflictResolve(oldEntry, newEntry, false);
if (ctx.isMerge()) {
Object resVal = ctx.mergeValue();
if ((op == CREATE || op == UPDATE) && resVal == null)
op = DELETE;
else if (op == DELETE && resVal != null)
op = old.isNewLocked() ? CREATE : UPDATE;
}
return F.t(op, ctx);
}
use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class IgniteTxAdapter method applyTransformClosures.
/**
* @param txEntry Entry to process.
* @param metrics {@code True} if metrics should be updated.
* @param ret Optional return value to initialize.
* @return Tuple containing transformation results.
* @throws IgniteCheckedException If failed to get previous value for transform.
* @throws GridCacheEntryRemovedException If entry was concurrently deleted.
*/
protected IgniteBiTuple<GridCacheOperation, CacheObject> applyTransformClosures(IgniteTxEntry txEntry, boolean metrics, @Nullable GridCacheReturn ret) throws GridCacheEntryRemovedException, IgniteCheckedException {
assert txEntry.op() != TRANSFORM || !F.isEmpty(txEntry.entryProcessors()) : txEntry;
GridCacheContext cacheCtx = txEntry.context();
assert cacheCtx != null;
if (isSystemInvalidate())
return F.t(cacheCtx.writeThrough() ? RELOAD : DELETE, null);
if (F.isEmpty(txEntry.entryProcessors())) {
if (ret != null)
ret.value(cacheCtx, txEntry.value(), txEntry.keepBinary());
return F.t(txEntry.op(), txEntry.value());
} else {
T2<GridCacheOperation, CacheObject> calcVal = txEntry.entryProcessorCalculatedValue();
if (calcVal != null)
return calcVal;
boolean recordEvt = cctx.gridEvents().isRecordable(EVT_CACHE_OBJECT_READ);
final boolean keepBinary = txEntry.keepBinary();
CacheObject cacheVal;
if (txEntry.hasValue())
cacheVal = txEntry.value();
else if (txEntry.hasOldValue())
cacheVal = txEntry.oldValue();
else {
cacheVal = txEntry.cached().innerGet(null, this, /*read through*/
false, /*metrics*/
metrics, /*event*/
recordEvt, /*subjId*/
subjId, /*closure name */
recordEvt ? F.first(txEntry.entryProcessors()).get1() : null, resolveTaskName(), null, keepBinary);
}
boolean modified = false;
Object val = null;
Object key = null;
GridCacheVersion ver;
try {
ver = txEntry.cached().version();
} catch (GridCacheEntryRemovedException e) {
assert optimistic() : txEntry;
if (log.isDebugEnabled())
log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
ver = null;
}
for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : txEntry.entryProcessors()) {
CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry<>(txEntry.key(), key, cacheVal, val, ver, keepBinary, txEntry.cached());
Object procRes = null;
Exception err = null;
try {
EntryProcessor<Object, Object, Object> processor = t.get1();
procRes = processor.process(invokeEntry, t.get2());
val = invokeEntry.getValue();
key = invokeEntry.key();
} catch (Exception e) {
err = e;
}
if (ret != null) {
if (err != null || procRes != null)
ret.addEntryProcessResult(txEntry.context(), txEntry.key(), null, procRes, err, keepBinary);
else
ret.invokeResult(true);
}
modified |= invokeEntry.modified();
}
if (modified)
cacheVal = cacheCtx.toCacheObject(cacheCtx.unwrapTemporary(val));
GridCacheOperation op = modified ? (cacheVal == null ? DELETE : UPDATE) : NOOP;
if (op == NOOP) {
ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
if (expiry != null) {
long ttl = CU.toTtl(expiry.getExpiryForAccess());
txEntry.ttl(ttl);
if (ttl == CU.TTL_ZERO)
op = DELETE;
}
}
return F.t(op, cacheVal);
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class AffinityHistoryCleanupTest method checkHistory.
/**
* @param ignite Node.
* @param expHist Expected history.
* @param expSize Expected 'non client events' history size.
* @throws Exception If failed.
*/
private void checkHistory(Ignite ignite, List<AffinityTopologyVersion> expHist, int expSize) throws Exception {
awaitPartitionMapExchange();
GridCacheProcessor proc = ((IgniteKernal) ignite).context().cache();
int cnt = 0;
for (GridCacheContext cctx : proc.context().cacheContexts()) {
GridAffinityAssignmentCache aff = GridTestUtils.getFieldValue(cctx.affinity(), "aff");
AtomicInteger histSize = GridTestUtils.getFieldValue(aff, "histSize");
assertEquals(expSize, histSize.get());
Map<AffinityTopologyVersion, Object> cache = GridTestUtils.getFieldValue(aff, "affCache");
assertEquals("Unexpected history: " + cache.keySet(), expHist.size(), cache.size());
for (AffinityTopologyVersion topVer : expHist) assertTrue("No history [ver=" + topVer + ", hist=" + cache.keySet() + ']', cache.containsKey(topVer));
cnt++;
}
assert cnt > 4;
}
use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class IgniteTxAdapter method isNearLocallyMapped.
/**
* @param e Transaction entry.
* @param primaryOnly Flag to include backups into check or not.
* @return {@code True} if entry is locally mapped as a primary or back up node.
*/
protected boolean isNearLocallyMapped(IgniteTxEntry e, boolean primaryOnly) {
GridCacheContext cacheCtx = e.context();
if (!cacheCtx.isNear())
return false;
// Try to take either entry-recorded primary node ID,
// or transaction node ID from near-local transactions.
UUID nodeId = e.nodeId() == null ? local() ? this.nodeId : null : e.nodeId();
if (nodeId != null && nodeId.equals(cctx.localNodeId()))
return true;
GridCacheEntryEx cached = e.cached();
int part = cached != null ? cached.partition() : cacheCtx.affinity().partition(e.key());
List<ClusterNode> affNodes = cacheCtx.affinity().nodesByPartition(part, topologyVersion());
e.locallyMapped(F.contains(affNodes, cctx.localNode()));
if (primaryOnly) {
ClusterNode primary = F.first(affNodes);
if (primary == null && !cacheCtx.affinityNode())
return false;
assert primary != null : "Primary node is null for affinity nodes: " + affNodes;
return primary.isLocal();
} else
return e.locallyMapped();
}
use of org.apache.ignite.internal.processors.cache.GridCacheContext in project ignite by apache.
the class GridContinuousProcessor method processStartAckRequest.
/**
* @param topVer Topology version.
* @param msg Message.
*/
private void processStartAckRequest(AffinityTopologyVersion topVer, StartRoutineAckDiscoveryMessage msg) {
StartFuture fut = startFuts.remove(msg.routineId());
if (fut != null) {
if (msg.errs().isEmpty()) {
LocalRoutineInfo routine = locInfos.get(msg.routineId());
// Update partition counters.
if (routine != null && routine.handler().isQuery()) {
Map<UUID, Map<Integer, T2<Long, Long>>> cntrsPerNode = msg.updateCountersPerNode();
Map<Integer, T2<Long, Long>> cntrs = msg.updateCounters();
GridCacheAdapter<Object, Object> interCache = ctx.cache().internalCache(routine.handler().cacheName());
GridCacheContext cctx = interCache != null ? interCache.context() : null;
if (cctx != null && cntrsPerNode != null && !cctx.isLocal() && cctx.affinityNode())
cntrsPerNode.put(ctx.localNodeId(), toCountersMap(cctx.topology().localUpdateCounters(false)));
routine.handler().updateCounters(topVer, cntrsPerNode, cntrs);
}
fut.onRemoteRegistered();
} else {
IgniteCheckedException firstEx = F.first(msg.errs().values());
fut.onDone(firstEx);
stopRoutine(msg.routineId());
}
}
}
Aggregations