Search in sources :

Example 1 with GridNearCacheEntry

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;
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridNearCacheEntry(org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry) IgniteInternalTx(org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx)

Example 2 with GridNearCacheEntry

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());
        }
    }
}
Also used : IgniteKernal(org.apache.ignite.internal.IgniteKernal) GridNearLockRequest(org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest) TestRecordingCommunicationSpi(org.apache.ignite.internal.TestRecordingCommunicationSpi) GridNearCacheEntry(org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry) Transaction(org.apache.ignite.transactions.Transaction) Collection(java.util.Collection) NearCacheConfiguration(org.apache.ignite.configuration.NearCacheConfiguration) CacheConfiguration(org.apache.ignite.configuration.CacheConfiguration) GridCommonAbstractTest(org.apache.ignite.testframework.junits.common.GridCommonAbstractTest) Test(org.junit.Test)

Example 3 with GridNearCacheEntry

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;
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridNearCacheEntry(org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteInternalTx(org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx)

Example 4 with GridNearCacheEntry

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;
}
Also used : GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) GridNearCacheEntry(org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) GridNearCacheAdapter(org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter) IgniteException(org.apache.ignite.IgniteException)

Example 5 with GridNearCacheEntry

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();
}
Also used : GridNearCacheEntry(org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry) GridCacheAdapter(org.apache.ignite.internal.processors.cache.GridCacheAdapter)

Aggregations

GridNearCacheEntry (org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry)9 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)6 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)3 IgniteException (org.apache.ignite.IgniteException)3 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)3 GridNearCacheAdapter (org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter)3 Collection (java.util.Collection)2 HashSet (java.util.HashSet)2 Set (java.util.Set)2 IgniteKernal (org.apache.ignite.internal.IgniteKernal)2 NodeStoppingException (org.apache.ignite.internal.NodeStoppingException)2 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)2 GridCacheAdapter (org.apache.ignite.internal.processors.cache.GridCacheAdapter)2 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)2 IgniteInternalTx (org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx)2 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Map (java.util.Map)1