Search in sources :

Example 91 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class GridDhtAtomicAbstractUpdateFuture method addWriteEntry.

/**
 * @param affAssignment Affinity assignment.
 * @param entry Entry to map.
 * @param val Value to write.
 * @param entryProcessor Entry processor.
 * @param ttl TTL (optional).
 * @param conflictExpireTime Conflict expire time (optional).
 * @param conflictVer Conflict version (optional).
 * @param addPrevVal If {@code true} sends previous value to backups.
 * @param prevVal Previous value.
 * @param updateCntr Partition update counter.
 */
@SuppressWarnings("ForLoopReplaceableByForEach")
final void addWriteEntry(AffinityAssignment affAssignment, GridDhtCacheEntry entry, @Nullable CacheObject val, EntryProcessor<Object, Object, Object> entryProcessor, long ttl, long conflictExpireTime, @Nullable GridCacheVersion conflictVer, boolean addPrevVal, @Nullable CacheObject prevVal, long updateCntr) {
    AffinityTopologyVersion topVer = updateReq.topologyVersion();
    List<ClusterNode> affNodes = affAssignment.get(entry.partition());
    // Client has seen that rebalancing finished, it is safe to use affinity mapping.
    List<ClusterNode> dhtNodes = updateReq.affinityMapping() ? affNodes : cctx.dht().topology().nodes(entry.partition(), affAssignment, affNodes);
    if (dhtNodes == null)
        dhtNodes = affNodes;
    if (log.isDebugEnabled())
        log.debug("Mapping entry to DHT nodes [nodes=" + U.nodeIds(dhtNodes) + ", entry=" + entry + ']');
    CacheWriteSynchronizationMode syncMode = updateReq.writeSynchronizationMode();
    addDhtKey(entry.key(), dhtNodes);
    for (int i = 0; i < dhtNodes.size(); i++) {
        ClusterNode node = dhtNodes.get(i);
        UUID nodeId = node.id();
        if (!nodeId.equals(cctx.localNodeId())) {
            GridDhtAtomicAbstractUpdateRequest updateReq = mappings.get(nodeId);
            if (updateReq == null) {
                updateReq = createRequest(node.id(), futId, writeVer, syncMode, topVer, ttl, conflictExpireTime, conflictVer);
                mappings.put(nodeId, updateReq);
            }
            updateReq.addWriteValue(entry.key(), val, entryProcessor, ttl, conflictExpireTime, conflictVer, addPrevVal, prevVal, updateCntr);
        }
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) CacheWriteSynchronizationMode(org.apache.ignite.cache.CacheWriteSynchronizationMode) UUID(java.util.UUID)

Example 92 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class GridDhtAtomicCache method getAllAsync0.

/**
 * Entry point to all public API get methods.
 *
 * @param keys Keys.
 * @param forcePrimary Force primary flag.
 * @param subjId Subject ID.
 * @param taskName Task name.
 * @param deserializeBinary Deserialize binary flag.
 * @param expiryPlc Expiry policy.
 * @param skipVals Skip values flag.
 * @param skipStore Skip store flag.
 * @param needVer Need version.
 * @return Get future.
 */
private IgniteInternalFuture<Map<K, V>> getAllAsync0(@Nullable Collection<KeyCacheObject> keys, boolean forcePrimary, UUID subjId, String taskName, boolean deserializeBinary, boolean recovery, @Nullable ExpiryPolicy expiryPlc, boolean skipVals, boolean skipStore, boolean needVer) {
    AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
    final IgniteCacheExpiryPolicy expiry = skipVals ? null : expiryPolicy(expiryPlc);
    final boolean evt = !skipVals;
    // Optimisation: try to resolve value locally and escape 'get future' creation.
    if (!forcePrimary && ctx.affinityNode()) {
        try {
            Map<K, V> locVals = U.newHashMap(keys.size());
            boolean success = true;
            boolean readNoEntry = ctx.readNoEntry(expiry, false);
            // Optimistically expect that all keys are available locally (avoid creation of get future).
            for (KeyCacheObject key : keys) {
                if (readNoEntry) {
                    CacheDataRow row = ctx.offheap().read(ctx, key);
                    if (row != null) {
                        long expireTime = row.expireTime();
                        if (expireTime == 0 || expireTime > U.currentTimeMillis()) {
                            ctx.addResult(locVals, key, row.value(), skipVals, false, deserializeBinary, true, null, row.version(), 0, 0, needVer);
                            if (evt) {
                                ctx.events().readEvent(key, null, row.value(), subjId, taskName, !deserializeBinary);
                            }
                        } else
                            success = false;
                    } else
                        success = false;
                } else {
                    GridCacheEntryEx entry = null;
                    while (true) {
                        try {
                            entry = entryEx(key);
                            // If our DHT cache do has value, then we peek it.
                            if (entry != null) {
                                boolean isNew = entry.isNewLocked();
                                EntryGetResult getRes = null;
                                CacheObject v = null;
                                GridCacheVersion ver = null;
                                if (needVer) {
                                    getRes = entry.innerGetVersioned(null, null, /*update-metrics*/
                                    false, /*event*/
                                    evt, subjId, null, taskName, expiry, true, null);
                                    if (getRes != null) {
                                        v = getRes.value();
                                        ver = getRes.version();
                                    }
                                } else {
                                    v = entry.innerGet(null, null, /*read-through*/
                                    false, /*update-metrics*/
                                    false, /*event*/
                                    evt, subjId, null, taskName, expiry, !deserializeBinary);
                                }
                                // Entry was not in memory or in swap, so we remove it from cache.
                                if (v == null) {
                                    if (isNew && entry.markObsoleteIfEmpty(context().versions().next()))
                                        removeEntry(entry);
                                    success = false;
                                } else {
                                    ctx.addResult(locVals, key, v, skipVals, false, deserializeBinary, true, getRes, ver, 0, 0, needVer);
                                }
                            } else
                                success = false;
                            // While.
                            break;
                        } catch (GridCacheEntryRemovedException ignored) {
                        // No-op, retry.
                        } catch (GridDhtInvalidPartitionException ignored) {
                            success = false;
                            // While.
                            break;
                        } finally {
                            if (entry != null)
                                ctx.evicts().touch(entry, topVer);
                        }
                    }
                }
                if (!success)
                    break;
                else if (!skipVals && ctx.statisticsEnabled())
                    metrics0().onRead(true);
            }
            if (success) {
                sendTtlUpdateRequest(expiry);
                return new GridFinishedFuture<>(locVals);
            }
        } catch (IgniteCheckedException e) {
            return new GridFinishedFuture<>(e);
        }
    }
    if (expiry != null)
        expiry.reset();
    // Either reload or not all values are available locally.
    GridPartitionedGetFuture<K, V> fut = new GridPartitionedGetFuture<>(ctx, keys, !skipStore, forcePrimary, subjId, taskName, deserializeBinary, recovery, expiry, skipVals, needVer, false);
    fut.init(topVer);
    return fut;
}
Also used : CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException) GridPartitionedGetFuture(org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedGetFuture) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) GridFinishedFuture(org.apache.ignite.internal.util.future.GridFinishedFuture) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) EntryGetResult(org.apache.ignite.internal.processors.cache.EntryGetResult) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) IgniteCacheExpiryPolicy(org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Example 93 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class GridDhtAtomicCache method getAsync0.

/**
 * Entry point to all public API single get methods.
 *
 * @param key Key.
 * @param forcePrimary Force primary flag.
 * @param subjId Subject ID.
 * @param taskName Task name.
 * @param deserializeBinary Deserialize binary flag.
 * @param expiryPlc Expiry policy.
 * @param skipVals Skip values flag.
 * @param skipStore Skip store flag.
 * @param needVer Need version.
 * @return Get future.
 */
private IgniteInternalFuture<V> getAsync0(KeyCacheObject key, boolean forcePrimary, UUID subjId, String taskName, boolean deserializeBinary, boolean recovery, @Nullable ExpiryPolicy expiryPlc, boolean skipVals, boolean skipStore, boolean needVer) {
    AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
    IgniteCacheExpiryPolicy expiry = skipVals ? null : expiryPolicy(expiryPlc);
    GridPartitionedSingleGetFuture fut = new GridPartitionedSingleGetFuture(ctx, key, topVer, !skipStore, forcePrimary, subjId, taskName, deserializeBinary, expiry, skipVals, needVer, false, recovery);
    fut.init();
    return (IgniteInternalFuture<V>) fut;
}
Also used : GridPartitionedSingleGetFuture(org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteCacheExpiryPolicy(org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy)

Example 94 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class GridDhtAtomicCache method updatePartialBatch.

/**
 * @param hasNear {@code True} if originating node has near cache.
 * @param firstEntryIdx Index of the first entry in the request keys collection.
 * @param entries Entries to update.
 * @param ver Version to set.
 * @param nearNode Originating node.
 * @param writeVals Write values.
 * @param putMap Values to put.
 * @param rmvKeys Keys to remove.
 * @param entryProcessorMap Entry processors.
 * @param dhtFut DHT update future if has backups.
 * @param req Request.
 * @param res Response.
 * @param replicate Whether replication is enabled.
 * @param batchRes Batch update result.
 * @param taskName Task name.
 * @param expiry Expiry policy.
 * @param sndPrevVal If {@code true} sends previous value to backups.
 * @return Deleted entries.
 */
@SuppressWarnings("ForLoopReplaceableByForEach")
@Nullable
private GridDhtAtomicAbstractUpdateFuture updatePartialBatch(final boolean hasNear, final int firstEntryIdx, final List<GridDhtCacheEntry> entries, final GridCacheVersion ver, final ClusterNode nearNode, @Nullable final List<CacheObject> writeVals, @Nullable final Map<KeyCacheObject, CacheObject> putMap, @Nullable final Collection<KeyCacheObject> rmvKeys, @Nullable final Map<KeyCacheObject, EntryProcessor<Object, Object, Object>> entryProcessorMap, @Nullable GridDhtAtomicAbstractUpdateFuture dhtFut, final GridNearAtomicAbstractUpdateRequest req, final GridNearAtomicUpdateResponse res, final boolean replicate, final DhtAtomicUpdateResult batchRes, final String taskName, @Nullable final IgniteCacheExpiryPolicy expiry, final boolean sndPrevVal) {
    assert putMap == null ^ rmvKeys == null;
    assert req.conflictVersions() == null : "Cannot be called when there are conflict entries in the batch.";
    AffinityTopologyVersion topVer = req.topologyVersion();
    CacheStorePartialUpdateException storeErr = null;
    try {
        GridCacheOperation op;
        if (putMap != null) {
            try {
                Map<? extends KeyCacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>> view = F.viewReadOnly(putMap, new C1<CacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>>() {

                    @Override
                    public IgniteBiTuple<? extends CacheObject, GridCacheVersion> apply(CacheObject val) {
                        return F.t(val, ver);
                    }
                });
                ctx.store().putAll(null, view);
            } catch (CacheStorePartialUpdateException e) {
                storeErr = e;
            }
            op = UPDATE;
        } else {
            try {
                ctx.store().removeAll(null, rmvKeys);
            } catch (CacheStorePartialUpdateException e) {
                storeErr = e;
            }
            op = DELETE;
        }
        boolean intercept = ctx.config().getInterceptor() != null;
        AffinityAssignment affAssignment = ctx.affinity().assignment(topVer);
        // Avoid iterator creation.
        for (int i = 0; i < entries.size(); i++) {
            GridDhtCacheEntry entry = entries.get(i);
            assert entry.lockedByCurrentThread();
            if (entry.obsolete()) {
                assert req.operation() == DELETE : "Entry can become obsolete only after remove: " + entry;
                continue;
            }
            if (storeErr != null && storeErr.failedKeys().contains(entry.key().value(ctx.cacheObjectContext(), false)))
                continue;
            try {
                // We are holding java-level locks on entries at this point.
                CacheObject writeVal = op == UPDATE ? writeVals.get(i) : null;
                assert writeVal != null || op == DELETE : "null write value found.";
                // Get readers before innerUpdate (reader cleared after remove).
                GridDhtCacheEntry.ReaderId[] readers = entry.readersLocked();
                GridCacheUpdateAtomicResult updRes = entry.innerUpdate(ver, nearNode.id(), locNodeId, op, writeVal, null, /*write-through*/
                false, /*read-through*/
                false, /*retval*/
                sndPrevVal, req.keepBinary(), expiry, /*event*/
                true, /*metrics*/
                true, /*primary*/
                true, /*verCheck*/
                false, topVer, null, replicate ? DR_PRIMARY : DR_NONE, CU.TTL_NOT_CHANGED, CU.EXPIRE_TIME_CALCULATE, null, /*conflict resolve*/
                false, /*intercept*/
                false, req.subjectId(), taskName, null, null, dhtFut);
                assert !updRes.success() || updRes.newTtl() == CU.TTL_NOT_CHANGED || expiry != null : "success=" + updRes.success() + ", newTtl=" + updRes.newTtl() + ", expiry=" + expiry;
                if (intercept) {
                    if (op == UPDATE) {
                        ctx.config().getInterceptor().onAfterPut(new CacheLazyEntry(ctx, entry.key(), updRes.newValue(), req.keepBinary()));
                    } else {
                        assert op == DELETE : op;
                        // Old value should be already loaded for 'CacheInterceptor.onBeforeRemove'.
                        ctx.config().getInterceptor().onAfterRemove(new CacheLazyEntry(ctx, entry.key(), updRes.oldValue(), req.keepBinary()));
                    }
                }
                batchRes.addDeleted(entry, updRes, entries);
                if (dhtFut != null) {
                    EntryProcessor<Object, Object, Object> entryProcessor = entryProcessorMap == null ? null : entryProcessorMap.get(entry.key());
                    dhtFut.addWriteEntry(affAssignment, entry, writeVal, entryProcessor, updRes.newTtl(), CU.EXPIRE_TIME_CALCULATE, null, sndPrevVal, updRes.oldValue(), updRes.updateCounter());
                    if (readers != null)
                        dhtFut.addNearWriteEntries(nearNode, readers, entry, writeVal, entryProcessor, updRes.newTtl(), CU.EXPIRE_TIME_CALCULATE);
                }
                if (hasNear) {
                    if (!ctx.affinity().partitionBelongs(nearNode, entry.partition(), topVer)) {
                        int idx = firstEntryIdx + i;
                        if (req.operation() == TRANSFORM) {
                            res.addNearValue(idx, writeVal, updRes.newTtl(), CU.EXPIRE_TIME_CALCULATE);
                        } else
                            res.addNearTtl(idx, updRes.newTtl(), CU.EXPIRE_TIME_CALCULATE);
                        if (writeVal != null || entry.hasValue()) {
                            IgniteInternalFuture<Boolean> f = entry.addReader(nearNode.id(), req.messageId(), topVer);
                            assert f == null : f;
                        }
                    } else if (GridDhtCacheEntry.ReaderId.contains(readers, nearNode.id())) {
                        // Reader became primary or backup.
                        entry.removeReader(nearNode.id(), req.messageId());
                    } else
                        res.addSkippedIndex(firstEntryIdx + i);
                }
            } catch (GridCacheEntryRemovedException e) {
                assert false : "Entry cannot become obsolete while holding lock.";
                e.printStackTrace();
            }
        }
    } catch (IgniteCheckedException e) {
        res.addFailedKeys(putMap != null ? putMap.keySet() : rmvKeys, e);
    }
    if (storeErr != null) {
        ArrayList<KeyCacheObject> failed = new ArrayList<>(storeErr.failedKeys().size());
        for (Object failedKey : storeErr.failedKeys()) failed.add(ctx.toCacheKeyObject(failedKey));
        res.addFailedKeys(failed, storeErr.getCause());
    }
    return dhtFut;
}
Also used : CacheLazyEntry(org.apache.ignite.internal.processors.cache.CacheLazyEntry) AffinityAssignment(org.apache.ignite.internal.processors.affinity.AffinityAssignment) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) ArrayList(java.util.ArrayList) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) GridDhtCacheEntry(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry) CacheStorePartialUpdateException(org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) GridTimeoutObject(org.apache.ignite.internal.processors.timeout.GridTimeoutObject) GridCacheOperation(org.apache.ignite.internal.processors.cache.GridCacheOperation) GridCacheUpdateAtomicResult(org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult) Nullable(org.jetbrains.annotations.Nullable)

