use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.
the class GridNearTxLocal method updateExplicitVersion.
/**
* {@inheritDoc}
*/
@Override
protected void updateExplicitVersion(IgniteTxEntry txEntry, GridCacheEntryEx entry) throws GridCacheEntryRemovedException {
if (entry.detached()) {
GridCacheMvccCandidate cand = cctx.mvcc().explicitLock(threadId(), entry.txKey());
if (cand != null && !xidVersion().equals(cand.version())) {
GridCacheVersion candVer = cand.version();
txEntry.explicitVersion(candVer);
if (candVer.compareTo(minVer) < 0)
minVer = candVer;
}
} else
super.updateExplicitVersion(txEntry, entry);
}
use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.
the class GridNearTransactionalCache method unlockAll.
/**
* {@inheritDoc}
*/
@Override
public void unlockAll(Collection<? extends K> keys) {
if (keys.isEmpty())
return;
try {
GridCacheVersion ver = null;
int keyCnt = -1;
Map<ClusterNode, GridNearUnlockRequest> map = null;
Collection<KeyCacheObject> locKeys = new LinkedList<>();
for (K key : keys) {
while (true) {
KeyCacheObject cacheKey = ctx.toCacheKeyObject(key);
GridDistributedCacheEntry entry = peekExx(cacheKey);
if (entry == null)
// While.
break;
try {
GridCacheMvccCandidate cand = entry.candidate(ctx.nodeId(), Thread.currentThread().getId());
AffinityTopologyVersion topVer = AffinityTopologyVersion.NONE;
if (cand != null) {
assert cand.nearLocal() : "Got non-near-local candidate in near cache: " + cand;
ver = cand.version();
if (map == null) {
Collection<ClusterNode> affNodes = CU.affinityNodes(ctx, cand.topologyVersion());
if (F.isEmpty(affNodes))
return;
keyCnt = (int) Math.ceil((double) keys.size() / affNodes.size());
map = U.newHashMap(affNodes.size());
}
topVer = cand.topologyVersion();
// Send request to remove from remote nodes.
ClusterNode primary = ctx.affinity().primaryByKey(key, topVer);
if (primary == null) {
if (log.isDebugEnabled())
log.debug("Failed to unlock key (all partition nodes left the grid).");
break;
}
GridNearUnlockRequest req = map.get(primary);
if (req == null) {
map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt, ctx.deploymentEnabled()));
req.version(ver);
}
// Remove candidate from local node first.
GridCacheMvccCandidate rmv = entry.removeLock();
if (rmv != null) {
if (!rmv.reentry()) {
if (ver != null && !ver.equals(rmv.version()))
throw new IgniteCheckedException("Failed to unlock (if keys were locked separately, " + "then they need to be unlocked separately): " + keys);
if (!primary.isLocal()) {
assert req != null;
req.addKey(entry.key(), ctx);
} else
locKeys.add(cacheKey);
if (log.isDebugEnabled())
log.debug("Removed lock (will distribute): " + rmv);
} else if (log.isDebugEnabled())
log.debug("Current thread still owns lock (or there are no other nodes)" + " [lock=" + rmv + ", curThreadId=" + Thread.currentThread().getId() + ']');
}
}
assert !topVer.equals(AffinityTopologyVersion.NONE) || cand == null;
if (topVer.equals(AffinityTopologyVersion.NONE))
topVer = ctx.affinity().affinityTopologyVersion();
entry.touch();
break;
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Attempted to unlock removed entry (will retry): " + entry);
}
}
}
if (ver == null)
return;
for (Map.Entry<ClusterNode, GridNearUnlockRequest> mapping : map.entrySet()) {
ClusterNode n = mapping.getKey();
GridDistributedUnlockRequest req = mapping.getValue();
if (n.isLocal())
dht.removeLocks(ctx.nodeId(), req.version(), locKeys, true);
else if (!F.isEmpty(req.keys()))
// We don't wait for reply to this message.
ctx.io().send(n, req, ctx.ioPolicy());
}
} catch (IgniteCheckedException ex) {
U.error(log, "Failed to unlock the lock for keys: " + keys, ex);
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.
the class GridNearLockFuture method addEntry.
/**
* Adds entry to future.
*
* @param topVer Topology version.
* @param entry Entry to add.
* @param dhtNodeId DHT node ID.
* @return Lock candidate.
* @throws GridCacheEntryRemovedException If entry was removed.
*/
@Nullable
private GridCacheMvccCandidate addEntry(AffinityTopologyVersion topVer, GridNearCacheEntry entry, UUID dhtNodeId) throws GridCacheEntryRemovedException {
assert Thread.holdsLock(this);
// Check if lock acquisition is timed out.
if (timedOut)
return null;
// Add local lock first, as it may throw GridCacheEntryRemovedException.
GridCacheMvccCandidate c = entry.addNearLocal(dhtNodeId, threadId, lockVer, topVer, timeout, !inTx(), inTx(), implicitSingleTx(), false);
if (inTx()) {
IgniteTxEntry txEntry = tx.entry(entry.txKey());
txEntry.cached(entry);
}
entries.add(entry);
if (c == null && timeout < 0) {
if (log.isDebugEnabled())
log.debug("Failed to acquire lock with negative timeout: " + entry);
onFailed(false);
return null;
}
// Double check if lock acquisition has already timed out.
if (timedOut) {
entry.removeLock(lockVer);
return null;
}
return c;
}
use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.
the class GridNearCacheEntry method removeLock.
/**
* Unlocks local lock.
*
* @return Removed candidate, or <tt>null</tt> if thread still holds the lock.
*/
@Nullable
@Override
public GridCacheMvccCandidate removeLock() {
CacheLockCandidates prev = null;
CacheLockCandidates owner = null;
CacheObject val;
UUID locId = cctx.nodeId();
GridCacheMvccCandidate cand = null;
lockEntry();
try {
GridCacheMvcc mvcc = mvccExtras();
if (mvcc != null) {
prev = mvcc.allOwners();
boolean emptyBefore = mvcc.isEmpty();
cand = mvcc.localCandidate(locId, Thread.currentThread().getId());
assert cand == null || cand.nearLocal();
if (cand != null && cand.owner()) {
// If a reentry, then release reentry. Otherwise, remove lock.
GridCacheMvccCandidate reentry = cand.unenter();
if (reentry != null) {
assert reentry.reentry();
return reentry;
}
mvcc.remove(cand.version());
owner = mvcc.allOwners();
} else
return null;
boolean emptyAfter = mvcc.isEmpty();
checkCallbacks(emptyBefore, emptyAfter);
if (emptyAfter)
mvccExtras(null);
}
val = this.val;
} finally {
unlockEntry();
}
assert cand != null;
assert owner != prev;
if (log.isDebugEnabled())
log.debug("Released local candidate from entry [owner=" + owner + ", prev=" + prev + ", entry=" + this + ']');
cctx.mvcc().removeExplicitLock(cand);
checkThreadChain(cand);
// This call must be outside of synchronization.
checkOwnerChanged(prev, owner, val);
return cand;
}
use of org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate in project ignite by apache.
the class GridHashMapLoadTest method testMapEntry.
/**
* @throws Exception If failed.
*/
@Test
public void testMapEntry() throws Exception {
Map<Integer, GridCacheMapEntry> map = new HashMap<>(5 * 1024 * 1024);
int i = 0;
GridCacheTestContext<Integer, Integer> ctx = new GridCacheTestContext<>(new GridTestKernalContext(new GridTestLog4jLogger()));
while (true) {
Integer key = i++;
map.put(key, new GridCacheMapEntry(ctx, ctx.toCacheKeyObject(key)) {
@Override
public boolean tmLock(IgniteInternalTx tx, long timeout, @Nullable GridCacheVersion serOrder, GridCacheVersion serReadVer, boolean read) {
return false;
}
@Override
protected void checkThreadChain(GridCacheMvccCandidate owner) {
// No-op.
}
@Override
public void txUnlock(IgniteInternalTx tx) {
// No-op.
}
@Override
public boolean removeLock(GridCacheVersion ver) {
return false;
}
});
if (i % 100000 == 0)
info("Inserted objects: " + i / 2);
}
}
Aggregations