use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion 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;
}
use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.
the class GridNearTxLocal method loadMissing.
/**
* @param cacheCtx Cache context.
* @param keys Keys to load.
* @param filter Filter.
* @param ret Return value.
* @param needReadVer Read version flag.
* @param singleRmv {@code True} for single remove operation.
* @param hasFilters {@code True} if filters not empty.
* @param readThrough Read through flag.
* @param retval Return value flag.
* @param expiryPlc Expiry policy.
* @return Load future.
*/
private IgniteInternalFuture<Void> loadMissing(final GridCacheContext cacheCtx, final AffinityTopologyVersion topVer, final Set<KeyCacheObject> keys, final CacheEntryPredicate[] filter, final GridCacheReturn ret, final boolean needReadVer, final boolean singleRmv, final boolean hasFilters, final boolean readThrough, final boolean retval, final boolean keepBinary, final boolean recovery, final ExpiryPolicy expiryPlc) {
GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c = new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
@Override
public void apply(KeyCacheObject key, @Nullable Object val, @Nullable GridCacheVersion loadVer) {
if (log.isDebugEnabled())
log.debug("Loaded value from remote node [key=" + key + ", val=" + val + ']');
IgniteTxEntry e = entry(new IgniteTxKey(key, cacheCtx.cacheId()));
assert e != null;
if (needReadVer) {
assert loadVer != null;
e.entryReadVersion(singleRmv && val != null ? SER_READ_NOT_EMPTY_VER : loadVer);
}
if (singleRmv) {
assert !hasFilters && !retval;
assert val == null || Boolean.TRUE.equals(val) : val;
ret.set(cacheCtx, null, val != null, keepBinary, U.deploymentClassLoader(cctx.kernalContext(), deploymentLdrId));
} else {
CacheObject cacheVal = cacheCtx.toCacheObject(val);
if (e.op() == TRANSFORM) {
GridCacheVersion ver;
e.readValue(cacheVal);
try {
ver = e.cached().version();
} catch (GridCacheEntryRemovedException ex) {
assert optimistic() : e;
if (log.isDebugEnabled())
log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
ver = null;
}
addInvokeResult(e, cacheVal, ret, ver);
} else {
boolean success;
if (hasFilters) {
success = isAll(e.context(), key, cacheVal, filter);
if (!success) {
e.value(cacheVal, false, false);
e.op(READ);
}
} else
success = true;
ret.set(cacheCtx, cacheVal, success, keepBinary, U.deploymentClassLoader(cctx.kernalContext(), deploymentLdrId));
}
}
}
};
return loadMissing(cacheCtx, topVer, readThrough, /*async*/
true, keys, /*skipVals*/
singleRmv, needReadVer, keepBinary, recovery, null, expiryPlc, c);
}
use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.
the class GridNearTxLocal method localCacheLoadMissing.
/**
* @param cacheCtx Cache context.
* @param readThrough Read through flag.
* @param async if {@code True}, then loading will happen in a separate thread.
* @param keys Keys.
* @param skipVals Skip values flag.
* @param needVer If {@code true} version is required for loaded values.
* @param c Closure to be applied for loaded values.
* @param expiryPlc Expiry policy.
* @return Future with {@code True} value if loading took place.
*/
private IgniteInternalFuture<Void> localCacheLoadMissing(final GridCacheContext cacheCtx, final AffinityTopologyVersion topVer, final boolean readThrough, boolean async, final Collection<KeyCacheObject> keys, boolean skipVals, boolean needVer, boolean keepBinary, boolean recovery, final ExpiryPolicy expiryPlc, final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c) {
assert cacheCtx.isLocal() : cacheCtx.name();
if (!readThrough || !cacheCtx.readThrough()) {
for (KeyCacheObject key : keys) c.apply(key, null, SER_READ_EMPTY_ENTRY_VER);
return new GridFinishedFuture<>();
}
try {
IgniteCacheExpiryPolicy expiryPlc0 = optimistic() ? accessPolicy(cacheCtx, keys) : cacheCtx.cache().expiryPolicy(expiryPlc);
Map<KeyCacheObject, GridCacheVersion> misses = null;
for (KeyCacheObject key : keys) {
while (true) {
IgniteTxEntry txEntry = entry(cacheCtx.txKey(key));
GridCacheEntryEx entry = txEntry == null ? cacheCtx.cache().entryEx(key) : txEntry.cached();
if (entry == null)
continue;
try {
EntryGetResult res = entry.innerGetVersioned(null, this, /*update-metrics*/
!skipVals, /*event*/
!skipVals, null, resolveTaskName(), expiryPlc0, txEntry == null ? keepBinary : txEntry.keepBinary(), null);
if (res == null) {
if (misses == null)
misses = new LinkedHashMap<>();
misses.put(key, entry.version());
} else
c.apply(key, skipVals ? true : res.value(), res.version());
break;
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed entry, will retry: " + key);
if (txEntry != null)
txEntry.cached(cacheCtx.cache().entryEx(key, topologyVersion()));
}
}
}
if (misses != null) {
final Map<KeyCacheObject, GridCacheVersion> misses0 = misses;
cacheCtx.store().loadAll(this, misses.keySet(), new CI2<KeyCacheObject, Object>() {
@Override
public void apply(KeyCacheObject key, Object val) {
GridCacheVersion ver = misses0.remove(key);
assert ver != null : key;
if (val != null) {
CacheObject cacheVal = cacheCtx.toCacheObject(val);
while (true) {
GridCacheEntryEx entry = cacheCtx.cache().entryEx(key, topVer);
try {
cacheCtx.shared().database().ensureFreeSpace(cacheCtx.dataRegion());
EntryGetResult verVal = entry.versionedValue(cacheVal, ver, null, null, null);
if (log.isDebugEnabled()) {
log.debug("Set value loaded from store into entry [" + "oldVer=" + ver + ", newVer=" + verVal.version() + ", entry=" + entry + ']');
}
ver = verVal.version();
break;
} catch (GridCacheEntryRemovedException ignore) {
if (log.isDebugEnabled())
log.debug("Got removed entry, (will retry): " + entry);
} catch (IgniteCheckedException e) {
// Wrap errors (will be unwrapped).
throw new GridClosureException(e);
}
}
} else
ver = SER_READ_EMPTY_ENTRY_VER;
c.apply(key, val, ver);
}
});
for (KeyCacheObject key : misses0.keySet()) c.apply(key, null, SER_READ_EMPTY_ENTRY_VER);
}
return new GridFinishedFuture<>();
} catch (IgniteCheckedException e) {
setRollbackOnly();
return new GridFinishedFuture<>(e);
}
}
use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.
the class GridNearTxLocal method readyNearLock.
/**
* @param txEntry TX entry.
* @param dhtVer DHT version.
* @param pendingVers Pending versions.
* @param committedVers Committed versions.
* @param rolledbackVers Rolled back versions.
*/
private void readyNearLock(IgniteTxEntry txEntry, GridCacheVersion dhtVer, Collection<GridCacheVersion> pendingVers, Collection<GridCacheVersion> committedVers, Collection<GridCacheVersion> rolledbackVers) {
while (true) {
GridCacheContext cacheCtx = txEntry.cached().context();
assert cacheCtx.isNear();
GridDistributedCacheEntry entry = (GridDistributedCacheEntry) txEntry.cached();
try {
// Handle explicit locks.
GridCacheVersion explicit = txEntry.explicitVersion();
if (explicit == null) {
entry.readyNearLock(xidVer, dhtVer, committedVers, rolledbackVers, pendingVers);
}
break;
} catch (GridCacheEntryRemovedException ignored) {
assert entry.obsoleteVersion() != null;
if (log.isDebugEnabled())
log.debug("Replacing obsolete entry in remote transaction [entry=" + entry + ", tx=" + this + ']');
// Replace the entry.
txEntry.cached(txEntry.context().cache().entryEx(txEntry.key(), topologyVersion()));
}
}
}
use of org.apache.ignite.internal.processors.cache.version.GridCacheVersion in project ignite by apache.
the class GridNearTxLocal method loadMissing.
/**
* @param cacheCtx Cache context.
* @param readThrough Read through flag.
* @param async if {@code True}, then loading will happen in a separate thread.
* @param keys Keys.
* @param skipVals Skip values flag.
* @param needVer If {@code true} version is required for loaded values.
* @param c Closure to be applied for loaded values.
* @param readRepairStrategy Read Repair strategy.
* @param expiryPlc Expiry policy.
* @return Future with {@code True} value if loading took place.
*/
private IgniteInternalFuture<Void> loadMissing(final GridCacheContext cacheCtx, AffinityTopologyVersion topVer, boolean readThrough, boolean async, final Collection<KeyCacheObject> keys, final boolean skipVals, final boolean needVer, boolean keepBinary, boolean recovery, ReadRepairStrategy readRepairStrategy, final ExpiryPolicy expiryPlc, final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c) {
IgniteCacheExpiryPolicy expiryPlc0 = optimistic() ? accessPolicy(cacheCtx, keys) : cacheCtx.cache().expiryPolicy(expiryPlc);
if (cacheCtx.isNear()) {
return cacheCtx.nearTx().txLoadAsync(this, topVer, keys, readThrough, needVer || !cacheCtx.config().isReadFromBackup() || (optimistic() && serializable() && readThrough), /*deserializeBinary*/
false, recovery, expiryPlc0, skipVals, needVer).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
@Override
public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
try {
Map<Object, Object> map = f.get();
processLoaded(map, keys, needVer, c);
return null;
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
}
});
} else if (cacheCtx.isColocated()) {
if (readRepairStrategy != null) {
return new GridNearReadRepairCheckOnlyFuture(cacheCtx, keys, readRepairStrategy, readThrough, taskName, false, recovery, expiryPlc0, skipVals, needVer, true, this).multi().chain((fut) -> {
try {
Map<Object, Object> map = fut.get();
processLoaded(map, keys, needVer, c);
return null;
} catch (IgniteConsistencyViolationException e) {
for (KeyCacheObject key : keys) // Will be recreated after repair.
txState().removeEntry(cacheCtx.txKey(key));
throw new GridClosureException(e);
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
});
}
if (keys.size() == 1) {
final KeyCacheObject key = F.first(keys);
return cacheCtx.colocated().loadAsync(key, readThrough, needVer || !cacheCtx.config().isReadFromBackup() || (optimistic() && serializable() && readThrough), topVer, resolveTaskName(), /*deserializeBinary*/
false, expiryPlc0, skipVals, needVer, /*keepCacheObject*/
true, recovery, null, label()).chain(new C1<IgniteInternalFuture<Object>, Void>() {
@Override
public Void apply(IgniteInternalFuture<Object> f) {
try {
Object val = f.get();
processLoaded(key, val, needVer, skipVals, c);
return null;
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
}
});
} else {
return cacheCtx.colocated().loadAsync(keys, readThrough, needVer || !cacheCtx.config().isReadFromBackup() || (optimistic() && serializable() && readThrough), topVer, resolveTaskName(), /*deserializeBinary*/
false, recovery, expiryPlc0, skipVals, needVer, /*keepCacheObject*/
true, label(), null).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
@Override
public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
try {
Map<Object, Object> map = f.get();
processLoaded(map, keys, needVer, c);
return null;
} catch (Exception e) {
setRollbackOnly();
throw new GridClosureException(e);
}
}
});
}
} else {
assert cacheCtx.isLocal();
return localCacheLoadMissing(cacheCtx, topVer, readThrough, async, keys, skipVals, needVer, keepBinary, recovery, expiryPlc, c);
}
}
Aggregations