diff options
| author | 2026-02-21 21:24:07 +0800 | |
|---|---|---|
| committer | 2026-02-21 21:31:28 +0800 | |
| commit | e6ee208f91acdc61f4e9ba2d9d450cce94477673 (patch) | |
| tree | 42302f63731ea915e51ab45c9e6fd915868a27c0 /repository/traversal_helpers_test.go | |
| parent | *: Fix nosec (diff) | |
| signature | No signature | |
repository: Add full-traversal benchmark
Diffstat (limited to 'repository/traversal_helpers_test.go')
| -rw-r--r-- | repository/traversal_helpers_test.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/repository/traversal_helpers_test.go b/repository/traversal_helpers_test.go new file mode 100644 index 00000000..09cd61bd --- /dev/null +++ b/repository/traversal_helpers_test.go @@ -0,0 +1,79 @@ +package repository_test + +import ( + "codeberg.org/lindenii/furgit/object" + "codeberg.org/lindenii/furgit/objectid" + "codeberg.org/lindenii/furgit/repository" +) + +func traverseTreeIter(repo *repository.Repository, root objectid.ObjectID) (int, error) { + stack := []objectid.ObjectID{root} + total := 0 + + for len(stack) > 0 { + id := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + stored, err := repo.ReadStored(id) + if err != nil { + return 0, err + } + total++ + + tree, ok := stored.Object().(*object.Tree) + if !ok { + continue + } + for i := len(tree.Entries) - 1; i >= 0; i-- { + entry := tree.Entries[i] + if entry.Mode == object.FileModeGitlink { + continue + } + stack = append(stack, entry.ID) + } + } + + return total, nil +} + +func traverseReachableIter(repo *repository.Repository, root objectid.ObjectID) (int, error) { + stack := []objectid.ObjectID{root} + visited := make(map[objectid.ObjectID]struct{}) + total := 0 + + for len(stack) > 0 { + id := stack[len(stack)-1] + stack = stack[:len(stack)-1] + if _, ok := visited[id]; ok { + continue + } + visited[id] = struct{}{} + + stored, err := repo.ReadStored(id) + if err != nil { + return 0, err + } + total++ + + switch obj := stored.Object().(type) { + case *object.Commit: + stack = append(stack, obj.Tree) + stack = append(stack, obj.Parents...) + case *object.Tree: + for i := len(obj.Entries) - 1; i >= 0; i-- { + entry := obj.Entries[i] + if entry.Mode == object.FileModeGitlink { + continue + } + stack = append(stack, entry.ID) + } + case *object.Tag: + stack = append(stack, obj.Target) + case *object.Blob: + default: + // Unknown parsed object variants are treated as leaves. + } + } + + return total, nil +} |
