From 5b15b9a81acfe2c5a7a300a31b51bf1176a67e7b Mon Sep 17 00:00:00 2001 From: Sahil-4555 Date: Fri, 17 Oct 2025 08:57:35 +0530 Subject: [PATCH 1/2] optimize parse path --- encoding/ssz/query/path.go | 85 ++++++++++++++++----------------- encoding/ssz/query/path_test.go | 22 +++++++++ 2 files changed, 63 insertions(+), 44 deletions(-) diff --git a/encoding/ssz/query/path.go b/encoding/ssz/query/path.go index a45ed171d395..b3e509a0eb1f 100644 --- a/encoding/ssz/query/path.go +++ b/encoding/ssz/query/path.go @@ -15,48 +15,45 @@ type PathElement struct { } func ParsePath(rawPath string) ([]PathElement, error) { - // We use dot notation, so we split the path by '.'. - rawElements := strings.Split(rawPath, ".") - if len(rawElements) == 0 { - return nil, errors.New("empty path provided") - } - - if rawElements[0] == "" { - // Remove leading dot if present - rawElements = rawElements[1:] - } - - var path []PathElement - for _, elem := range rawElements { - if elem == "" { - return nil, errors.New("invalid path: consecutive dots or trailing dot") - } - - fieldName := elem - var index *uint64 - - // Check for index notation, e.g., "field[0]" - if strings.Contains(elem, "[") { - parts := strings.SplitN(elem, "[", 2) - if len(parts) != 2 { - return nil, fmt.Errorf("invalid index notation in path element %s", elem) - } - - fieldName = parts[0] - indexPart := strings.TrimSuffix(parts[1], "]") - if indexPart == "" { - return nil, errors.New("index cannot be empty") - } - - indexValue, err := strconv.ParseUint(indexPart, 10, 64) - if err != nil { - return nil, fmt.Errorf("invalid index in path element %s: %w", elem, err) - } - index = &indexValue - } - - path = append(path, PathElement{Name: fieldName, Index: index}) - } - - return path, nil + if rawPath == "" { + return nil, errors.New("empty path provided") + } + + rawElements := strings.Split(rawPath, ".") + if rawElements[0] == "" { + rawElements = rawElements[1:] + if len(rawElements) == 0 { + return nil, errors.New("invalid path: only a dot") + } + } + + path := make([]PathElement, 0, len(rawElements)) + for _, elem := range rawElements { + if elem == "" { + return nil, errors.New("invalid path: consecutive dots or trailing dot") + } + + i := strings.IndexByte(elem, '[') + if i < 0 { + path = append(path, PathElement{Name: elem}) + continue + } + + if elem[len(elem)-1] != ']' || len(elem)-1 <= i { + return nil, fmt.Errorf("invalid index notation in path element %s", elem) + } + fieldName := elem[:i] + indexPart := elem[i+1 : len(elem)-1] + if indexPart == "" { + return nil, errors.New("index cannot be empty") + } + + val, err := strconv.ParseUint(indexPart, 10, 64) + if err != nil { + return nil, fmt.Errorf("invalid index in path element %s: %w", elem, err) + } + path = append(path, PathElement{Name: fieldName, Index: &val}) + } + return path, nil } + diff --git a/encoding/ssz/query/path_test.go b/encoding/ssz/query/path_test.go index 0594459d38bb..2557e2d3ea9d 100644 --- a/encoding/ssz/query/path_test.go +++ b/encoding/ssz/query/path_test.go @@ -51,3 +51,25 @@ func TestParsePath(t *testing.T) { }) } } + +func BenchmarkParsePath(b *testing.B) { + benchmarks := []struct { + name string + path string + }{ + {name: "simple path", path: "data.target.root"}, + {name: "path with leading dot", path: ".data.target.root"}, + {name: "nested arrays", path: "data.targets[15].values[42].leaf"}, + {name: "deep nested", path: "root.level1.level2.level3.level4.level5"}, + {name: "path with multiple indices", path: "root.array1[1].array2[2].array3[3].end"}, + } + + for _, bm := range benchmarks { + b.Run(bm.name, func(b *testing.B) { + for b.Loop() { + _, _ = query.ParsePath(bm.path) + } + }) + } +} + From 58c64cf8342ba11994882a27b5a81f46c2839c10 Mon Sep 17 00:00:00 2001 From: Sahil-4555 Date: Fri, 17 Oct 2025 09:25:55 +0530 Subject: [PATCH 2/2] added changelog --- changelog/sahil-4555-SSZ-QL: Access n-th element in List.m.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog/sahil-4555-SSZ-QL: Access n-th element in List.m.md diff --git a/changelog/sahil-4555-SSZ-QL: Access n-th element in List.m.md b/changelog/sahil-4555-SSZ-QL: Access n-th element in List.m.md new file mode 100644 index 000000000000..16115451125f --- /dev/null +++ b/changelog/sahil-4555-SSZ-QL: Access n-th element in List.m.md @@ -0,0 +1,3 @@ +### Fixed + +- refactor the ParsePath function to improve performance \ No newline at end of file