Search in sources :

Example 6 with CacheDataRowAdapter

use of org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter in project ignite by apache.

the class GridCacheMapEntry method innerUpdate.

/**
 * {@inheritDoc}
 */
@SuppressWarnings("unchecked")
@Override
public GridCacheUpdateAtomicResult innerUpdate(final GridCacheVersion newVer, final UUID evtNodeId, final UUID affNodeId, final GridCacheOperation op, @Nullable final Object writeObj, @Nullable final Object[] invokeArgs, final boolean writeThrough, final boolean readThrough, final boolean retval, final boolean keepBinary, @Nullable final IgniteCacheExpiryPolicy expiryPlc, final boolean evt, final boolean metrics, final boolean primary, final boolean verCheck, final AffinityTopologyVersion topVer, @Nullable final CacheEntryPredicate[] filter, final GridDrType drType, final long explicitTtl, final long explicitExpireTime, @Nullable final GridCacheVersion conflictVer, final boolean conflictResolve, final boolean intercept, final String taskName, @Nullable final CacheObject prevVal, @Nullable final Long updateCntr, @Nullable final GridDhtAtomicAbstractUpdateFuture fut, boolean transformOp) throws IgniteCheckedException, GridCacheEntryRemovedException, GridClosureException {
    assert cctx.atomic() && !detached();
    AtomicCacheUpdateClosure c;
    if (!primary && !isNear())
        ensureFreeSpace();
    lockListenerReadLock();
    lockEntry();
    try {
        checkObsolete();
        boolean internal = isInternal() || !context().userCache();
        Map<UUID, CacheContinuousQueryListener> lsnrs = cctx.continuousQueries().updateListeners(internal, false);
        boolean needVal = lsnrs != null || intercept || retval || op == GridCacheOperation.TRANSFORM || !F.isEmptyOrNulls(filter);
        // Possibly read value from store.
        boolean readFromStore = readThrough && needVal && (cctx.readThrough() && (op == GridCacheOperation.TRANSFORM || cctx.loadPreviousValue()));
        c = new AtomicCacheUpdateClosure(this, topVer, newVer, op, writeObj, invokeArgs, readFromStore, writeThrough, keepBinary, expiryPlc, primary, verCheck, filter, explicitTtl, explicitExpireTime, conflictVer, conflictResolve, intercept, updateCntr, cctx.disableTriggeringCacheInterceptorOnConflict());
        key.valueBytes(cctx.cacheObjectContext());
        if (isNear()) {
            CacheDataRow dataRow = val != null ? new CacheDataRowAdapter(key, val, ver, expireTimeExtras()) : null;
            c.call(dataRow);
        } else
            cctx.offheap().invoke(cctx, key, localPartition(), c);
        GridCacheUpdateAtomicResult updateRes = c.updateRes;
        assert updateRes != null : c;
        // We should ignore expired old row. Expired oldRow instance is needed for correct row replacement\deletion only.
        CacheObject oldVal = c.oldRow != null && !c.oldRowExpiredFlag ? c.oldRow.value() : null;
        CacheObject updateVal = null;
        GridCacheVersion updateVer = c.newVer;
        boolean updateMetrics = metrics && cctx.statisticsEnabled();
        // Apply metrics.
        if (updateMetrics && updateRes.outcome().updateReadMetrics() && needVal)
            cctx.cache().metrics0().onRead(oldVal != null);
        if (updateMetrics && INVOKE_NO_OP.equals(updateRes.outcome()) && (transformOp || updateRes.transformed()))
            cctx.cache().metrics0().onReadOnlyInvoke(oldVal != null);
        else if (updateMetrics && REMOVE_NO_VAL.equals(updateRes.outcome()) && (transformOp || updateRes.transformed()))
            cctx.cache().metrics0().onInvokeRemove(oldVal != null);
        switch(updateRes.outcome()) {
            case VERSION_CHECK_FAILED:
                {
                    if (!cctx.isNear()) {
                        CacheObject evtVal;
                        if (op == GridCacheOperation.TRANSFORM) {
                            EntryProcessor<Object, Object, ?> entryProcessor = (EntryProcessor<Object, Object, ?>) writeObj;
                            CacheInvokeEntry<Object, Object> entry = new CacheInvokeEntry<>(key, prevVal, version(), keepBinary, this);
                            IgniteThread.onEntryProcessorEntered(true);
                            try {
                                entryProcessor.process(entry, invokeArgs);
                                evtVal = entry.modified() ? cctx.toCacheObject(cctx.unwrapTemporary(entry.getValue())) : prevVal;
                            } catch (Exception ignore) {
                                evtVal = prevVal;
                            } finally {
                                IgniteThread.onEntryProcessorLeft();
                            }
                        } else
                            evtVal = (CacheObject) writeObj;
                        assert !primary && updateCntr != null;
                        onUpdateFinished(updateCntr);
                        cctx.continuousQueries().onEntryUpdated(key, evtVal, prevVal, isInternal() || !context().userCache(), partition(), primary, false, updateCntr, null, topVer);
                    }
                    return updateRes;
                }
            case CONFLICT_USE_OLD:
            case FILTER_FAILED:
            case INVOKE_NO_OP:
            case INTERCEPTOR_CANCEL:
                return updateRes;
        }
        assert updateRes.outcome() == UpdateOutcome.SUCCESS || updateRes.outcome() == UpdateOutcome.REMOVE_NO_VAL;
        CacheObject evtOld = null;
        if (evt && op == TRANSFORM && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) {
            assert writeObj instanceof EntryProcessor : writeObj;
            evtOld = cctx.unwrapTemporary(oldVal);
            Object transformClo = EntryProcessorResourceInjectorProxy.unwrap(writeObj);
            cctx.events().addEvent(partition(), key, evtNodeId, null, null, updateVer, EVT_CACHE_OBJECT_READ, evtOld, evtOld != null, evtOld, evtOld != null, transformClo.getClass().getName(), taskName, keepBinary);
        }
        if (c.op == UPDATE) {
            updateVal = val;
            assert updateVal != null : c;
            drReplicate(drType, updateVal, updateVer, topVer);
            recordNodeId(affNodeId, topVer);
            if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_PUT)) {
                if (evtOld == null)
                    evtOld = cctx.unwrapTemporary(oldVal);
                cctx.events().addEvent(partition(), key, evtNodeId, null, null, updateVer, EVT_CACHE_OBJECT_PUT, updateVal, true, evtOld, evtOld != null, null, taskName, keepBinary);
            }
        } else {
            assert c.op == DELETE : c.op;
            clearReaders();
            drReplicate(drType, null, updateVer, topVer);
            recordNodeId(affNodeId, topVer);
            if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_REMOVED)) {
                if (evtOld == null)
                    evtOld = cctx.unwrapTemporary(oldVal);
                cctx.events().addEvent(partition(), key, evtNodeId, null, null, updateVer, EVT_CACHE_OBJECT_REMOVED, null, false, evtOld, evtOld != null, null, taskName, keepBinary);
            }
        }
        if (updateRes.success())
            updateMetrics(c.op, metrics, transformOp || updateRes.transformed(), oldVal != null);
        // Continuous query filter should be perform under lock.
        if (lsnrs != null) {
            CacheObject evtVal = cctx.unwrapTemporary(updateVal);
            CacheObject evtOldVal = cctx.unwrapTemporary(oldVal);
            cctx.continuousQueries().onEntryUpdated(lsnrs, key, evtVal, evtOldVal, internal, partition(), primary, false, c.updateRes.updateCounter(), fut, topVer);
        }
        if (intercept && c.wasIntercepted) {
            assert c.op == UPDATE || c.op == DELETE : c.op;
            Cache.Entry<?, ?> entry = new CacheLazyEntry<>(cctx, key, null, c.op == UPDATE ? updateVal : oldVal, null, keepBinary, c.updateRes.updateCounter());
            if (c.op == UPDATE)
                cctx.config().getInterceptor().onAfterPut(entry);
            else
                cctx.config().getInterceptor().onAfterRemove(entry);
        }
        updatePlatformCache(c.op == UPDATE ? updateVal : null, topVer);
    } finally {
        unlockEntry();
        unlockListenerReadLock();
    }
    onUpdateFinished(c.updateRes.updateCounter());
    return c.updateRes;
}
Also used : CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteTxSerializationCheckedException(org.apache.ignite.internal.transactions.IgniteTxSerializationCheckedException) StorageException(org.apache.ignite.internal.processors.cache.persistence.StorageException) IgniteException(org.apache.ignite.IgniteException) UnregisteredClassException(org.apache.ignite.internal.UnregisteredClassException) NodeStoppingException(org.apache.ignite.internal.NodeStoppingException) UnregisteredBinaryTypeException(org.apache.ignite.internal.UnregisteredBinaryTypeException) IgniteTxDuplicateKeyCheckedException(org.apache.ignite.internal.transactions.IgniteTxDuplicateKeyCheckedException) GridClosureException(org.apache.ignite.internal.util.lang.GridClosureException) CacheContinuousQueryListener(org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryListener) GridCacheVersion(org.apache.ignite.internal.processors.cache.version.GridCacheVersion) EntryProcessor(javax.cache.processor.EntryProcessor) CacheDataRowAdapter(org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter) UUID(java.util.UUID) Cache(javax.cache.Cache) IgniteCache(org.apache.ignite.IgniteCache)