Example 95 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class GridNearAtomicUpdateFuture method mapOnTopology.

/**
 * {@inheritDoc}
 */
@Override
protected void mapOnTopology() {
    AffinityTopologyVersion topVer;
    if (cache.topology().stopping()) {
        completeFuture(null, new CacheStoppedException(cache.name()), null);
        return;
    }
    GridDhtTopologyFuture fut = cache.topology().topologyVersionFuture();
    if (fut.isDone()) {
        Throwable err = fut.validateCache(cctx, recovery, false, null, keys);
        if (err != null) {
            completeFuture(null, err, null);
            return;
        }
        topVer = fut.topologyVersion();
    } else {
        assert !topLocked : this;
        fut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {

            @Override
            public void apply(IgniteInternalFuture<AffinityTopologyVersion> t) {
                cctx.kernalContext().closure().runLocalSafe(new Runnable() {

                    @Override
                    public void run() {
                        mapOnTopology();
                    }
                });
            }
        });
        return;
    }
    map(topVer, remapKeys);
}
Also used : GridDhtTopologyFuture(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture) CacheStoppedException(org.apache.ignite.internal.processors.cache.CacheStoppedException) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture)

Aggregations

AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)242 ClusterNode (org.apache.ignite.cluster.ClusterNode)87 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)75 ArrayList (java.util.ArrayList)60 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)46 List (java.util.List)36 UUID (java.util.UUID)35 Ignite (org.apache.ignite.Ignite)33 Map (java.util.Map)32 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)31 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)30 HashMap (java.util.HashMap)27 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)22 DiscoveryEvent (org.apache.ignite.events.DiscoveryEvent)20 IgniteKernal (org.apache.ignite.internal.IgniteKernal)20 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)20 IgniteException (org.apache.ignite.IgniteException)19 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)17 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)17 GridAffinityFunctionContextImpl (org.apache.ignite.internal.processors.affinity.GridAffinityFunctionContextImpl)15