use of org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer 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;
}
use of org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer 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;
}
use of org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer in project ignite by apache.
the class GridCacheMapEntry method mvccPreloadEntry.
/**
* {@inheritDoc}
*/
@Override
public boolean mvccPreloadEntry(List<GridCacheMvccEntryInfo> entryHist) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert !entryHist.isEmpty();
WALPointer logPtr = null;
ensureFreeSpace();
boolean updated = false;
lockEntry();
try {
checkObsolete();
key.valueBytes(cctx.cacheObjectContext());
if (cctx.offheap().mvccApplyHistoryIfAbsent(this, entryHist)) {
updated = true;
if (!cctx.isNear() && cctx.group().persistenceEnabled() && cctx.group().walEnabled()) {
MvccDataRecord rec;
if (entryHist.size() == 1) {
GridCacheMvccEntryInfo info = entryHist.get(0);
rec = new MvccDataRecord(toMvccDataEntry(info, null));
} else {
// Batched WAL update.
List<DataEntry> dataEntries = new ArrayList<>(entryHist.size());
for (GridCacheMvccEntryInfo info : entryHist) dataEntries.add(toMvccDataEntry(info, null));
rec = new MvccDataRecord(dataEntries);
}
logPtr = cctx.shared().wal().log(rec);
}
}
} finally {
if (lockedByCurrentThread()) {
unlockEntry();
cctx.evicts().touch(this);
}
}
if (logPtr != null)
cctx.shared().wal().flush(logPtr, false);
return updated;
}
use of org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer in project ignite by apache.
the class GridCacheMapEntry method mvccUpdateRowsWithPreloadInfo.
/**
* {@inheritDoc}
*/
@Override
public GridCacheUpdateTxResult mvccUpdateRowsWithPreloadInfo(IgniteInternalTx tx, UUID affNodeId, AffinityTopologyVersion topVer, List<GridCacheEntryInfo> entries, GridCacheOperation op, MvccSnapshot mvccVer, IgniteUuid futId, int batchNum) throws IgniteCheckedException, GridCacheEntryRemovedException {
assert mvccVer != null && MvccUtils.mvccVersionIsValid(mvccVer.coordinatorVersion(), mvccVer.counter(), mvccVer.operationCounter());
assert !F.isEmpty(entries);
WALPointer logPtr = null;
ensureFreeSpace();
CacheObject val = null;
CacheObject oldVal = null;
lockEntry();
try {
checkObsolete();
boolean walEnabled = cctx.group().persistenceEnabled() && cctx.group().walEnabled();
List<DataEntry> walEntries = walEnabled ? new ArrayList<>(entries.size() + 1) : Collections.EMPTY_LIST;
// or via rebalance.
for (int i = 0; i < entries.size(); i++) {
GridCacheMvccEntryInfo info = (GridCacheMvccEntryInfo) entries.get(i);
assert info.mvccTxState() == TxState.COMMITTED || MvccUtils.compare(info, mvccVer.coordinatorVersion(), mvccVer.counter()) == 0;
assert info.newMvccTxState() == TxState.COMMITTED || MvccUtils.compareNewVersion(info, mvccVer.coordinatorVersion(), mvccVer.counter()) == 0 || info.newMvccCoordinatorVersion() == MvccUtils.MVCC_CRD_COUNTER_NA;
boolean added = cctx.offheap().mvccUpdateRowWithPreloadInfo(this, info.value(), info.version(), info.expireTime(), info.mvccVersion(), info.newMvccVersion(), info.mvccTxState(), info.newMvccTxState());
if (walEnabled)
walEntries.add(toMvccDataEntry(info, tx));
if (oldVal == null && MvccUtils.compare(info.mvccVersion(), mvccVer.coordinatorVersion(), mvccVer.counter()) != 0 && MvccUtils.compareNewVersion(info, mvccVer.coordinatorVersion(), mvccVer.counter()) == 0)
// Old means a value before current transaction.
oldVal = info.value();
if (!added)
break;
}
GridCacheMvccEntryInfo last = (GridCacheMvccEntryInfo) entries.get(0);
if (walEnabled)
Collections.reverse(walEntries);
if (op == DELETE) {
assert MvccUtils.compareNewVersion(last, mvccVer) == 0;
if (walEnabled)
walEntries.add(new MvccDataEntry(cctx.cacheId(), key, null, DELETE, tx.nearXidVersion(), last.version(), last.expireTime(), key.partition(), 0, last.mvccVersion()));
} else {
assert last.newMvccCoordinatorVersion() == MvccUtils.MVCC_CRD_COUNTER_NA;
assert MvccUtils.compare(last, mvccVer) == 0;
val = last.value();
}
if (walEnabled)
logPtr = cctx.shared().wal().log(new MvccDataRecord(walEntries));
} finally {
if (lockedByCurrentThread()) {
unlockEntry();
cctx.evicts().touch(this);
}
}
GridCacheUpdateTxResult res = new GridCacheUpdateTxResult(true, logPtr);
res.newValue(val);
res.oldValue(oldVal);
return res;
}
use of org.apache.ignite.internal.processors.cache.persistence.wal.WALPointer in project ignite by apache.
the class MetaStorage method writeRaw.
/**
* {@inheritDoc}
*/
@Override
public void writeRaw(String key, byte[] data) throws IgniteCheckedException {
if (!readOnly) {
WALPointer ptr;
synchronized (this) {
ptr = wal.log(new MetastoreDataRecord(key, data));
MetastorageDataRow oldRow = tree.findOne(new MetastorageSearchRow(key));
byte[] keyBytes = key.getBytes();
long keyLink;
if (oldRow != null)
keyLink = oldRow.keyLink();
else if (keyBytes.length > MetastorageTree.MAX_KEY_LEN)
keyLink = tree.rowStore().addRow(keyBytes);
else
keyLink = 0L;
long dataLink = tree.rowStore().addRow(data);
tree.put(new MetastorageDataRow(dataLink, key, keyLink));
if (oldRow != null)
tree.rowStore().removeRow(oldRow.link());
}
wal.flush(ptr, false);
}
}
Aggregations