use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry in project ignite by apache.
the class GridCacheMapEntry method innerGet0.
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked", "RedundantTypeArguments", "TooBroadScope" })
private Object innerGet0(GridCacheVersion nextVer, IgniteInternalTx tx, boolean readThrough, boolean evt, boolean updateMetrics, UUID subjId, Object transformClo, String taskName, @Nullable IgniteCacheExpiryPolicy expiryPlc, boolean retVer, boolean keepBinary, boolean reserveForLoad, @Nullable ReaderArguments readerArgs) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert !(retVer && readThrough);
assert !(reserveForLoad && readThrough);
// Disable read-through if there is no store.
if (readThrough && !cctx.readThrough())
readThrough = false;
GridCacheVersion startVer;
GridCacheVersion resVer = null;
boolean obsolete = false;
boolean deferred = false;
GridCacheVersion ver0 = null;
Object res = null;
lockEntry();
try {
checkObsolete();
boolean valid = valid(tx != null ? tx.topologyVersion() : cctx.affinity().affinityTopologyVersion());
CacheObject val;
if (valid) {
val = this.val;
if (val == null) {
if (isStartVersion()) {
unswap(null, false);
val = this.val;
}
}
if (val != null) {
long expireTime = expireTimeExtras();
if (expireTime > 0 && (expireTime - U.currentTimeMillis() <= 0)) {
if (onExpired((CacheObject) cctx.unwrapTemporary(val), null)) {
val = null;
evt = false;
if (cctx.deferredDelete()) {
deferred = true;
ver0 = ver;
} else
obsolete = true;
}
}
}
} else
val = null;
CacheObject ret = val;
if (ret == null) {
if (updateMetrics && cctx.statisticsEnabled())
cctx.cache().metrics0().onRead(false);
} else {
if (updateMetrics && cctx.statisticsEnabled())
cctx.cache().metrics0().onRead(true);
}
if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) {
transformClo = EntryProcessorResourceInjectorProxy.unwrap(transformClo);
GridCacheMvcc mvcc = mvccExtras();
cctx.events().addEvent(partition(), key, tx, mvcc != null ? mvcc.anyOwner() : null, EVT_CACHE_OBJECT_READ, ret, ret != null, ret, ret != null, subjId, transformClo != null ? transformClo.getClass().getName() : null, taskName, keepBinary);
// No more notifications.
evt = false;
}
if (ret != null && expiryPlc != null)
updateTtl(expiryPlc);
if (retVer) {
resVer = (isNear() && cctx.transactional()) ? ((GridNearCacheEntry) this).dhtVersion() : this.ver;
if (resVer == null)
ret = null;
}
// Cache version for optimistic check.
startVer = ver;
addReaderIfNeed(readerArgs);
if (ret != null) {
assert !obsolete;
assert !deferred;
// If return value is consistent, then done.
res = retVer ? entryGetResult(ret, resVer, false) : ret;
} else if (reserveForLoad && !obsolete) {
assert !readThrough;
assert retVer;
boolean reserve = !evictionDisabled();
if (reserve)
flags |= IS_EVICT_DISABLED;
res = entryGetResult(null, resVer, reserve);
}
} finally {
unlockEntry();
}
if (obsolete) {
onMarkedObsolete();
throw new GridCacheEntryRemovedException();
}
if (deferred)
cctx.onDeferredDelete(this, ver0);
if (res != null)
return res;
CacheObject ret = null;
if (readThrough) {
IgniteInternalTx tx0 = null;
if (tx != null && tx.local()) {
if (cctx.isReplicated() || cctx.isColocated() || tx.near())
tx0 = tx;
else if (tx.dht()) {
GridCacheVersion ver = tx.nearXidVersion();
tx0 = cctx.dht().near().context().tm().tx(ver);
}
}
Object storeVal = readThrough(tx0, key, false, subjId, taskName);
ret = cctx.toCacheObject(storeVal);
}
if (ret == null && !evt)
return null;
lockEntry();
try {
long ttl = ttlExtras();
// If version matched, set value.
if (startVer.equals(ver)) {
if (ret != null) {
// Detach value before index update.
ret = cctx.kernalContext().cacheObjects().prepareForCache(ret, cctx);
nextVer = nextVer != null ? nextVer : nextVersion();
long expTime = CU.toExpireTime(ttl);
// Update indexes before actual write to entry.
storeValue(ret, expTime, nextVer, null);
update(ret, expTime, ttl, nextVer, true);
if (cctx.deferredDelete() && deletedUnlocked() && !isInternal() && !detached())
deletedUnlocked(false);
assert readerArgs == null;
}
if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) {
transformClo = EntryProcessorResourceInjectorProxy.unwrap(transformClo);
GridCacheMvcc mvcc = mvccExtras();
cctx.events().addEvent(partition(), key, tx, mvcc != null ? mvcc.anyOwner() : null, EVT_CACHE_OBJECT_READ, ret, ret != null, null, false, subjId, transformClo != null ? transformClo.getClass().getName() : null, taskName, keepBinary);
}
}
} finally {
unlockEntry();
}
assert ret == null || !retVer;
return ret;
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry in project ignite by apache.
the class IgniteCacheNearLockValueSelfTest method testDhtVersion.
/**
* @throws Exception If failed.
*/
@Test
public void testDhtVersion() throws Exception {
CacheConfiguration<Object, Object> pCfg = new CacheConfiguration<>("partitioned");
pCfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
try (IgniteCache<Object, Object> cache = ignite(0).getOrCreateCache(pCfg, new NearCacheConfiguration<>())) {
cache.put("key1", "val1");
for (int i = 0; i < 3; i++) {
try (Transaction tx = ignite(0).transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
cache.get("key1");
tx.commit();
}
TestRecordingCommunicationSpi comm = (TestRecordingCommunicationSpi) ignite(0).configuration().getCommunicationSpi();
Collection<GridNearLockRequest> reqs = (Collection) comm.recordedMessages(false);
assertEquals(1, reqs.size());
GridCacheAdapter<Object, Object> primary = ((IgniteKernal) grid(1)).internalCache("partitioned");
GridCacheEntryEx dhtEntry = primary.peekEx(primary.context().toCacheKeyObject("key1"));
assertNotNull(dhtEntry);
GridNearLockRequest req = reqs.iterator().next();
assertEquals(dhtEntry.version(), req.dhtVersion(0));
// Check entry version in near cache after commit.
GridCacheAdapter<Object, Object> near = ((IgniteKernal) grid(0)).internalCache("partitioned");
GridNearCacheEntry nearEntry = (GridNearCacheEntry) near.peekEx(near.context().toCacheKeyObject("key1"));
assertNotNull(nearEntry);
assertEquals(dhtEntry.version(), nearEntry.dhtVersion());
}
}
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry in project ignite by apache.
the class GridCacheMapEntry method innerGet0.
/**
*/
@SuppressWarnings({ "TooBroadScope" })
private Object innerGet0(GridCacheVersion nextVer, IgniteInternalTx tx, boolean readThrough, boolean evt, boolean updateMetrics, Object transformClo, String taskName, @Nullable IgniteCacheExpiryPolicy expiryPlc, boolean retVer, boolean keepBinary, boolean reserveForLoad, @Nullable ReaderArguments readerArgs) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert !(retVer && readThrough);
assert !(reserveForLoad && readThrough);
// Disable read-through if there is no store.
if (readThrough && !cctx.readThrough())
readThrough = false;
GridCacheVersion startVer;
GridCacheVersion resVer = null;
boolean obsolete = false;
boolean deferred = false;
GridCacheVersion ver0 = null;
Object res = null;
lockEntry();
try {
checkObsolete();
CacheObject val;
AffinityTopologyVersion topVer = tx != null ? tx.topologyVersion() : cctx.affinity().affinityTopologyVersion();
boolean valid = valid(topVer);
if (valid) {
val = this.val;
if (val == null) {
if (isStartVersion()) {
unswap(null, false);
val = this.val;
if (val != null && tx == null)
updatePlatformCache(val, topVer);
}
}
if (val != null) {
long expireTime = expireTimeExtras();
if (expireTime > 0 && (expireTime < U.currentTimeMillis())) {
if (onExpired((CacheObject) cctx.unwrapTemporary(val), null)) {
val = null;
evt = false;
if (cctx.deferredDelete()) {
deferred = true;
ver0 = ver;
} else
obsolete = true;
}
}
}
} else
val = null;
CacheObject ret = val;
if (ret == null) {
if (updateMetrics && cctx.statisticsEnabled())
cctx.cache().metrics0().onRead(false);
} else {
if (updateMetrics && cctx.statisticsEnabled())
cctx.cache().metrics0().onRead(true);
}
if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) {
transformClo = EntryProcessorResourceInjectorProxy.unwrap(transformClo);
GridCacheMvcc mvcc = mvccExtras();
cctx.events().addEvent(partition(), key, tx, mvcc != null ? mvcc.anyOwner() : null, EVT_CACHE_OBJECT_READ, ret, ret != null, ret, ret != null, transformClo != null ? transformClo.getClass().getName() : null, taskName, keepBinary);
// No more notifications.
evt = false;
}
if (ret != null && expiryPlc != null)
updateTtl(expiryPlc);
if (retVer && resVer == null) {
resVer = (isNear() && cctx.transactional()) ? ((GridNearCacheEntry) this).dhtVersion() : this.ver;
if (resVer == null)
ret = null;
}
// Cache version for optimistic check.
startVer = ver;
addReaderIfNeed(readerArgs);
if (ret != null) {
assert !obsolete;
assert !deferred;
// If return value is consistent, then done.
res = retVer ? entryGetResult(ret, resVer, false) : ret;
} else if (reserveForLoad && !obsolete) {
assert !readThrough;
assert retVer;
boolean reserve = !evictionDisabled();
if (reserve)
flags |= IS_EVICT_DISABLED;
res = entryGetResult(null, resVer, reserve);
}
} finally {
unlockEntry();
}
if (obsolete) {
onMarkedObsolete();
throw new GridCacheEntryRemovedException();
}
if (deferred)
cctx.onDeferredDelete(this, ver0);
if (res != null)
return res;
CacheObject ret = null;
if (readThrough) {
IgniteInternalTx tx0 = null;
if (tx != null && tx.local()) {
if (cctx.isReplicated() || cctx.isColocated() || tx.near())
tx0 = tx;
else if (tx.dht()) {
GridCacheVersion ver = tx.nearXidVersion();
tx0 = cctx.dht().near().context().tm().tx(ver);
}
}
Object storeVal = readThrough(tx0, key, false, taskName);
ret = cctx.toCacheObject(storeVal);
}
if (ret == null && !evt)
return null;
lockEntry();
try {
long ttl = ttlExtras();
// If version matched, set value.
if (startVer.equals(ver)) {
if (ret != null) {
// Detach value before index update.
ret = cctx.kernalContext().cacheObjects().prepareForCache(ret, cctx);
nextVer = nextVer != null ? nextVer : nextVersion();
long expTime = CU.toExpireTime(ttl);
// Update indexes before actual write to entry.
storeValue(ret, expTime, nextVer);
update(ret, expTime, ttl, nextVer, true);
if (cctx.deferredDelete() && deletedUnlocked() && !isInternal() && !detached())
deletedUnlocked(false);
assert readerArgs == null;
}
if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) {
transformClo = EntryProcessorResourceInjectorProxy.unwrap(transformClo);
GridCacheMvcc mvcc = mvccExtras();
cctx.events().addEvent(partition(), key, tx, mvcc != null ? mvcc.anyOwner() : null, EVT_CACHE_OBJECT_READ, ret, ret != null, null, false, transformClo != null ? transformClo.getClass().getName() : null, taskName, keepBinary);
}
}
} finally {
unlockEntry();
}
assert ret == null || !retVer;
return ret;
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry in project ignite by apache.
the class GridCacheTtlManager method expire.
/**
* Processes specified amount of expired entries.
*
* @param amount Limit of processed entries by single call, {@code -1} for no limit.
* @return {@code True} if unprocessed expired entries remains.
*/
public boolean expire(int amount) {
// TTL manager is not initialized or eagerTtl disabled for cache.
if (!eagerTtlEnabled)
return false;
assert cctx != null;
long now = U.currentTimeMillis();
try {
if (pendingEntries != null) {
GridNearCacheAdapter nearCache = cctx.near();
GridCacheVersion obsoleteVer = null;
int limit = (-1 != amount) ? amount : pendingEntries.sizex();
for (int cnt = limit; cnt > 0; cnt--) {
EntryWrapper e = pendingEntries.firstx();
if (e == null || e.expireTime > now)
// All expired entries are processed.
break;
if (pendingEntries.remove(e)) {
if (obsoleteVer == null)
obsoleteVer = cctx.cache().nextVersion();
GridNearCacheEntry nearEntry = nearCache.peekExx(e.key);
if (nearEntry != null)
expireC.apply(nearEntry, obsoleteVer);
}
}
}
if (!cctx.affinityNode())
return false;
if (!hasPendingEntries || nextCleanTime > U.currentTimeMillis())
return false;
boolean more = cctx.offheap().expire(dhtCtx, expireC, amount);
if (more)
return true;
// There is nothing to clean, so the next clean up can be postponed.
nextCleanTime = U.currentTimeMillis() + unwindThrottlingTimeout;
if (amount != -1 && pendingEntries != null) {
EntryWrapper e = pendingEntries.firstx();
return e != null && e.expireTime <= now;
}
} catch (GridDhtInvalidPartitionException e) {
if (log.isDebugEnabled())
log.debug("Partition became invalid during rebalancing (will ignore): " + e.partition());
return false;
} catch (IgniteCheckedException e) {
U.error(log, "Failed to process entry expiration: " + e, e);
} catch (IgniteException e) {
if (e.hasCause(NodeStoppingException.class)) {
if (log.isDebugEnabled())
log.debug("Failed to expire because node is stopped: " + e);
} else
throw e;
}
return false;
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry in project ignite by apache.
the class GridCacheTxNodeFailureSelfTest method dataCheck.
/**
* @param orig Originating cache.
* @param backup Backup cache.
* @param key Key being committed and checked.
* @param commit Commit or rollback flag.
* @throws Exception If check failed.
*/
private void dataCheck(IgniteKernal orig, IgniteKernal backup, int key, boolean commit) throws Exception {
GridNearCacheEntry nearEntry = null;
GridCacheAdapter origCache = orig.internalCache(DEFAULT_CACHE_NAME);
if (origCache.isNear())
nearEntry = (GridNearCacheEntry) origCache.peekEx(key);
GridCacheAdapter backupCache = backup.internalCache(DEFAULT_CACHE_NAME);
if (backupCache.isNear())
backupCache = backupCache.context().near().dht();
GridDhtCacheEntry dhtEntry = (GridDhtCacheEntry) backupCache.entryEx(key);
dhtEntry.unswap();
if (commit) {
assertNotNull(dhtEntry);
assertTrue("dhtEntry=" + dhtEntry, dhtEntry.remoteMvccSnapshot().isEmpty());
assertTrue("dhtEntry=" + dhtEntry, dhtEntry.localCandidates().isEmpty());
assertEquals(key, backupCache.localPeek(key, null));
if (nearEntry != null) {
assertTrue("near=" + nearEntry, nearEntry.remoteMvccSnapshot().isEmpty());
assertTrue("near=" + nearEntry, nearEntry.localCandidates().isEmpty());
// Near peek wil be null since primary node has changed.
assertNull("near=" + nearEntry, origCache.localPeek(key, null));
}
} else {
assertTrue("near=" + nearEntry + ", hc=" + System.identityHashCode(nearEntry), nearEntry == null);
assertTrue("Invalid backup cache entry: " + dhtEntry, dhtEntry.rawGet() == null);
}
dhtEntry.touch();
}
Aggregations