wernerdv commented on code in PR #13554:
URL: https://github.com/apache/ignite/pull/13554#discussion_r4393398851
##########
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java:
##########
@@ -2978,6 +2986,52 @@ else if (GridDhtCacheEntry.ReaderId.contains(readers,
nearNode.id())) {
}
}
+ /**
+ * Reserves free-list pages for the <b>total</b> size of all rows in the
batch: size-aware admission control for
+ * the primary atomic path, which acquires entry locks via {@link
#lockEntries} before {@code innerUpdate} and so
+ * cannot reserve (or evict) per entry there. Reserving before {@link
#lockEntries} makes room for the data pages
+ * of all rows of a batch with known value sizes, so their inserts are not
expected to hit an out-of-memory in
+ * {@code FreeList.insertDataRow} (pages outside the reservation, e.g.
B+tree pages, are covered by the empty pages
+ * pool).
+ * <p>
+ * The full row size is reserved for updates too: an update inserts the
new row before removing the old one, unless
+ * it is done in place (same row size, no SQL indexes, unchanged expire
time), which can't be known before the entry
+ * lock. For in-place updates near the eviction threshold this keeps extra
empty pages free (up to the size of the
+ * rows being written concurrently) instead of using them for data; it is
not a correctness issue.
+ *
+ * @param req Update request.
+ * @return Reserved pages to release via {@code releaseInRegion}, or
{@code 0} if reservation is not engaged.
+ * @throws IgniteCheckedException If failed.
+ */
+ private long reserveBatchSpace(GridNearAtomicAbstractUpdateRequest req)
throws IgniteCheckedException {
+ DataRegion dataRegion = ctx.dataRegion();
+
+ // Skip computing the row sizes (it may require marshalling) if the
reservation is not engaged for the region.
+ if (!ctx.shared().database().isReserveEnabled(dataRegion))
+ return 0;
+
+ CacheObjectValueContext coctx = ctx.cacheObjectContext();
+
+ boolean storeCacheId = ctx.group().storeCacheIdInDataPage();
+
+ long sumRowSize = 0;
+
+ for (int i = 0; i < req.size(); i++) {
+ KeyCacheObject key = req.key(i);
+
+ CacheObject val = req.writeValue(i);
Review Comment:
For invoke, writeValue() doesn't return the entry processor. Entry
processors are kept separately (entryProcessors in
GridNearAtomicFullUpdateRequest, and writeValue() returns null in
GridNearAtomicSingleUpdateInvokeRequest), so for invoke only a row without a
value (key, version and row header) was reserved.
The javadoc of writeValue() ("either value, or transform closure") is
misleading, though, so I made it explicit: the value is taken for UPDATE only,
with a comment that a transform result is unknown before the entry processor
runs. DELETE is skipped since the previous fix.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]