Search in sources :

Example 1 with MvccUpdateResult

use of org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccUpdateResult in project ignite by apache.

the class GridCacheMapEntry method mvccLock.

/**
 * {@inheritDoc}
 */
@Override
public GridCacheUpdateTxResult mvccLock(GridDhtTxLocalAdapter tx, MvccSnapshot mvccVer) throws GridCacheEntryRemovedException, IgniteCheckedException {
    assert tx != null;
    assert mvccVer != null;
    final boolean valid = valid(tx.topologyVersion());
    final GridCacheVersion newVer;
    WALPointer logPtr = null;
    lockEntry();
    try {
        checkObsolete();
        newVer = tx.writeVersion();
        assert newVer != null : "Failed to get write version for tx: " + tx;
        assert tx.local();
        MvccUpdateResult res = cctx.offheap().mvccLock(this, mvccVer);
        assert res != null;
        if (res.resultType() == ResultType.VERSION_MISMATCH)
            throw serializationError();
        else if (res.resultType() == ResultType.LOCKED) {
            unlockEntry();
            MvccVersion lockVer = res.resultVersion();
            GridFutureAdapter<GridCacheUpdateTxResult> resFut = new GridFutureAdapter<>();
            IgniteInternalFuture<?> lockFut = cctx.kernalContext().coordinators().waitForLock(cctx, mvccVer, lockVer);
            lockFut.listen(new MvccAcquireLockListener(tx, this, mvccVer, resFut));
            return new GridCacheUpdateTxResult(false, resFut);
        }
    } finally {
        if (lockedByCurrentThread()) {
            unlockEntry();
            cctx.evicts().touch(this);
        }
    }
    onUpdateFinished(0L);
    return new GridCacheUpdateTxResult(valid, logPtr);
}
Also used : GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) MvccVersion(org.apache.ignite.internal.processors.cache.mvcc.MvccVersion) MvccUpdateResult(org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccUpdateResult) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) WALPointer(org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer)

Example 2 with MvccUpdateResult

use of org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccUpdateResult in project ignite by apache.

the class GridCacheMapEntry method mvccRemove.

/**
 * {@inheritDoc}
 */
@Override
public final GridCacheUpdateTxResult mvccRemove(IgniteInternalTx tx, UUID affNodeId, AffinityTopologyVersion topVer, MvccSnapshot mvccVer, boolean needHistory, boolean needOldVal, @Nullable CacheEntryPredicate filter, boolean retVal) throws IgniteCheckedException, GridCacheEntryRemovedException {
    assert tx != null;
    assert mvccVer != null;
    final boolean valid = valid(tx.topologyVersion());
    final GridCacheVersion newVer;
    WALPointer logPtr = null;
    lockEntry();
    MvccUpdateResult res;
    try {
        checkObsolete();
        newVer = tx.writeVersion();
        assert newVer != null : "Failed to get write version for tx: " + tx;
        res = cctx.offheap().mvccRemove(this, mvccVer, tx.local(), needHistory, needOldVal, filter, retVal);
        assert res != null;
        if (res.resultType() == ResultType.VERSION_MISMATCH)
            throw serializationError();
        else if (res.resultType() == ResultType.PREV_NULL)
            return new GridCacheUpdateTxResult(false);
        else if (res.resultType() == ResultType.FILTERED) {
            GridCacheUpdateTxResult updRes = new GridCacheUpdateTxResult(false);
            updRes.filtered(true);
            return updRes;
        } else if (res.resultType() == ResultType.LOCKED) {
            unlockEntry();
            MvccVersion lockVer = res.resultVersion();
            GridFutureAdapter<GridCacheUpdateTxResult> resFut = new GridFutureAdapter<>();
            IgniteInternalFuture<?> lockFut = cctx.kernalContext().coordinators().waitForLock(cctx, mvccVer, lockVer);
            lockFut.listen(new MvccRemoveLockListener(tx, this, affNodeId, topVer, mvccVer, needHistory, resFut, needOldVal, retVal, filter));
            return new GridCacheUpdateTxResult(false, resFut);
        }
        if (cctx.deferredDelete() && deletedUnlocked() && !detached())
            deletedUnlocked(false);
        if (res.resultType() == ResultType.PREV_NOT_NULL) {
            TxCounters counters = tx.txCounters(true);
            if (compareIgnoreOpCounter(res.resultVersion(), mvccVer) == 0) {
                if (// Do not count own update removal.
                res.isKeyAbsentBefore())
                    counters.decrementUpdateCounter(cctx.cacheId(), partition());
            } else
                counters.incrementUpdateCounter(cctx.cacheId(), partition());
            counters.accumulateSizeDelta(cctx.cacheId(), partition(), -1);
        }
        if (cctx.group().persistenceEnabled() && cctx.group().walEnabled())
            logPtr = logMvccUpdate(tx, null, 0, 0L, mvccVer);
        update(null, 0, 0, newVer, true);
        recordNodeId(affNodeId, topVer);
    } finally {
        if (lockedByCurrentThread()) {
            unlockEntry();
            cctx.evicts().touch(this);
        }
    }
    onUpdateFinished(0L);
    GridCacheUpdateTxResult updRes = valid ? new GridCacheUpdateTxResult(true, 0L, logPtr) : new GridCacheUpdateTxResult(false, logPtr);
    if (retVal && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.VERSION_FOUND))
        updRes.prevValue(res.oldValue());
    if (needOldVal && compareIgnoreOpCounter(res.resultVersion(), mvccVer) != 0 && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.REMOVED_NOT_NULL))
        updRes.oldValue(res.oldValue());
    updRes.mvccHistory(res.history());
    return updRes;
}
Also used : TxCounters(org.apache.ignite.internal.processors.cache.transactions.TxCounters) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) MvccVersion(org.apache.ignite.internal.processors.cache.mvcc.MvccVersion) MvccUpdateResult(org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccUpdateResult) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) WALPointer(org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer)