Example 7 with CacheDataRowAdapter

use of org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter in project ignite by apache.

the class PageAbstractEvictionTracker method evictDataPage.

/**
 * @param pageIdx Page index.
 * @return true if at least one data row has been evicted
 * @throws IgniteCheckedException If failed.
 */
final boolean evictDataPage(int pageIdx) throws IgniteCheckedException {
    long fakePageId = PageIdUtils.pageId(0, (byte) 0, pageIdx);
    long page = pageMem.acquirePage(0, fakePageId);
    List<CacheDataRowAdapter> rowsToEvict;
    try {
        long pageAddr = pageMem.readLockForce(0, fakePageId, page);
        try {
            if (PageIO.getType(pageAddr) != PageIO.T_DATA)
                // Can't evict: page has been recycled into non-data page.
                return false;
            DataPageIO io = DataPageIO.VERSIONS.forPage(pageAddr);
            long realPageId = PageIO.getPageId(pageAddr);
            if (!checkTouch(realPageId))
                // Can't evict: another thread concurrently invoked forgetPage()
                return false;
            rowsToEvict = io.forAllItems(pageAddr, new DataPageIO.CC<CacheDataRowAdapter>() {

                @Override
                public CacheDataRowAdapter apply(long link) throws IgniteCheckedException {
                    CacheDataRowAdapter row = new CacheDataRowAdapter(link);
                    row.initFromLink(null, sharedCtx, pageMem, CacheDataRowAdapter.RowData.KEY_ONLY, false);
                    assert row.cacheId() != 0 : "Cache ID should be stored in rows of evictable cache";
                    return row;
                }
            });
        } finally {
            pageMem.readUnlock(0, fakePageId, page);
        }
    } finally {
        pageMem.releasePage(0, fakePageId, page);
    }
    boolean evictionDone = false;
    for (CacheDataRowAdapter dataRow : rowsToEvict) {
        GridCacheContext<?, ?> cacheCtx = sharedCtx.cacheContext(dataRow.cacheId());
        if (!cacheCtx.userCache())
            continue;
        GridCacheEntryEx entryEx = cacheCtx.isNear() ? cacheCtx.near().dht().entryEx(dataRow.key()) : cacheCtx.cache().entryEx(dataRow.key());
        evictionDone |= entryEx.evictInternal(GridCacheVersionManager.EVICT_VER, null, true);
    }
    return evictionDone;
}
Also used : DataPageIO(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) CacheDataRowAdapter(org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter)

