You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by ze...@apache.org on 2026/10/21 20:49:48 UTC

(iceberg-go) branch main updated: perf(puffin): skip sorting blobs already in offset order (#2250)

This is an automated email from the ASF dual-hosted git repository.

zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-go.git


The following commit(s) were added to refs/heads/main by this push:
     new 172b4f0e5 perf(puffin): skip sorting blobs already in offset order (#2250)
172b4f0e5 is described below

commit 172b4f0e5790a7d66cd0a16bb4751fbf83449469
Author: Minh Vu <vu...@gmail.com>
AuthorDate: Wed Oct 21 22:49:40 2026 +0200

    perf(puffin): skip sorting blobs already in offset order (#2250)
    
    * perf(puffin): skip sorting blobs already in offset order
    
    Signed-off-by: Minh Vu <vu...@gmail.com>
    
    * style(puffin): satisfy nlreturn before breaking sort scan
    
    ---------
    
    Signed-off-by: Minh Vu <vu...@gmail.com>
---
 puffin/puffin_reader.go | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/puffin/puffin_reader.go b/puffin/puffin_reader.go
index 186876105..951961456 100644
--- a/puffin/puffin_reader.go
+++ b/puffin/puffin_reader.go
@@ -620,19 +620,30 @@ func (r *Reader) ReadAllBlobs() ([]*BlobData, error) {
 		return nil, nil
 	}
 
-	// Keep only indexes in the temporary read-order slice.
-	// Results retain defensive metadata copies in footer order.
-	order := make([]int, len(footer.Blobs))
-	for i := range order {
-		order[i] = i
+	// Footer metadata is usually already in offset order. Only allocate
+	// and sort indexes if it is not, keeping reads in physical order.
+	var order []int
+	for i := 1; i < len(footer.Blobs); i++ {
+		if footer.Blobs[i-1].Offset > footer.Blobs[i].Offset {
+			order = make([]int, len(footer.Blobs))
+			for j := range order {
+				order[j] = j
+			}
+			slices.SortFunc(order, func(a, b int) int {
+				return cmp.Compare(footer.Blobs[a].Offset, footer.Blobs[b].Offset)
+			})
+
+			break
+		}
 	}
-	slices.SortFunc(order, func(a, b int) int {
-		return cmp.Compare(footer.Blobs[a].Offset, footer.Blobs[b].Offset)
-	})
 
-	// Read blobs in offset order, store in original order
+	// Read blobs in offset order, store in original order.
 	results := make([]*BlobData, len(footer.Blobs))
-	for _, index := range order {
+	for i := range footer.Blobs {
+		index := i
+		if order != nil {
+			index = order[i]
+		}
 		meta := footer.Blobs[index]
 		data, err := r.readBlobData(meta)
 		if err != nil {