dongjoon-hyun commented on code in PR #60196:
URL: https://github.com/apache/spark/pull/60196#discussion_r4503019880


##########
core/src/main/java/org/apache/spark/unsafe/map/BytesToBytesMap.java:
##########
@@ -1037,18 +1095,20 @@ public boolean append(Object kbase, long koff, int 
klen, Object vbase, long voff
    * @return whether there is enough space to allocate the new page.
    */
   private boolean acquireNewPage(long required) {
+    final long size = Math.max(nextPageSizeBytes, required);
     final MemoryBlock page;
     try {
-      page = allocatePage(required);
+      page = allocatePage(size, required);
     } catch (SparkOutOfMemoryError e) {
       return false;
     }
     // Retaining exact-fit minimum-retry pages would consume one page-table 
slot per map entry.
-    if (required < pageSizeBytes && page.size() == required &&
+    if (required < size && page.size() == required &&
         isPageAllocationFromMinimumRetry(page)) {
       freePage(page);
       return false;
     }
+    nextPageSizeBytes = Math.min(pageSizeBytes, nextPageSizeBytes * 2);

Review Comment:
   Good catch. The growing pages now stop at exactly one page size: the last of 
them is cut to what is left to reach the page size, so with a 64 MiB page size 
the pages are 1, 2, 4, 8, 16, 32 and 1 MiB before the 64 MiB pages. The total 
is reset in `reset()`, and maps created through the existing constructors still 
request the page size for every page. `dataPagesGrowFromInitialPageSize` now 
uses a 6 KiB page size and checks that the growing pages are 1, 2 and 3 KiB 
before the 6 KiB pages.
   



##########
sql/core/src/main/scala/org/apache/spark/sql/execution/joins/HashedRelation.scala:
##########
@@ -452,6 +453,17 @@ private[joins] class UnsafeHashedRelation(
 
 private[joins] object UnsafeHashedRelation {
 
+  /**
+   * The size of the first data page of the map. Later pages double in size up 
to the page size.
+   *
+   * Otherwise `BytesToBytesMap` rounds its first page up to the page size 
(`spark.buffer.pageSize`,
+   * up to 64 MiB), so even a relation with a few rows reserves 64 MiB. A task 
that keeps many

Review Comment:
   Thanks, updated. The comment now says that even a few rows reserve a full 
page of `spark.buffer.pageSize` or a default of up to 64 MiB.
   



##########
core/src/main/java/org/apache/spark/unsafe/map/BytesToBytesMap.java:
##########
@@ -175,6 +175,17 @@ private enum MapState {
    */
   private final long pageSizeBytes;
 
+  /**
+   * The size of the first data page, at most {@link #pageSizeBytes}.

Review Comment:
   Updated. The `pageSizeBytes` doc now calls it the maximum size of regular 
data pages, which a map with a smaller initial page size grows its pages up to, 
and says that a record larger than a page gets a page of its own size.
   



##########
core/src/main/java/org/apache/spark/unsafe/map/BytesToBytesMap.java:
##########
@@ -259,10 +290,37 @@ public BytesToBytesMap(
       throw new IllegalArgumentException("Page size " + pageSizeBytes + " 
cannot exceed " +
         TaskMemoryManager.MAXIMUM_PAGE_SIZE_BYTES);
     }
+    if (initialPageSizeBytes <= 0) {
+      throw new IllegalArgumentException("Initial page size must be greater 
than 0");
+    }
+    this.initialPageSizeBytes = Math.min(initialPageSizeBytes, pageSizeBytes);

Review Comment:
   Added. The test also checks that a map whose initial page size is larger 
than its page size starts with a page of the page size.
   



##########
sql/core/src/main/scala/org/apache/spark/sql/execution/joins/HashedRelation.scala:
##########
@@ -469,7 +481,8 @@ private[joins] object UnsafeHashedRelation {
       taskMemoryManager,
       // Only 70% of the slots can be used before growing, more capacity help 
to reduce collision
       (sizeEstimate * 1.5 + 1).toInt,
-      pageSizeBytes)
+      pageSizeBytes,

Review Comment:
   Added a `private[joins]` accessor for the map's page size. The test now 
checks that a built relation and its Java and Kryo copies grow their pages up 
to the `SparkEnv` page size.
   



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to