use of org.apache.ignite.internal.processors.cache.CacheObject in project ignite by apache.
the class GridNearGetFuture method loadEntries.
/**
* @param nodeId Node id.
* @param keys Keys.
* @param infos Entry infos.
* @param savedEntries Saved entries.
* @param topVer Topology version
* @return Result map.
*/
private Map<K, V> loadEntries(UUID nodeId, Collection<KeyCacheObject> keys, Collection<GridCacheEntryInfo> infos, Map<KeyCacheObject, GridNearCacheEntry> savedEntries, AffinityTopologyVersion topVer) {
boolean empty = F.isEmpty(keys);
Map<K, V> map = empty ? Collections.<K, V>emptyMap() : new GridLeanMap<K, V>(keys.size());
if (!empty) {
boolean atomic = cctx.atomic();
GridCacheVersion ver = atomic ? null : F.isEmpty(infos) ? null : cctx.versions().next();
for (GridCacheEntryInfo info : infos) {
try {
info.unmarshalValue(cctx, cctx.deploy().globalLoader());
// Entries available locally in DHT should not be loaded into near cache for reading.
if (!cctx.affinity().keyLocalNode(info.key(), cctx.affinity().affinityTopologyVersion())) {
GridNearCacheEntry entry = savedEntries.get(info.key());
if (entry == null)
entry = cache().entryExx(info.key(), topVer);
// Load entry into cache.
entry.loadedValue(tx, nodeId, info.value(), atomic ? info.version() : ver, info.version(), info.ttl(), info.expireTime(), true, !deserializeBinary, topVer, subjId);
}
CacheObject val = info.value();
KeyCacheObject key = info.key();
assert skipVals == (info.value() == null);
cctx.addResult(map, key, val, skipVals, keepCacheObjects, deserializeBinary, false, needVer ? info.version() : null, 0, 0);
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed entry while processing get response (will not retry).");
} catch (Exception e) {
// Fail.
onDone(e);
return Collections.emptyMap();
}
}
}
return map;
}
use of org.apache.ignite.internal.processors.cache.CacheObject 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;
synchronized (this) {
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;
}
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.CacheObject in project ignite by apache.
the class GridNearGetFuture method localDhtGet.
/**
* @param key Key.
* @param part Partition.
* @param topVer Topology version.
* @param nearRead {@code True} if already tried to read from near cache.
* @return {@code True} if there is no need to further search value.
*/
private boolean localDhtGet(KeyCacheObject key, int part, AffinityTopologyVersion topVer, boolean nearRead) {
GridDhtCacheAdapter<K, V> dht = cache().dht();
assert dht.context().affinityNode() : this;
while (true) {
GridCacheEntryEx dhtEntry = null;
try {
dhtEntry = dht.entryEx(key);
CacheObject v = null;
// If near cache does not have value, then we peek DHT cache.
if (dhtEntry != null) {
boolean isNew = dhtEntry.isNewLocked() || !dhtEntry.valid(topVer);
if (needVer) {
EntryGetResult res = dhtEntry.innerGetVersioned(null, null, /**update-metrics*/
false, /*event*/
!nearRead && !skipVals, subjId, null, taskName, expiryPlc, !deserializeBinary, null);
if (res != null) {
v = res.value();
ver = res.version();
}
} else {
v = dhtEntry.innerGet(null, tx, /*read-through*/
false, /*update-metrics*/
false, /*events*/
!nearRead && !skipVals, subjId, null, taskName, expiryPlc, !deserializeBinary);
}
// Entry was not in memory or in swap, so we remove it from cache.
if (v == null && isNew && dhtEntry.markObsoleteIfEmpty(ver))
dht.removeEntry(dhtEntry);
}
if (v != null) {
if (cctx.cache().configuration().isStatisticsEnabled() && !skipVals)
cache().metrics0().onRead(true);
addResult(key, v, ver);
return true;
} else {
boolean topStable = cctx.isReplicated() || topVer.equals(cctx.topology().topologyVersion());
// Entry not found, do not continue search if topology did not change and there is no store.
return !cctx.readThroughConfigured() && (topStable || partitionOwned(part));
}
} catch (GridCacheEntryRemovedException ignored) {
// Retry.
} catch (GridDhtInvalidPartitionException ignored) {
return false;
} catch (IgniteCheckedException e) {
onDone(e);
return false;
} finally {
if (dhtEntry != null)
// Near cache is enabled, so near entry will be enlisted in the transaction.
// Always touch DHT entry in this case.
dht.context().evicts().touch(dhtEntry, topVer);
}
}
}
use of org.apache.ignite.internal.processors.cache.CacheObject in project ignite by apache.
the class GridNearGetFuture method map.
/**
* @param mappings Mappings.
* @param key Key to map.
* @param topVer Topology version
* @param mapped Previously mapped.
* @param saved Reserved near cache entries.
* @return Map.
*/
@SuppressWarnings("unchecked")
private Map<KeyCacheObject, GridNearCacheEntry> map(KeyCacheObject key, Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings, AffinityTopologyVersion topVer, Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mapped, Map<KeyCacheObject, GridNearCacheEntry> saved) {
int part = cctx.affinity().partition(key);
List<ClusterNode> affNodes = cctx.affinity().nodesByPartition(part, topVer);
if (affNodes.isEmpty()) {
onDone(serverNotFoundError(topVer));
return null;
}
final GridNearCacheAdapter near = cache();
// Allow to get cached value from the local node.
boolean allowLocRead = !forcePrimary || cctx.localNode().equals(affNodes.get(0));
while (true) {
GridNearCacheEntry entry = allowLocRead ? (GridNearCacheEntry) near.peekEx(key) : null;
try {
CacheObject v = null;
GridCacheVersion ver = null;
boolean isNear = entry != null;
// First we peek into near cache.
if (isNear) {
if (needVer) {
EntryGetResult res = entry.innerGetVersioned(null, null, /**update-metrics*/
true, /*event*/
!skipVals, subjId, null, taskName, expiryPlc, !deserializeBinary, null);
if (res != null) {
v = res.value();
ver = res.version();
}
} else {
v = entry.innerGet(null, tx, /*read-through*/
false, /*metrics*/
true, /*events*/
!skipVals, subjId, null, taskName, expiryPlc, !deserializeBinary);
}
}
if (v == null) {
boolean fastLocGet = allowLocRead && cctx.allowFastLocalRead(part, affNodes, topVer);
if (fastLocGet && localDhtGet(key, part, topVer, isNear))
break;
ClusterNode affNode = affinityNode(affNodes);
if (affNode == null) {
onDone(serverNotFoundError(topVer));
return saved;
}
if (cctx.cache().configuration().isStatisticsEnabled() && !skipVals && !affNode.isLocal())
cache().metrics0().onRead(false);
LinkedHashMap<KeyCacheObject, Boolean> keys = mapped.get(affNode);
if (keys != null && keys.containsKey(key)) {
if (REMAP_CNT_UPD.incrementAndGet(this) > MAX_REMAP_CNT) {
onDone(new ClusterTopologyCheckedException("Failed to remap key to a new node after " + MAX_REMAP_CNT + " attempts (key got remapped to the same node) " + "[key=" + key + ", node=" + U.toShortString(affNode) + ", mappings=" + mapped + ']'));
return saved;
}
}
if (!affNodes.contains(cctx.localNode())) {
GridNearCacheEntry nearEntry = entry != null ? entry : near.entryExx(key, topVer);
nearEntry.reserveEviction();
entry = null;
if (saved == null)
saved = U.newHashMap(3);
saved.put(key, nearEntry);
}
// Don't add reader if transaction acquires lock anyway to avoid deadlock.
boolean addRdr = tx == null || tx.optimistic();
if (!addRdr && tx.readCommitted() && !tx.writeSet().contains(cctx.txKey(key)))
addRdr = true;
LinkedHashMap<KeyCacheObject, Boolean> old = mappings.get(affNode);
if (old == null)
mappings.put(affNode, old = new LinkedHashMap<>(3, 1f));
old.put(key, addRdr);
} else
addResult(key, v, ver);
break;
} catch (IgniteCheckedException e) {
onDone(e);
break;
} catch (GridCacheEntryRemovedException ignored) {
// Retry.
} finally {
if (entry != null && tx == null)
cctx.evicts().touch(entry, topVer);
}
}
return saved;
}
use of org.apache.ignite.internal.processors.cache.CacheObject in project ignite by apache.
the class GridNearTxLocal method checkMissed.
/**
* @param cacheCtx Cache context.
* @param topVer Topology version.
* @param map Return map.
* @param missedMap Missed keys.
* @param deserializeBinary Deserialize binary flag.
* @param skipVals Skip values flag.
* @param keepCacheObjects Keep cache objects flag.
* @param skipStore Skip store flag.
* @param expiryPlc Expiry policy.
* @return Loaded key-value pairs.
*/
private <K, V> IgniteInternalFuture<Map<K, V>> checkMissed(final GridCacheContext cacheCtx, final AffinityTopologyVersion topVer, final Map<K, V> map, final Map<KeyCacheObject, GridCacheVersion> missedMap, final boolean deserializeBinary, final boolean skipVals, final boolean keepCacheObjects, final boolean skipStore, final boolean recovery, final boolean needVer, final ExpiryPolicy expiryPlc) {
if (log.isDebugEnabled())
log.debug("Loading missed values for missed map: " + missedMap);
final boolean needReadVer = (serializable() && optimistic()) || needVer;
return new GridEmbeddedFuture<>(new C2<Void, Exception, Map<K, V>>() {
@Override
public Map<K, V> apply(Void v, Exception e) {
if (e != null) {
setRollbackOnly();
throw new GridClosureException(e);
}
return map;
}
}, loadMissing(cacheCtx, topVer, !skipStore, false, missedMap.keySet(), skipVals, needReadVer, !deserializeBinary, recovery, expiryPlc, new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
@Override
public void apply(KeyCacheObject key, Object val, GridCacheVersion loadVer) {
if (isRollbackOnly()) {
if (log.isDebugEnabled())
log.debug("Ignoring loaded value for read because transaction was rolled back: " + GridNearTxLocal.this);
return;
}
CacheObject cacheVal = cacheCtx.toCacheObject(val);
CacheObject visibleVal = cacheVal;
IgniteTxKey txKey = cacheCtx.txKey(key);
IgniteTxEntry txEntry = entry(txKey);
if (txEntry != null) {
if (!readCommitted())
txEntry.readValue(cacheVal);
if (!F.isEmpty(txEntry.entryProcessors()))
visibleVal = txEntry.applyEntryProcessors(visibleVal);
}
assert txEntry != null || readCommitted() || skipVals;
GridCacheEntryEx e = txEntry == null ? entryEx(cacheCtx, txKey, topVer) : txEntry.cached();
if (readCommitted() || skipVals) {
cacheCtx.evicts().touch(e, topologyVersion());
if (visibleVal != null) {
cacheCtx.addResult(map, key, visibleVal, skipVals, keepCacheObjects, deserializeBinary, false, needVer ? loadVer : null, 0, 0);
}
} else {
assert txEntry != null;
txEntry.setAndMarkValid(cacheVal);
if (needReadVer) {
assert loadVer != null;
txEntry.entryReadVersion(loadVer);
}
if (visibleVal != null) {
cacheCtx.addResult(map, key, visibleVal, skipVals, keepCacheObjects, deserializeBinary, false, needVer ? loadVer : null, 0, 0);
}
}
}
}));
}
Aggregations