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;
}
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;
}
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;
}
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;
}
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;
}
Aggregations