use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class MvccCachingManager method onTxFinished.
/**
* @param tx Transaction.
* @param commit {@code True} if commit.
*/
public void onTxFinished(IgniteInternalTx tx, boolean commit) throws IgniteCheckedException {
if (log.isDebugEnabled())
log.debug("Transaction finished: [commit=" + commit + ", tx=" + tx + ']');
if (tx.system() || tx.internal() || tx.mvccSnapshot() == null)
return;
cntrs.remove(new TxKey(tx.mvccSnapshot().coordinatorVersion(), tx.mvccSnapshot().counter()));
EnlistBuffer buf = enlistCache.remove(tx.xidVersion());
Map<Integer, Map<KeyCacheObject, MvccTxEntry>> allCached = buf == null ? null : buf.getCached();
TxCounters txCntrs = tx.txCounters(false);
Collection<PartitionUpdateCountersMessage> cntrsColl = txCntrs == null ? null : txCntrs.updateCounters();
if (txCntrs == null || F.isEmpty(cntrsColl))
return;
GridIntList cacheIds = tx.txState().cacheIds();
assert cacheIds != null;
for (int i = 0; i < cacheIds.size(); i++) {
int cacheId = cacheIds.get(i);
GridCacheContext ctx0 = cctx.cacheContext(cacheId);
assert ctx0 != null;
ctx0.group().listenerLock().readLock().lock();
try {
boolean hasListeners = ctx0.hasContinuousQueryListeners(tx);
boolean drEnabled = ctx0.isDrEnabled();
if (!hasListeners && !drEnabled)
// There are no listeners to notify.
continue;
// Get cached entries for the given cache.
Map<KeyCacheObject, MvccTxEntry> cached = allCached == null ? null : allCached.get(cacheId);
Map<Integer, Map<Integer, T2<AtomicLong, Long>>> cntrsMap = countersPerPartition(cntrsColl);
Map<Integer, T2<AtomicLong, Long>> cntrPerCache = cntrsMap.get(cacheId);
if (F.isEmpty(cntrPerCache))
// No updates were made for this cache.
continue;
boolean fakeEntries = false;
if (F.isEmpty(cached)) {
if (log.isDebugEnabled())
log.debug("Transaction updates were not cached fully (this can happen when listener started" + " during the transaction execution). [tx=" + tx + ']');
if (hasListeners) {
// Create fake update entries if we have CQ listeners.
cached = createFakeCachedEntries(cntrPerCache, tx, cacheId);
fakeEntries = true;
} else
// Nothing to do further if tx is not cached entirely and there are no any CQ listeners.
continue;
}
if (F.isEmpty(cached))
continue;
// Feed CQ & DR with entries.
for (Map.Entry<KeyCacheObject, MvccTxEntry> entry : cached.entrySet()) {
MvccTxEntry e = entry.getValue();
assert e.key().partition() != -1;
assert cntrPerCache != null;
assert e.cacheId() == cacheId;
T2<AtomicLong, Long> cntr = cntrPerCache.get(e.key().partition());
long resCntr = cntr.getKey().incrementAndGet();
assert resCntr <= cntr.getValue();
e.updateCounter(resCntr);
if (ctx0.group().sharedGroup()) {
ctx0.group().onPartitionCounterUpdate(cacheId, e.key().partition(), resCntr, tx.topologyVersion(), tx.local());
}
if (log.isDebugEnabled())
log.debug("Process cached entry:" + e);
// DR
if (ctx0.isDrEnabled() && !fakeEntries) {
ctx0.dr().replicate(e.key(), e.value(), e.ttl(), e.expireTime(), e.version(), tx.local() ? DR_PRIMARY : DR_BACKUP, e.topologyVersion());
}
// CQ
CacheContinuousQueryManager contQryMgr = ctx0.continuousQueries();
if (ctx0.continuousQueries().notifyContinuousQueries(tx)) {
Map<UUID, CacheContinuousQueryListener> lsnrCol = continuousQueryListeners(ctx0, tx);
if (!F.isEmpty(lsnrCol)) {
contQryMgr.onEntryUpdated(lsnrCol, e.key(), // Force skip update counter if rolled back.
commit ? e.value() : null, // Force skip update counter if rolled back.
commit ? e.oldValue() : null, false, e.key().partition(), tx.local(), false, e.updateCounter(), null, e.topologyVersion());
}
}
}
} finally {
ctx0.group().listenerLock().readLock().unlock();
}
}
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridLocalAtomicCache method getAllInternal.
/**
* Entry point to all public API get methods.
*
* @param keys Keys to remove.
* @param storeEnabled Store enabled flag.
* @param taskName Task name.
* @param deserializeBinary Deserialize binary .
* @param skipVals Skip value flag.
* @param needVer Need version.
* @return Key-value map.
* @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("ConstantConditions")
private Map<K, V> getAllInternal(@Nullable Collection<? extends K> keys, boolean storeEnabled, String taskName, boolean deserializeBinary, boolean skipVals, boolean needVer) throws IgniteCheckedException {
ctx.checkSecurity(SecurityPermission.CACHE_READ);
if (F.isEmpty(keys))
return Collections.emptyMap();
CacheOperationContext opCtx = ctx.operationContextPerCall();
Map<K, V> vals = U.newHashMap(keys.size());
warnIfUnordered(keys, BulkOperation.GET);
final IgniteCacheExpiryPolicy expiry = expiryPolicy(opCtx != null ? opCtx.expiry() : null);
boolean success = true;
boolean readNoEntry = ctx.readNoEntry(expiry, false);
final boolean evt = !skipVals;
ctx.shared().database().checkpointReadLock();
try {
for (K key : keys) {
if (key == null)
throw new NullPointerException("Null key.");
KeyCacheObject cacheKey = ctx.toCacheKeyObject(key);
boolean skipEntry = readNoEntry;
if (readNoEntry) {
CacheDataRow row = ctx.offheap().read(ctx, cacheKey);
if (row != null) {
long expireTime = row.expireTime();
if (expireTime == 0 || expireTime > U.currentTimeMillis()) {
ctx.addResult(vals, cacheKey, row.value(), skipVals, false, deserializeBinary, true, null, row.version(), 0, 0, needVer, null);
if (ctx.statisticsEnabled() && !skipVals)
metrics0().onRead(true);
if (evt) {
ctx.events().readEvent(cacheKey, null, null, row.value(), taskName, !deserializeBinary);
}
} else
skipEntry = false;
} else
success = false;
}
if (!skipEntry) {
GridCacheEntryEx entry = null;
while (true) {
try {
entry = entryEx(cacheKey);
if (entry != null) {
CacheObject v;
if (needVer) {
EntryGetResult res = entry.innerGetVersioned(null, null, /*update-metrics*/
false, /*event*/
evt, null, taskName, expiry, !deserializeBinary, null);
if (res != null) {
ctx.addResult(vals, cacheKey, res, skipVals, false, deserializeBinary, true, needVer);
} else
success = false;
} else {
v = entry.innerGet(null, null, /*read-through*/
false, /*update-metrics*/
true, /*event*/
evt, null, taskName, expiry, !deserializeBinary);
if (v != null) {
ctx.addResult(vals, cacheKey, v, skipVals, false, deserializeBinary, true, null, 0, 0, null);
} else
success = false;
}
}
// While.
break;
} catch (GridCacheEntryRemovedException ignored) {
// No-op, retry.
} finally {
if (entry != null)
entry.touch();
}
if (!success && storeEnabled)
break;
}
}
if (!success) {
if (!storeEnabled && ctx.statisticsEnabled() && !skipVals)
metrics0().onRead(false);
}
}
} finally {
ctx.shared().database().checkpointReadUnlock();
}
if (success || !storeEnabled)
return vals;
return getAllAsync(keys, null, opCtx == null || !opCtx.skipStore(), false, taskName, deserializeBinary, opCtx != null && opCtx.recovery(), null, /*force primary*/
false, expiry, skipVals, needVer).get();
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearReadRepairAbstractFuture method check.
/**
* Checks consistency.
*
* @return Regular `get` result when data is consistent.
*/
protected final Map<KeyCacheObject, EntryGetResult> check() throws IgniteCheckedException {
Map<KeyCacheObject, EntryGetResult> resMap = new HashMap<>(keys.size());
Set<KeyCacheObject> inconsistentKeys = new HashSet<>();
for (GridPartitionedGetFuture<KeyCacheObject, EntryGetResult> fut : futs.values()) {
for (KeyCacheObject key : fut.keys()) {
EntryGetResult curRes = fut.result().get(key);
if (!resMap.containsKey(key)) {
resMap.put(key, curRes);
continue;
}
EntryGetResult prevRes = resMap.get(key);
if (curRes != null) {
if (prevRes == null || prevRes.version().compareTo(curRes.version()) != 0)
inconsistentKeys.add(key);
else {
CacheObject curVal = curRes.value();
CacheObject prevVal = prevRes.value();
byte[] curBytes = curVal.valueBytes(ctx.cacheObjectContext());
byte[] prevBytes = prevVal.valueBytes(ctx.cacheObjectContext());
if (!Arrays.equals(curBytes, prevBytes))
inconsistentKeys.add(key);
}
} else if (prevRes != null)
inconsistentKeys.add(key);
}
}
if (!inconsistentKeys.isEmpty())
throw new IgniteConsistencyViolationException(inconsistentKeys);
return resMap;
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearReadRepairAbstractFuture method recordConsistencyViolation.
/**
* @param fixedEntries Fixed map.
*/
protected final void recordConsistencyViolation(Collection<KeyCacheObject> inconsistentKeys, Map<KeyCacheObject, EntryGetResult> fixedEntries, ReadRepairStrategy strategy) {
GridEventStorageManager evtMgr = ctx.gridEvents();
if (!evtMgr.isRecordable(EVT_CONSISTENCY_VIOLATION))
return;
Map<Object, Map<ClusterNode, CacheConsistencyViolationEvent.EntryInfo>> entries = new HashMap<>();
for (Map.Entry<ClusterNode, GridPartitionedGetFuture<KeyCacheObject, EntryGetResult>> pair : futs.entrySet()) {
ClusterNode node = pair.getKey();
GridPartitionedGetFuture<KeyCacheObject, EntryGetResult> fut = pair.getValue();
for (KeyCacheObject key : fut.keys()) {
if (inconsistentKeys.contains(key)) {
Map<ClusterNode, CacheConsistencyViolationEvent.EntryInfo> map = entries.computeIfAbsent(ctx.unwrapBinaryIfNeeded(key, !deserializeBinary, false, null), k -> new HashMap<>());
EntryGetResult res = fut.result().get(key);
CacheEntryVersion ver = res != null ? res.version() : null;
Object val = res != null ? ctx.unwrapBinaryIfNeeded(res.value(), !deserializeBinary, false, null) : null;
boolean primary = primaries.get(key).equals(fut.affNode());
boolean correct = fixedEntries != null && ((fixedEntries.get(key) != null && fixedEntries.get(key).equals(res)) || (fixedEntries.get(key) == null && res == null));
map.put(node, new EventEntryInfo(val, ver, primary, correct));
}
}
}
Map<Object, Object> fixed;
if (fixedEntries == null)
fixed = Collections.emptyMap();
else {
fixed = new HashMap<>();
for (Map.Entry<KeyCacheObject, EntryGetResult> entry : fixedEntries.entrySet()) {
Object key = ctx.unwrapBinaryIfNeeded(entry.getKey(), !deserializeBinary, false, null);
Object val = entry.getValue() != null ? ctx.unwrapBinaryIfNeeded(entry.getValue().value(), !deserializeBinary, false, null) : null;
fixed.put(key, val);
}
}
evtMgr.record(new CacheConsistencyViolationEvent(ctx.name(), ctx.discovery().localNode(), "Consistency violation was " + (fixed == null ? "NOT " : "") + "fixed.", entries, fixed, strategy));
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridNearReadRepairFuture method fixWithMajority.
/**
*/
public Map<KeyCacheObject, EntryGetResult> fixWithMajority(Collection<KeyCacheObject> inconsistentKeys) throws IgniteCheckedException {
/**
*/
class ByteArrayWrapper {
final byte[] arr;
/**
*/
public ByteArrayWrapper(byte[] arr) {
this.arr = arr;
}
/**
*/
@Override
public boolean equals(Object o) {
return Arrays.equals(arr, ((ByteArrayWrapper) o).arr);
}
/**
*/
@Override
public int hashCode() {
return Arrays.hashCode(arr);
}
}
Set<KeyCacheObject> irreparableSet = new HashSet<>(inconsistentKeys.size());
Map<KeyCacheObject, EntryGetResult> fixedMap = new HashMap<>(inconsistentKeys.size());
for (KeyCacheObject key : inconsistentKeys) {
Map<T2<ByteArrayWrapper, GridCacheVersion>, T2<EntryGetResult, Integer>> cntMap = new HashMap<>();
for (GridPartitionedGetFuture<KeyCacheObject, EntryGetResult> fut : futs.values()) {
if (!fut.keys().contains(key))
continue;
EntryGetResult res = fut.result().get(key);
ByteArrayWrapper wrapped;
GridCacheVersion ver;
if (res != null) {
CacheObject val = res.value();
wrapped = new ByteArrayWrapper(val.valueBytes(ctx.cacheObjectContext()));
ver = res.version();
} else {
wrapped = new ByteArrayWrapper(null);
ver = null;
}
T2<ByteArrayWrapper, GridCacheVersion> keyVer = new T2<>(wrapped, ver);
cntMap.putIfAbsent(keyVer, new T2<>(res, 0));
cntMap.compute(keyVer, (kv, ri) -> new T2<>(ri.getKey(), ri.getValue() + 1));
}
int[] sorted = cntMap.values().stream().map(IgniteBiTuple::getValue).sorted(Comparator.reverseOrder()).mapToInt(v -> v).toArray();
int max = sorted[0];
assert max > 0;
if (sorted.length > 1 && sorted[1] == max) {
// Majority was not found.
irreparableSet.add(key);
continue;
}
for (Map.Entry<T2<ByteArrayWrapper, GridCacheVersion>, T2<EntryGetResult, Integer>> count : cntMap.entrySet()) if (count.getValue().getValue().equals(max)) {
fixedMap.put(key, count.getValue().getKey());
break;
}
}
if (!irreparableSet.isEmpty())
throwIrreparable(inconsistentKeys, irreparableSet);
return fixedMap;
}
Aggregations