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]

Reply via email to