use of org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException in project ignite by apache.
the class GridCacheStoreManagerAdapter method putAll.
/** {@inheritDoc} */
@Override
public final boolean putAll(@Nullable IgniteInternalTx tx, Map<? extends KeyCacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>> map) throws IgniteCheckedException {
if (F.isEmpty(map))
return true;
if (map.size() == 1) {
Map.Entry<? extends KeyCacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>> e = ((Map<? extends KeyCacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>>) map).entrySet().iterator().next();
return put(tx, e.getKey(), e.getValue().get1(), e.getValue().get2());
} else {
if (store != null) {
EntriesView entries = new EntriesView(map);
if (log.isDebugEnabled())
log.debug("Storing values in cache store [entries=" + entries + ']');
sessionInit0(tx);
boolean threwEx = true;
try {
store.writeAll(entries);
threwEx = false;
} catch (ClassCastException e) {
handleClassCastException(e);
} catch (Exception e) {
if (!(e instanceof CacheWriterException))
e = new CacheWriterException(e);
if (!entries.isEmpty()) {
List<Object> keys = new ArrayList<>(entries.size());
for (Cache.Entry<?, ?> entry : entries) keys.add(entry.getKey());
throw new CacheStorePartialUpdateException(keys, e);
}
throw new IgniteCheckedException(e);
} finally {
sessionEnd0(tx, threwEx);
}
if (log.isDebugEnabled())
log.debug("Stored value in cache store [entries=" + entries + ']');
return true;
}
return false;
}
}
use of org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException in project ignite by apache.
the class GridDhtAtomicCache method updatePartialBatch.
/**
* @param hasNear {@code True} if originating node has near cache.
* @param firstEntryIdx Index of the first entry in the request keys collection.
* @param entries Entries to update.
* @param ver Version to set.
* @param nearNode Originating node.
* @param writeVals Write values.
* @param putMap Values to put.
* @param rmvKeys Keys to remove.
* @param entryProcessorMap Entry processors.
* @param dhtFut DHT update future if has backups.
* @param req Request.
* @param res Response.
* @param replicate Whether replication is enabled.
* @param batchRes Batch update result.
* @param taskName Task name.
* @param expiry Expiry policy.
* @param sndPrevVal If {@code true} sends previous value to backups.
* @return Deleted entries.
*/
@SuppressWarnings("ForLoopReplaceableByForEach")
@Nullable
private GridDhtAtomicAbstractUpdateFuture updatePartialBatch(final boolean hasNear, final int firstEntryIdx, final List<GridDhtCacheEntry> entries, final GridCacheVersion ver, final ClusterNode nearNode, @Nullable final List<CacheObject> writeVals, @Nullable final Map<KeyCacheObject, CacheObject> putMap, @Nullable final Collection<KeyCacheObject> rmvKeys, @Nullable final Map<KeyCacheObject, EntryProcessor<Object, Object, Object>> entryProcessorMap, @Nullable GridDhtAtomicAbstractUpdateFuture dhtFut, final GridNearAtomicAbstractUpdateRequest req, final GridNearAtomicUpdateResponse res, final boolean replicate, final UpdateBatchResult batchRes, final String taskName, @Nullable final IgniteCacheExpiryPolicy expiry, final boolean sndPrevVal) {
assert putMap == null ^ rmvKeys == null;
assert req.conflictVersions() == null : "Cannot be called when there are conflict entries in the batch.";
AffinityTopologyVersion topVer = req.topologyVersion();
boolean checkReaders = hasNear || ctx.discovery().hasNearCache(ctx.cacheId(), topVer);
CacheStorePartialUpdateException storeErr = null;
try {
GridCacheOperation op;
if (putMap != null) {
try {
Map<? extends KeyCacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>> view = F.viewReadOnly(putMap, new C1<CacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>>() {
@Override
public IgniteBiTuple<? extends CacheObject, GridCacheVersion> apply(CacheObject val) {
return F.t(val, ver);
}
});
ctx.store().putAll(null, view);
} catch (CacheStorePartialUpdateException e) {
storeErr = e;
}
op = UPDATE;
} else {
try {
ctx.store().removeAll(null, rmvKeys);
} catch (CacheStorePartialUpdateException e) {
storeErr = e;
}
op = DELETE;
}
boolean intercept = ctx.config().getInterceptor() != null;
AffinityAssignment affAssignment = ctx.affinity().assignment(topVer);
// Avoid iterator creation.
for (int i = 0; i < entries.size(); i++) {
GridDhtCacheEntry entry = entries.get(i);
assert Thread.holdsLock(entry);
if (entry.obsolete()) {
assert req.operation() == DELETE : "Entry can become obsolete only after remove: " + entry;
continue;
}
if (storeErr != null && storeErr.failedKeys().contains(entry.key().value(ctx.cacheObjectContext(), false)))
continue;
try {
// We are holding java-level locks on entries at this point.
CacheObject writeVal = op == UPDATE ? writeVals.get(i) : null;
assert writeVal != null || op == DELETE : "null write value found.";
Collection<UUID> readers = null;
Collection<UUID> filteredReaders = null;
if (checkReaders) {
readers = entry.readers();
filteredReaders = F.view(entry.readers(), F.notEqualTo(nearNode.id()));
}
GridCacheUpdateAtomicResult updRes = entry.innerUpdate(ver, nearNode.id(), locNodeId, op, writeVal, null, /*write-through*/
false, /*read-through*/
false, /*retval*/
sndPrevVal, req.keepBinary(), expiry, /*event*/
true, /*metrics*/
true, /*primary*/
true, /*verCheck*/
false, topVer, null, replicate ? DR_PRIMARY : DR_NONE, CU.TTL_NOT_CHANGED, CU.EXPIRE_TIME_CALCULATE, null, /*conflict resolve*/
false, /*intercept*/
false, req.subjectId(), taskName, null, null, dhtFut);
assert !updRes.success() || updRes.newTtl() == CU.TTL_NOT_CHANGED || expiry != null : "success=" + updRes.success() + ", newTtl=" + updRes.newTtl() + ", expiry=" + expiry;
if (intercept) {
if (op == UPDATE) {
ctx.config().getInterceptor().onAfterPut(new CacheLazyEntry(ctx, entry.key(), updRes.newValue(), req.keepBinary()));
} else {
assert op == DELETE : op;
// Old value should be already loaded for 'CacheInterceptor.onBeforeRemove'.
ctx.config().getInterceptor().onAfterRemove(new CacheLazyEntry(ctx, entry.key(), updRes.oldValue(), req.keepBinary()));
}
}
batchRes.addDeleted(entry, updRes, entries);
if (dhtFut != null) {
EntryProcessor<Object, Object, Object> entryProcessor = entryProcessorMap == null ? null : entryProcessorMap.get(entry.key());
dhtFut.addWriteEntry(affAssignment, entry, writeVal, entryProcessor, updRes.newTtl(), CU.EXPIRE_TIME_CALCULATE, null, sndPrevVal, updRes.oldValue(), updRes.updateCounter());
if (!F.isEmpty(filteredReaders))
dhtFut.addNearWriteEntries(filteredReaders, entry, writeVal, entryProcessor, updRes.newTtl(), CU.EXPIRE_TIME_CALCULATE);
}
if (hasNear) {
if (!ctx.affinity().partitionBelongs(nearNode, entry.partition(), topVer)) {
int idx = firstEntryIdx + i;
if (req.operation() == TRANSFORM) {
res.addNearValue(idx, writeVal, updRes.newTtl(), CU.EXPIRE_TIME_CALCULATE);
} else
res.addNearTtl(idx, updRes.newTtl(), CU.EXPIRE_TIME_CALCULATE);
if (writeVal != null || entry.hasValue()) {
IgniteInternalFuture<Boolean> f = entry.addReader(nearNode.id(), req.messageId(), topVer);
assert f == null : f;
}
} else if (// Reader became primary or backup.
readers.contains(nearNode.id()))
entry.removeReader(nearNode.id(), req.messageId());
else
res.addSkippedIndex(firstEntryIdx + i);
}
} catch (GridCacheEntryRemovedException e) {
assert false : "Entry cannot become obsolete while holding lock.";
e.printStackTrace();
}
}
} catch (IgniteCheckedException e) {
res.addFailedKeys(putMap != null ? putMap.keySet() : rmvKeys, e);
}
if (storeErr != null) {
ArrayList<KeyCacheObject> failed = new ArrayList<>(storeErr.failedKeys().size());
for (Object failedKey : storeErr.failedKeys()) failed.add(ctx.toCacheKeyObject(failedKey));
res.addFailedKeys(failed, storeErr.getCause());
}
return dhtFut;
}
use of org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException in project ignite by apache.
the class GridLocalAtomicCache method updatePartialBatch.
/**
* @param entries Entries to update.
* @param ver Cache version.
* @param writeVals Cache values.
* @param putMap Values to put.
* @param rmvKeys Keys to remove.
* @param expiryPlc Expiry policy.
* @param err Optional partial update exception.
* @param subjId Subject ID.
* @param taskName Task name.
* @return Partial update exception.
*/
@SuppressWarnings({ "unchecked", "ConstantConditions", "ForLoopReplaceableByForEach" })
@Nullable
private CachePartialUpdateCheckedException updatePartialBatch(List<GridCacheEntryEx> entries, final GridCacheVersion ver, @Nullable List<CacheObject> writeVals, @Nullable Map<KeyCacheObject, CacheObject> putMap, @Nullable Collection<KeyCacheObject> rmvKeys, @Nullable ExpiryPolicy expiryPlc, boolean keepBinary, @Nullable CachePartialUpdateCheckedException err, UUID subjId, String taskName) {
assert putMap == null ^ rmvKeys == null;
GridCacheOperation op;
CacheStorePartialUpdateException storeErr = null;
try {
if (putMap != null) {
try {
Map<? extends KeyCacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>> view = F.viewReadOnly(putMap, new C1<CacheObject, IgniteBiTuple<? extends CacheObject, GridCacheVersion>>() {
@Override
public IgniteBiTuple<? extends CacheObject, GridCacheVersion> apply(CacheObject val) {
return F.t(val, ver);
}
});
ctx.store().putAll(null, view);
} catch (CacheStorePartialUpdateException e) {
storeErr = e;
}
op = UPDATE;
} else {
try {
ctx.store().removeAll(null, rmvKeys);
} catch (CacheStorePartialUpdateException e) {
storeErr = e;
}
op = DELETE;
}
} catch (IgniteCheckedException e) {
if (err == null)
err = partialUpdateException();
err.add(putMap != null ? putMap.keySet() : rmvKeys, e);
return err;
}
boolean intercept = ctx.config().getInterceptor() != null;
for (int i = 0; i < entries.size(); i++) {
GridCacheEntryEx entry = entries.get(i);
assert Thread.holdsLock(entry);
if (entry.obsolete() || (storeErr != null && storeErr.failedKeys().contains(entry.key().value(ctx.cacheObjectContext(), false))))
continue;
try {
// We are holding java-level locks on entries at this point.
CacheObject writeVal = op == UPDATE ? writeVals.get(i) : null;
assert writeVal != null || op == DELETE : "null write value found.";
GridTuple3<Boolean, Object, EntryProcessorResult<Object>> t = entry.innerUpdateLocal(ver, op, writeVal, null, false, false, false, keepBinary, expiryPlc, true, true, null, false, subjId, taskName);
if (intercept) {
if (op == UPDATE)
ctx.config().getInterceptor().onAfterPut(new CacheLazyEntry(ctx, entry.key(), writeVal, keepBinary));
else
ctx.config().getInterceptor().onAfterRemove(new CacheLazyEntry(ctx, entry.key(), t.get2(), keepBinary));
}
} catch (GridCacheEntryRemovedException ignore) {
assert false : "Entry cannot become obsolete while holding lock.";
} catch (IgniteCheckedException e) {
if (err == null)
err = partialUpdateException();
err.add(Collections.singleton(entry.key()), e);
}
}
return err;
}
use of org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException in project ignite by apache.
the class GridCacheStoreManagerAdapter method removeAll.
/** {@inheritDoc} */
@Override
public final boolean removeAll(@Nullable IgniteInternalTx tx, Collection<? extends KeyCacheObject> keys) throws IgniteCheckedException {
if (F.isEmpty(keys))
return true;
if (keys.size() == 1) {
KeyCacheObject key = keys.iterator().next();
return remove(tx, key);
}
if (store != null) {
Collection<Object> keys0 = cctx.unwrapBinariesIfNeeded(keys, !convertBinary());
if (log.isDebugEnabled())
log.debug(S.toString("Removing values from cache store", "keys", keys0, true));
sessionInit0(tx);
boolean threwEx = true;
try {
store.deleteAll(keys0);
threwEx = false;
} catch (ClassCastException e) {
handleClassCastException(e);
} catch (Exception e) {
if (!(e instanceof CacheWriterException))
e = new CacheWriterException(e);
if (!keys0.isEmpty())
throw new CacheStorePartialUpdateException(keys0, e);
throw new IgniteCheckedException(e);
} finally {
sessionEnd0(tx, threwEx);
}
if (log.isDebugEnabled())
log.debug(S.toString("Removed values from cache store", "keys", keys0, true));
return true;
}
return false;
}
Aggregations