Example 8 with CacheDataRowAdapter

use of org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter in project ignite by apache.

the class CacheDataTree method compareKeys.

/**
 * @param key Key.
 * @param link Link.
 * @return Compare result.
 * @throws IgniteCheckedException If failed.
 */
private int compareKeys(KeyCacheObject key, final long link) throws IgniteCheckedException {
    byte[] bytes = key.valueBytes(grp.cacheObjectContext());
    final long pageId = pageId(link);
    final long page = acquirePage(pageId);
    try {
        // Non-empty data page must not be recycled.
        long pageAddr = readLock(pageId, page);
        assert pageAddr != 0L : link;
        try {
            DataPageIO io = DataPageIO.VERSIONS.forPage(pageAddr);
            DataPagePayload data = io.readPayload(pageAddr, itemId(link), pageSize());
            if (data.nextLink() == 0) {
                long addr = pageAddr + data.offset();
                if (grp.mvccEnabled())
                    // Skip MVCC info.
                    addr += MVCC_INFO_SIZE;
                if (grp.storeCacheIdInDataPage())
                    // Skip cache id.
                    addr += 4;
                final int len = PageUtils.getInt(addr, 0);
                int lenCmp = Integer.compare(len, bytes.length);
                if (lenCmp != 0)
                    return lenCmp;
                // Skip length and type byte.
                addr += 5;
                final int words = len / 8;
                for (int i = 0; i < words; i++) {
                    int off = i * 8;
                    long b1 = PageUtils.getLong(addr, off);
                    long b2 = GridUnsafe.getLong(bytes, GridUnsafe.BYTE_ARR_OFF + off);
                    int cmp = Long.compare(b1, b2);
                    if (cmp != 0)
                        return cmp;
                }
                for (int i = words * 8; i < len; i++) {
                    byte b1 = PageUtils.getByte(addr, i);
                    byte b2 = bytes[i];
                    if (b1 != b2)
                        return b1 > b2 ? 1 : -1;
                }
                return 0;
            }
        } finally {
            readUnlock(pageId, page, pageAddr);
        }
    } finally {
        releasePage(pageId, page);
    }
    // TODO GG-11768.
    CacheDataRowAdapter other = grp.mvccEnabled() ? new MvccDataRow(link) : new CacheDataRowAdapter(link);
    other.initFromLink(grp, CacheDataRowAdapter.RowData.KEY_ONLY);
    byte[] bytes1 = other.key().valueBytes(grp.cacheObjectContext());
    byte[] bytes2 = key.valueBytes(grp.cacheObjectContext());
    int lenCmp = Integer.compare(bytes1.length, bytes2.length);
    if (lenCmp != 0)
        return lenCmp;
    final int len = bytes1.length;
    final int words = len / 8;
    for (int i = 0; i < words; i++) {
        int off = GridUnsafe.BYTE_ARR_INT_OFF + i * 8;
        long b1 = GridUnsafe.getLong(bytes1, off);
        long b2 = GridUnsafe.getLong(bytes2, off);
        int cmp = Long.compare(b1, b2);
        if (cmp != 0)
            return cmp;
    }
    for (int i = words * 8; i < len; i++) {
        byte b1 = bytes1[i];
        byte b2 = bytes2[i];
        if (b1 != b2)
            return b1 > b2 ? 1 : -1;
    }
    return 0;
}
Also used : DataPageIO(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO) DataPagePayload(org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPagePayload) CacheDataRowAdapter(org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter) MvccDataRow(org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataRow)