Example 3 with MvccUpdateResult

use of org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccUpdateResult in project ignite by apache.

the class GridCacheMapEntry method mvccSet.

/**
 * {@inheritDoc}
 */
@Override
public final GridCacheUpdateTxResult mvccSet(IgniteInternalTx tx, UUID affNodeId, CacheObject val, EntryProcessor entryProc, Object[] invokeArgs, long ttl0, AffinityTopologyVersion topVer, MvccSnapshot mvccVer, GridCacheOperation op, boolean needHistory, boolean noCreate, boolean needOldVal, CacheEntryPredicate filter, boolean retVal, boolean keepBinary) throws IgniteCheckedException, GridCacheEntryRemovedException {
    assert tx != null;
    final boolean valid = valid(tx.topologyVersion());
    final boolean invoke = entryProc != null;
    final GridCacheVersion newVer;
    WALPointer logPtr = null;
    ensureFreeSpace();
    lockEntry();
    MvccUpdateResult res;
    try {
        checkObsolete();
        newVer = tx.writeVersion();
        assert newVer != null : "Failed to get write version for tx: " + tx;
        // Determine new ttl and expire time.
        long expireTime, ttl = ttl0;
        if (ttl == -1L) {
            ttl = ttlExtras();
            expireTime = expireTimeExtras();
        } else
            expireTime = CU.toExpireTime(ttl);
        assert ttl >= 0 : ttl;
        assert expireTime >= 0 : expireTime;
        // Detach value before index update.
        val = cctx.kernalContext().cacheObjects().prepareForCache(val, cctx);
        assert val != null || invoke;
        res = cctx.offheap().mvccUpdate(this, val, newVer, expireTime, mvccVer, tx.local(), needHistory, noCreate, needOldVal, filter, retVal, keepBinary, entryProc, invokeArgs);
        assert res != null;
        // updating the key which just has been rebalanced.
        assert res.resultType() != ResultType.VERSION_FOUND || op == CREATE && tx.local() || !tx.local();
        // PREV_NOT_NULL on CREATE is possible only on primary.
        assert res.resultType() != ResultType.PREV_NOT_NULL || op != CREATE || tx.local();
        if (res.resultType() == ResultType.VERSION_MISMATCH)
            throw serializationError();
        else if (res.resultType() == ResultType.FILTERED) {
            GridCacheUpdateTxResult updRes = new GridCacheUpdateTxResult(invoke);
            assert !invoke || res.invokeResult() != null;
            if (// No-op invoke happened.
            invoke)
                updRes.invokeResult(res.invokeResult());
            updRes.filtered(true);
            if (retVal)
                updRes.prevValue(res.oldValue());
            return updRes;
        } else if (noCreate && !invoke && res.resultType() == ResultType.PREV_NULL)
            return new GridCacheUpdateTxResult(false);
        else if (res.resultType() == ResultType.LOCKED) {
            unlockEntry();
            MvccVersion lockVer = res.resultVersion();
            GridFutureAdapter<GridCacheUpdateTxResult> resFut = new GridFutureAdapter<>();
            IgniteInternalFuture<?> lockFut = cctx.kernalContext().coordinators().waitForLock(cctx, mvccVer, lockVer);
            lockFut.listen(new MvccUpdateLockListener(tx, this, affNodeId, topVer, val, ttl0, mvccVer, op, needHistory, noCreate, resFut, needOldVal, filter, retVal, keepBinary, entryProc, invokeArgs));
            return new GridCacheUpdateTxResult(false, resFut);
        } else if (op == CREATE && tx.local() && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.VERSION_FOUND))
            throw new IgniteTxDuplicateKeyCheckedException("Duplicate key during INSERT [key=" + key + ']');
        if (cctx.deferredDelete() && deletedUnlocked() && !detached())
            deletedUnlocked(false);
        if (res.resultType() == ResultType.PREV_NULL) {
            TxCounters counters = tx.txCounters(true);
            if (compareIgnoreOpCounter(res.resultVersion(), mvccVer) == 0) {
                if (res.isKeyAbsentBefore())
                    counters.incrementUpdateCounter(cctx.cacheId(), partition());
            } else
                counters.incrementUpdateCounter(cctx.cacheId(), partition());
            counters.accumulateSizeDelta(cctx.cacheId(), partition(), 1);
        } else if (res.resultType() == ResultType.PREV_NOT_NULL && compareIgnoreOpCounter(res.resultVersion(), mvccVer) != 0) {
            TxCounters counters = tx.txCounters(true);
            counters.incrementUpdateCounter(cctx.cacheId(), partition());
        } else if (res.resultType() == ResultType.REMOVED_NOT_NULL) {
            TxCounters counters = tx.txCounters(true);
            if (compareIgnoreOpCounter(res.resultVersion(), mvccVer) == 0) {
                if (// Do not count own update removal.
                res.isKeyAbsentBefore())
                    counters.decrementUpdateCounter(cctx.cacheId(), partition());
            } else
                counters.incrementUpdateCounter(cctx.cacheId(), partition());
            counters.accumulateSizeDelta(cctx.cacheId(), partition(), -1);
        }
        if (cctx.group().persistenceEnabled() && cctx.group().walEnabled()) {
            logPtr = cctx.shared().wal().log(new MvccDataRecord(new MvccDataEntry(cctx.cacheId(), key, val, res.resultType() == ResultType.PREV_NULL ? CREATE : (res.resultType() == ResultType.REMOVED_NOT_NULL) ? DELETE : UPDATE, tx.nearXidVersion(), newVer, expireTime, key.partition(), 0L, mvccVer)));
        }
        update(val, expireTime, ttl, newVer, true);
        recordNodeId(affNodeId, topVer);
    } finally {
        if (lockedByCurrentThread()) {
            unlockEntry();
            cctx.evicts().touch(this);
        }
    }
    onUpdateFinished(0L);
    GridCacheUpdateTxResult updRes = valid ? new GridCacheUpdateTxResult(true, 0L, logPtr) : new GridCacheUpdateTxResult(false, logPtr);
    if (retVal && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.VERSION_FOUND))
        updRes.prevValue(res.oldValue());
    if (needOldVal && compareIgnoreOpCounter(res.resultVersion(), mvccVer) != 0 && (res.resultType() == ResultType.PREV_NOT_NULL || res.resultType() == ResultType.REMOVED_NOT_NULL))
        updRes.oldValue(res.oldValue());
    updRes.newValue(res.newValue());
    if (invoke && res.resultType() != ResultType.VERSION_FOUND) {
        assert res.invokeResult() != null;
        updRes.invokeResult(res.invokeResult());
    }
    updRes.mvccHistory(res.history());
    return updRes;
}
Also used : TxCounters(org.apache.ignite.internal.processors.cache.transactions.TxCounters) MvccUpdateResult(org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccUpdateResult) MvccDataEntry(org.apache.ignite.internal.pagemem.wal.record.MvccDataEntry) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteTxDuplicateKeyCheckedException(org.apache.ignite.internal.transactions.IgniteTxDuplicateKeyCheckedException) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) MvccVersion(org.apache.ignite.internal.processors.cache.mvcc.MvccVersion) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) MvccDataRecord(org.apache.ignite.internal.pagemem.wal.record.MvccDataRecord) WALPointer(org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer)

Aggregations

IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)3 MvccVersion (org.apache.ignite.internal.processors.cache.mvcc.MvccVersion)3 WALPointer (org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer)3 MvccUpdateResult (org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccUpdateResult)3 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)3 GridFutureAdapter (org.apache.ignite.internal.util.future.GridFutureAdapter)3 TxCounters (org.apache.ignite.internal.processors.cache.transactions.TxCounters)2 MvccDataEntry (org.apache.ignite.internal.pagemem.wal.record.MvccDataEntry)1 MvccDataRecord (org.apache.ignite.internal.pagemem.wal.record.MvccDataRecord)1 IgniteTxDuplicateKeyCheckedException (org.apache.ignite.internal.transactions.IgniteTxDuplicateKeyCheckedException)1