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 772af76b2 perf(variant): avoid copying unescaped path members (#2242)
772af76b2 is described below

commit 772af76b29cb50c546046f728884ba69490cee5d
Author: Minh Vu <[email protected]>
AuthorDate: Wed Oct 21 22:43:27 2026 +0200

    perf(variant): avoid copying unescaped path members (#2242)
    
    * perf(variant): avoid copying unescaped path members
    
    Signed-off-by: Minh Vu <[email protected]>
    
    * perf(variant): avoid retaining path for empty selectors
    
    * style(variant): satisfy nlreturn for quoted member parsing
    
    ---------
    
    Signed-off-by: Minh Vu <[email protected]>
---
 variant_path.go            | 20 +++++++++--
 variant_path_bench_test.go | 86 ++++++++++++++++++++++++++++++++++++++++++++++
 variant_path_test.go       |  5 +++
 3 files changed, 108 insertions(+), 3 deletions(-)

diff --git a/variant_path.go b/variant_path.go
index 34080932e..307ddd347 100644
--- a/variant_path.go
+++ b/variant_path.go
@@ -127,20 +127,33 @@ func parseBracketSelector(s, path string) (string, int, 
error) {
                return "", 0, fmt.Errorf("%w: unsupported variant path %q (only 
quoted member selectors like ['name'] are supported)", ErrInvalidArgument, path)
        }
 
+       // Delay copying until an escape is found. Plain quoted members can
+       // reference the original path without allocating a new string.
        var b strings.Builder
+       start := 2
        for i := 2; i < len(s); {
-               c := s[i]
-               switch c {
+               switch s[i] {
                case '\'':
                        if i+1 >= len(s) || s[i+1] != ']' {
                                return "", 0, fmt.Errorf("%w: invalid variant 
path %q (expected ']' after quoted member)", ErrInvalidArgument, path)
                        }
 
+                       if start == 2 {
+                               if i == 2 {
+                                       // Avoid retaining the input path for 
an empty member.
+                                       return "", i + 2, nil
+                               }
+
+                               return s[2:i], i + 2, nil
+                       }
+                       b.WriteString(s[start:i])
+
                        return b.String(), i + 2, nil
                case '\\':
                        if i+1 >= len(s) {
                                return "", 0, fmt.Errorf("%w: invalid variant 
path %q (dangling escape)", ErrInvalidArgument, path)
                        }
+                       b.WriteString(s[start:i])
                        switch e := s[i+1]; e {
                        case 'b':
                                b.WriteByte('\b')
@@ -161,14 +174,15 @@ func parseBracketSelector(s, path string) (string, int, 
error) {
                                }
                                b.WriteRune(r)
                                i += consumed
+                               start = i
 
                                continue
                        default:
                                return "", 0, fmt.Errorf("%w: invalid variant 
path %q (unknown escape \\%c)", ErrInvalidArgument, path, e)
                        }
                        i += 2
+                       start = i
                default:
-                       b.WriteByte(c)
                        i++
                }
        }
diff --git a/variant_path_bench_test.go b/variant_path_bench_test.go
new file mode 100644
index 000000000..4cbb4d229
--- /dev/null
+++ b/variant_path_bench_test.go
@@ -0,0 +1,86 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package iceberg
+
+import "testing"
+
+var (
+       benchmarkVariantPathMember   string
+       benchmarkVariantPathConsumed int
+       benchmarkVariantPathFields   []string
+)
+
+// BenchmarkParseBracketSelector measures the selector fast path separately.
+func BenchmarkParseBracketSelector(b *testing.B) {
+       for _, tt := range []struct {
+               name, selector string
+       }{
+               {"Short", "['id']"},
+               {"Medium", "['event_type']"},
+               {"Long", 
"['this_is_a_very_long_field_name_for_analytic_queries']"},
+               {"UTF8", "['naïve_東京_データ']"},
+               {"Escaped", "['o\\'brien']"},
+               {"UnicodeEscape", "['\\uD840\\uDC00']"},
+       } {
+               b.Run(tt.name, func(b *testing.B) {
+                       path := "$" + tt.selector
+                       b.ReportAllocs()
+
+                       var member string
+                       var consumed int
+                       var err error
+                       for range b.N {
+                               member, consumed, err = 
parseBracketSelector(tt.selector, path)
+                       }
+                       if err != nil {
+                               b.Fatal(err)
+                       }
+                       benchmarkVariantPathMember = member
+                       benchmarkVariantPathConsumed = consumed
+               })
+       }
+}
+
+// BenchmarkParseVariantPath measures the complete parser, including slice 
allocations.
+func BenchmarkParseVariantPath(b *testing.B) {
+       for _, tt := range []struct {
+               name, path string
+       }{
+               {"One", "$['event_type']"},
+               {"Two", "$['location']['latitude']"},
+               {"Four", "$['customer']['account']['profile']['event_type']"},
+               {"UTF8", "$['naïve_東京_データ']"},
+               {"Escaped", "$['o\\'brien']"},
+               {"Mixed", "$['customer'].profile['created_at']"},
+               {"DotOnly", "$.customer.profile.created_at"},
+       } {
+               b.Run(tt.name, func(b *testing.B) {
+                       b.ReportAllocs()
+
+                       var fields []string
+                       var err error
+                       for range b.N {
+                               fields, err = parseVariantPath(tt.path)
+                       }
+                       if err != nil {
+                               b.Fatal(err)
+                       }
+                       benchmarkVariantPathFields = fields
+               })
+       }
+}
diff --git a/variant_path_test.go b/variant_path_test.go
index a9a113e23..2675e540c 100644
--- a/variant_path_test.go
+++ b/variant_path_test.go
@@ -57,6 +57,11 @@ func TestParseVariantPath(t *testing.T) {
                {"underscore and digits", "$._a1.b2", []string{"_a1", "b2"}},
                {"non-ascii first char", "$.naïve", []string{"naïve"}},
                {"bracket notation", "$['event_id']", []string{"event_id"}},
+               {"bracket empty quoted member", "$['']", []string{""}},
+               {"bracket plain unicode", "$['naïve_東京']", 
[]string{"naïve_東京"}},
+               {"bracket literal delimiters", "$['a.b[0]']", 
[]string{"a.b[0]"}},
+               {"bracket two different escapes", "$['a\\nb\\tc']", 
[]string{"a\nb\tc"}},
+               {"bracket mixed escaped and plain runs", 
"$['pre\\'mid\\\\end']", []string{"pre'mid\\end"}},
                {"bracket nested", "$['location']['latitude']", 
[]string{"location", "latitude"}},
                {"bracket dotted name", "$['user.name']", 
[]string{"user.name"}},
                {"bracket leading digit", "$['1abc']", []string{"1abc"}},

Reply via email to