Example 9 with CacheDataRowAdapter

use of org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter in project ignite by apache.

the class InlineIndexTree method createIndexRow.

/**
 * Creates an index row for this tree.
 */
public IndexRowImpl createIndexRow(long link) throws IgniteCheckedException {
    IndexRowImpl cachedRow = idxRowCache == null ? null : idxRowCache.get(link);
    if (cachedRow != null)
        return cachedRow;
    CacheDataRowAdapter row = new CacheDataRowAdapter(link);
    row.initFromLink(cacheGroupContext(), CacheDataRowAdapter.RowData.FULL, true);
    IndexRowImpl r = new IndexRowImpl(rowHandler(), row);
    if (idxRowCache != null)
        idxRowCache.put(r);
    return r;
}
Also used : IndexRowImpl(org.apache.ignite.internal.cache.query.index.sorted.IndexRowImpl) CacheDataRowAdapter(org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter)

Example 10 with CacheDataRowAdapter

use of org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter in project ignite by apache.

the class H2RowFactory method getRow.

/**
 * !!! This method must be invoked in read or write lock of referring index page. It is needed to
 * !!! make sure that row at this link will be invisible, when the link will be removed from
 * !!! from all the index pages, so that row can be safely erased from the data page.
 *
 * @param link Link.
 * @return Row.
 * @throws IgniteCheckedException If failed.
 */
public GridH2Row getRow(long link) throws IgniteCheckedException {
    // TODO Avoid extra garbage generation. In upcoming H2 1.4.193 Row will become an interface,
    // TODO we need to refactor all this to return CacheDataRowAdapter implementing Row here.
    final CacheDataRowAdapter rowBuilder = new CacheDataRowAdapter(link);
    rowBuilder.initFromLink(cctx.group(), CacheDataRowAdapter.RowData.FULL);
    GridH2Row row;
    try {
        row = rowDesc.createRow(rowBuilder);
    } catch (IgniteCheckedException e) {
        throw new IgniteException(e);
    }
    assert row.version() != null;
    return row;
}
Also used : IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) GridH2Row(org.apache.ignite.internal.processors.query.h2.opt.GridH2Row) CacheDataRowAdapter(org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter)

Aggregations

CacheDataRowAdapter (org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter)15 IgniteException (org.apache.ignite.IgniteException)5 MvccDataRow (org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataRow)5 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)4 DataPageIO (org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO)4 UUID (java.util.UUID)2 Cache (javax.cache.Cache)2 EntryProcessor (javax.cache.processor.EntryProcessor)2 IgniteCache (org.apache.ignite.IgniteCache)2 NodeStoppingException (org.apache.ignite.internal.NodeStoppingException)2 UnregisteredBinaryTypeException (org.apache.ignite.internal.UnregisteredBinaryTypeException)2 UnregisteredClassException (org.apache.ignite.internal.UnregisteredClassException)2 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)2 GridCacheEntryEx (org.apache.ignite.internal.processors.cache.GridCacheEntryEx)2 CacheDataRow (org.apache.ignite.internal.processors.cache.persistence.CacheDataRow)2 StorageException (org.apache.ignite.internal.processors.cache.persistence.StorageException)2 DataPagePayload (org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPagePayload)2 CacheContinuousQueryListener (org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryListener)2 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)2 IgniteTxDuplicateKeyCheckedException (org.apache.ignite.internal.transactions.IgniteTxDuplicateKeyCheckedException)2