use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridCacheQueryManager method store.
/**
* Writes key-value pair to index.
*
* @param key Key.
* @param partId Partition.
* @param prevVal Previous value.
* @param prevVer Previous version.
* @param val Value.
* @param ver Cache entry version.
* @param expirationTime Expiration time or 0 if never expires.
* @param link Link.
* @throws IgniteCheckedException In case of error.
*/
public void store(KeyCacheObject key, int partId, @Nullable CacheObject prevVal, @Nullable GridCacheVersion prevVer, CacheObject val, GridCacheVersion ver, long expirationTime, long link) throws IgniteCheckedException {
assert key != null;
assert val != null;
assert enabled();
if (key instanceof GridCacheInternal)
// No-op.
return;
if (!enterBusy())
throw new NodeStoppingException("Operation has been cancelled (node is stopping).");
try {
if (isIndexingSpiEnabled()) {
CacheObjectContext coctx = cctx.cacheObjectContext();
Object key0 = unwrapIfNeeded(key, coctx);
Object val0 = unwrapIfNeeded(val, coctx);
cctx.kernalContext().indexing().store(cacheName, key0, val0, expirationTime);
}
if (qryProcEnabled)
qryProc.store(cacheName, key, partId, prevVal, prevVer, val, ver, expirationTime, link);
} finally {
invalidateResultCache();
leaveBusy();
}
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject in project ignite by apache.
the class GridDhtPreloader method request0.
/**
* @param keys Keys to request.
* @param topVer Topology version.
* @return Future for request.
*/
@SuppressWarnings({ "unchecked", "RedundantCast" })
private GridDhtFuture<Object> request0(Collection<KeyCacheObject> keys, AffinityTopologyVersion topVer) {
final GridDhtForceKeysFuture<?, ?> fut = new GridDhtForceKeysFuture<>(cctx, topVer, keys, this);
IgniteInternalFuture<?> topReadyFut = cctx.affinity().affinityReadyFuturex(topVer);
if (startFut.isDone() && topReadyFut == null)
fut.init();
else {
if (topReadyFut == null)
startFut.listen(new CI1<IgniteInternalFuture<?>>() {
@Override
public void apply(IgniteInternalFuture<?> syncFut) {
cctx.kernalContext().closure().runLocalSafe(new GridPlainRunnable() {
@Override
public void run() {
fut.init();
}
});
}
});
else {
GridCompoundFuture<Object, Object> compound = new GridCompoundFuture<>();
compound.add((IgniteInternalFuture<Object>) startFut);
compound.add((IgniteInternalFuture<Object>) topReadyFut);
compound.markInitialized();
compound.listen(new CI1<IgniteInternalFuture<?>>() {
@Override
public void apply(IgniteInternalFuture<?> syncFut) {
fut.init();
}
});
}
}
return (GridDhtFuture) fut;
}
use of org.apache.ignite.internal.processors.cache.KeyCacheObject 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.KeyCacheObject 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 entry.lockedByCurrentThread();
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.KeyCacheObject in project ignite by apache.
the class GridLocalAtomicCache method updateWithBatch.
/**
* Updates entries using batched write-through.
*
* @param op Operation.
* @param keys Keys.
* @param vals Values.
* @param invokeArgs Optional arguments for EntryProcessor.
* @param expiryPlc Expiry policy.
* @param ver Cache version.
* @param filter Optional filter.
* @param subjId Subject ID.
* @param taskName Task name.
* @return Results map for invoke operation.
* @throws CachePartialUpdateCheckedException If update failed.
*/
@SuppressWarnings({ "ForLoopReplaceableByForEach", "unchecked" })
private Map<K, EntryProcessorResult> updateWithBatch(GridCacheOperation op, Collection<? extends K> keys, @Nullable Iterable<?> vals, @Nullable Object[] invokeArgs, @Nullable ExpiryPolicy expiryPlc, GridCacheVersion ver, @Nullable CacheEntryPredicate[] filter, boolean keepBinary, UUID subjId, String taskName) throws IgniteCheckedException {
List<GridCacheEntryEx> locked = lockEntries(keys);
try {
int size = locked.size();
Map<KeyCacheObject, CacheObject> putMap = null;
Collection<KeyCacheObject> rmvKeys = null;
List<CacheObject> writeVals = null;
Map<K, EntryProcessorResult> invokeResMap = op == TRANSFORM ? U.<K, EntryProcessorResult>newHashMap(size) : null;
List<GridCacheEntryEx> filtered = new ArrayList<>(size);
CachePartialUpdateCheckedException err = null;
Iterator<?> valsIter = vals != null ? vals.iterator() : null;
boolean intercept = ctx.config().getInterceptor() != null;
for (int i = 0; i < size; i++) {
GridCacheEntryEx entry = locked.get(i);
Object val = valsIter != null ? valsIter.next() : null;
if (val == null && op != DELETE)
throw new NullPointerException("Null value.");
try {
try {
if (!ctx.isAllLocked(entry, filter)) {
if (log.isDebugEnabled())
log.debug("Entry did not pass the filter (will skip write) [entry=" + entry + ", filter=" + Arrays.toString(filter) + ']');
continue;
}
} catch (IgniteCheckedException e) {
if (err == null)
err = partialUpdateException();
err.add(F.asList(entry.key()), e);
continue;
}
if (op == TRANSFORM) {
ctx.kernalContext().resource().inject(val, GridResourceIoc.AnnotationSet.ENTRY_PROCESSOR, ctx.name());
EntryProcessor<Object, Object, Object> entryProcessor = (EntryProcessor<Object, Object, Object>) val;
CacheObject old = entry.innerGet(null, null, /*read-through*/
true, /*update-metrics*/
true, /*event*/
true, subjId, entryProcessor, taskName, null, keepBinary);
Object oldVal = null;
CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry<>(entry.key(), old, entry.version(), keepBinary, entry);
CacheObject updated;
Object updatedVal = null;
CacheInvokeResult invokeRes = null;
boolean validation = false;
try {
Object computed = entryProcessor.process(invokeEntry, invokeArgs);
updatedVal = ctx.unwrapTemporary(invokeEntry.getValue());
updated = ctx.toCacheObject(updatedVal);
if (computed != null)
invokeRes = CacheInvokeResult.fromResult(ctx.unwrapTemporary(computed));
if (invokeEntry.modified()) {
validation = true;
ctx.validateKeyAndValue(entry.key(), updated);
}
} catch (Exception e) {
invokeRes = CacheInvokeResult.fromError(e);
updated = old;
if (validation) {
invokeResMap.put((K) entry.key().value(ctx.cacheObjectContext(), false), invokeRes);
continue;
}
}
if (invokeRes != null)
invokeResMap.put((K) entry.key().value(ctx.cacheObjectContext(), false), invokeRes);
if (updated == null) {
if (intercept) {
IgniteBiTuple<Boolean, ?> interceptorRes = ctx.config().getInterceptor().onBeforeRemove(new CacheLazyEntry(ctx, entry.key(), invokeEntry.key(), old, oldVal, keepBinary));
if (ctx.cancelRemove(interceptorRes))
continue;
}
// Update previous batch.
if (putMap != null) {
err = updatePartialBatch(filtered, ver, writeVals, putMap, null, expiryPlc, keepBinary, err, subjId, taskName);
putMap = null;
writeVals = null;
filtered = new ArrayList<>();
}
// Start collecting new batch.
if (rmvKeys == null)
rmvKeys = new ArrayList<>(size);
rmvKeys.add(entry.key());
} else {
if (intercept) {
Object interceptorVal = ctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(ctx, entry.key(), invokeEntry.getKey(), old, oldVal, keepBinary), updatedVal);
if (interceptorVal == null)
continue;
updated = ctx.toCacheObject(ctx.unwrapTemporary(interceptorVal));
}
// Update previous batch.
if (rmvKeys != null) {
err = updatePartialBatch(filtered, ver, null, null, rmvKeys, expiryPlc, keepBinary, err, subjId, taskName);
rmvKeys = null;
filtered = new ArrayList<>();
}
if (putMap == null) {
putMap = new LinkedHashMap<>(size, 1.0f);
writeVals = new ArrayList<>(size);
}
putMap.put(entry.key(), updated);
writeVals.add(updated);
}
} else if (op == UPDATE) {
CacheObject cacheVal = ctx.toCacheObject(val);
if (intercept) {
CacheObject old = entry.innerGet(null, null, /*read-through*/
ctx.loadPreviousValue(), /*update-metrics*/
true, /*event*/
true, subjId, null, taskName, null, keepBinary);
Object interceptorVal = ctx.config().getInterceptor().onBeforePut(new CacheLazyEntry(ctx, entry.key(), old, keepBinary), val);
if (interceptorVal == null)
continue;
cacheVal = ctx.toCacheObject(ctx.unwrapTemporary(interceptorVal));
}
ctx.validateKeyAndValue(entry.key(), cacheVal);
if (putMap == null) {
putMap = new LinkedHashMap<>(size, 1.0f);
writeVals = new ArrayList<>(size);
}
putMap.put(entry.key(), cacheVal);
writeVals.add(cacheVal);
} else {
assert op == DELETE;
if (intercept) {
CacheObject old = entry.innerGet(null, null, /*read-through*/
ctx.loadPreviousValue(), /*update-metrics*/
true, /*event*/
true, subjId, null, taskName, null, keepBinary);
IgniteBiTuple<Boolean, ?> interceptorRes = ctx.config().getInterceptor().onBeforeRemove(new CacheLazyEntry(ctx, entry.key(), old, keepBinary));
if (ctx.cancelRemove(interceptorRes))
continue;
}
if (rmvKeys == null)
rmvKeys = new ArrayList<>(size);
rmvKeys.add(entry.key());
}
filtered.add(entry);
} catch (IgniteCheckedException e) {
if (err == null)
err = partialUpdateException();
err.add(F.asList(entry.key()), e);
} catch (GridCacheEntryRemovedException ignore) {
assert false : "Entry cannot become obsolete while holding lock.";
}
}
// Store final batch.
if (putMap != null || rmvKeys != null) {
err = updatePartialBatch(filtered, ver, writeVals, putMap, rmvKeys, expiryPlc, keepBinary, err, subjId, taskName);
} else
assert filtered.isEmpty();
if (err != null)
throw err;
return invokeResMap;
} finally {
unlockEntries(locked);
}
}
Aggregations