use of org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter in project gridgain by gridgain.
the class H2CacheRow method getMemory.
/**
* {@inheritDoc}
*/
@Override
public int getMemory() {
if (memory != MEMORY_CALCULATE)
return memory;
long size = 32;
if (!F.isEmpty(valCache)) {
int len = valCache.length;
size += Constants.MEMORY_ARRAY + len * Constants.MEMORY_POINTER;
for (Value v : valCache) {
if (v != null)
size += v.getMemory();
}
}
assert row instanceof CacheDataRowAdapter;
assert row.key() instanceof KeyCacheObjectImpl;
assert row.value() instanceof BinaryObjectImpl;
try {
// CacheDataRow =49, DataRow =57, MvccDataRow =100
size += 56;
/* CacheDataRowAdapter */
size += 32 + /* KeyCacheObjectImpl */
Constants.MEMORY_ARRAY + row.key().valueBytesLength(null);
size += 40 + /* BinaryObjectImpl */
Constants.MEMORY_ARRAY + ((BinaryObjectImpl) row.value()).array().length;
} catch (IgniteCheckedException e) {
U.warn(desc.context().logger(H2CacheRow.class), e);
}
assert size < Integer.MAX_VALUE;
memory = (int) size;
return memory;
}
use of org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter in project gridgain by gridgain.
the class UpgradePendingTreeToPerPartitionTask method getEntry.
/**
* Return CacheEntry instance for lock purpose.
*
* @param grp Cache group
* @param row Pending row.
* @return CacheEntry if found or null otherwise.
*/
private GridCacheEntryEx getEntry(CacheGroupContext grp, PendingRow row) {
try {
CacheDataRowAdapter rowData = new CacheDataRowAdapter(row.link);
rowData.initFromLink(grp, CacheDataRowAdapter.RowData.KEY_ONLY);
GridCacheContext cctx = grp.shared().cacheContext(row.cacheId);
assert cctx != null;
return cctx.cache().entryEx(rowData.key());
} catch (Throwable ex) {
if (Thread.currentThread().isInterrupted() || X.hasCause(ex, InterruptedException.class))
throw new IgniteException(new InterruptedException());
log.warning("Failed to move old-version pending entry " + "to per-partition PendingTree: key not found (skipping): " + "[grpId=" + grp.groupId() + ", grpName=" + grp.name() + ", pendingRow=" + row + "]");
return null;
}
}
use of org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter in project gridgain by gridgain.
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;
byte type = PageUtils.getByte(addr, 4);
if (type != CacheObject.TYPE_BINARY_COMPRESSED) {
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 gridgain by gridgain.
the class PendingRow method initKey.
/**
* @param grp Cache group.
* @return Row.
* @throws IgniteCheckedException If failed.
*/
PendingRow initKey(CacheGroupContext grp) throws IgniteCheckedException {
CacheDataRowAdapter rowData = grp.mvccEnabled() ? new MvccDataRow(link) : new CacheDataRowAdapter(link);
rowData.initFromLink(grp, CacheDataRowAdapter.RowData.KEY_ONLY);
key = rowData.key();
return this;
}
use of org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter in project gridgain by gridgain.
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, @Nullable final UUID subjId, 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();
boolean reserved = false;
try {
checkObsolete();
GridDhtLocalPartition locPart = localPartition();
// Reserve before update to avoid writing to evicting partition.
if (locPart != null && !(reserved = locPart.reserve()))
throw new GridDhtInvalidPartitionException(partition(), "The partition can't be reserved");
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, new GridCacheVersion(newVer), op, writeObj, invokeArgs, readFromStore, writeThrough, keepBinary, expiryPlc, primary, verCheck, filter, explicitTtl, explicitExpireTime, conflictVer, conflictResolve, intercept, updateCntr, cctx.disableTriggeringCacheInterceptorOnConflict());
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 or tombstone.
// Expired oldRow instance is needed for correct row replacement or deletion only.
CacheObject oldVal = c.oldRow != null && !c.ignoreOldValue ? 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 == updateRes.outcome() && (transformOp || updateRes.transformed()))
cctx.cache().metrics0().onReadOnlyInvoke(oldVal != null);
else if (updateMetrics && REMOVE_NO_VAL == 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, subjId, 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, subjId, 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, subjId, 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 {
if (reserved)
localPartition().release();
unlockEntry();
unlockListenerReadLock();
}
onUpdateFinished(c.updateRes.updateCounter());
return c.updateRes;
}
Aggregations