diff options
| author | 2026-03-06 01:48:44 +0800 | |
|---|---|---|
| committer | 2026-03-06 01:48:44 +0800 | |
| commit | 120509f0aad0e945d8e0fc90a822fa904fb70b68 (patch) | |
| tree | 20a541f059591b35795a1a5d3b7dcf48ec711b6a | |
| parent | refstore/loose: Fix package-level comment (diff) | |
| signature | No signature | |
repository: Refactor v0.1.55
| -rw-r--r-- | repository/algorithm.go (renamed from repository/open_config.go) | 22 | ||||
| -rw-r--r-- | repository/close.go | 32 | ||||
| -rw-r--r-- | repository/config.go | 32 | ||||
| -rw-r--r-- | repository/objects.go (renamed from repository/open_objects.go) | 5 | ||||
| -rw-r--r-- | repository/refs.go (renamed from repository/open_refs.go) | 5 | ||||
| -rw-r--r-- | repository/refs_test.go (renamed from repository/repository_test.go) | 0 | ||||
| -rw-r--r-- | repository/repository.go | 54 | ||||
| -rw-r--r-- | repository/stored.go (renamed from repository/read_stored.go) | 0 | ||||
| -rw-r--r-- | repository/traversal_bench_test.go | 73 | ||||
| -rw-r--r-- | repository/traversal_helpers_test.go | 102 | ||||
| -rw-r--r-- | repository/traversal_test.go | 48 | ||||
| -rw-r--r-- | repository/tree.go (renamed from repository/tree_resolve.go) | 0 |
12 files changed, 127 insertions, 246 deletions
diff --git a/repository/open_config.go b/repository/algorithm.go index fcc9793c..22326cbd 100644 --- a/repository/open_config.go +++ b/repository/algorithm.go @@ -2,28 +2,11 @@ package repository import ( "fmt" - "os" "codeberg.org/lindenii/furgit/config" "codeberg.org/lindenii/furgit/objectid" ) -func parseRepositoryConfig(root *os.Root) (*config.Config, error) { - configFile, err := root.Open("config") - if err != nil { - return nil, fmt.Errorf("repository: open config: %w", err) - } - - defer func() { _ = configFile.Close() }() - - cfg, err := config.ParseConfig(configFile) - if err != nil { - return nil, fmt.Errorf("repository: parse config: %w", err) - } - - return cfg, nil -} - func detectObjectAlgorithm(cfg *config.Config) (objectid.Algorithm, error) { algoName := cfg.Lookup("extensions", "", "objectformat").Value if algoName == "" { @@ -37,3 +20,8 @@ func detectObjectAlgorithm(cfg *config.Config) (objectid.Algorithm, error) { return algo, nil } + +// Algorithm returns the repository object ID algorithm. +func (repo *Repository) Algorithm() objectid.Algorithm { + return repo.algo +} diff --git a/repository/close.go b/repository/close.go new file mode 100644 index 00000000..998742d0 --- /dev/null +++ b/repository/close.go @@ -0,0 +1,32 @@ +package repository + +import "errors" + +// Close closes owned stores and filesystem roots. +// The behavior of the repo after Close is undefined. +func (repo *Repository) Close() error { + var errs []error + + if repo.refs != nil { + err := repo.refs.Close() + if err != nil { + errs = append(errs, err) + } + } + + if repo.objects != nil { + err := repo.objects.Close() + if err != nil { + errs = append(errs, err) + } + } + + if repo.objectsLooseForWritingOnly != nil { + err := repo.objectsLooseForWritingOnly.Close() + if err != nil { + errs = append(errs, err) + } + } + + return errors.Join(errs...) +} diff --git a/repository/config.go b/repository/config.go new file mode 100644 index 00000000..de33e2c3 --- /dev/null +++ b/repository/config.go @@ -0,0 +1,32 @@ +package repository + +import ( + "fmt" + "os" + + "codeberg.org/lindenii/furgit/config" +) + +func parseRepositoryConfig(root *os.Root) (*config.Config, error) { + configFile, err := root.Open("config") + if err != nil { + return nil, fmt.Errorf("repository: open config: %w", err) + } + + defer func() { _ = configFile.Close() }() + + cfg, err := config.ParseConfig(configFile) + if err != nil { + return nil, fmt.Errorf("repository: parse config: %w", err) + } + + return cfg, nil +} + +// Config returns the parsed repository configuration snapshot. +// +// The returned pointer is owned by Repository. Callers should treat it as +// read-only. +func (repo *Repository) Config() *config.Config { + return repo.config +} diff --git a/repository/open_objects.go b/repository/objects.go index 61fc0f93..c8278150 100644 --- a/repository/open_objects.go +++ b/repository/objects.go @@ -62,3 +62,8 @@ func openObjectStore(root *os.Root, algo objectid.Algorithm) (objectstore.Store, return objectsChain, objectsLooseForWritingOnly, nil } + +// Objects returns the configured object store. +func (repo *Repository) Objects() objectstore.Store { + return repo.objects +} diff --git a/repository/open_refs.go b/repository/refs.go index c802b4fa..bdcab843 100644 --- a/repository/open_refs.go +++ b/repository/refs.go @@ -45,3 +45,8 @@ func openRefStore(root *os.Root, algo objectid.Algorithm) (out refstore.Store, e return refchain.New(backends...), nil } + +// Refs returns the configured ref store. +func (repo *Repository) Refs() refstore.Store { + return repo.refs +} diff --git a/repository/repository_test.go b/repository/refs_test.go index 8d8c604e..8d8c604e 100644 --- a/repository/repository_test.go +++ b/repository/refs_test.go diff --git a/repository/repository.go b/repository/repository.go index 02945456..aeb048bd 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -2,8 +2,6 @@ package repository import ( - "errors" - "codeberg.org/lindenii/furgit/config" "codeberg.org/lindenii/furgit/objectid" "codeberg.org/lindenii/furgit/objectstore" @@ -23,55 +21,3 @@ type Repository struct { objectsLooseForWritingOnly *objectloose.Store refs refstore.Store } - -// Algorithm returns the repository object ID algorithm. -func (repo *Repository) Algorithm() objectid.Algorithm { - return repo.algo -} - -// Config returns the parsed repository configuration snapshot. -// -// The returned pointer is owned by Repository. Callers should treat it as -// read-only. -func (repo *Repository) Config() *config.Config { - return repo.config -} - -// Objects returns the configured object store. -func (repo *Repository) Objects() objectstore.Store { - return repo.objects -} - -// Refs returns the configured ref store. -func (repo *Repository) Refs() refstore.Store { - return repo.refs -} - -// Close closes owned stores and filesystem roots. -// The behavior of the repo after Close is undefined. -func (repo *Repository) Close() error { - var errs []error - - if repo.refs != nil { - err := repo.refs.Close() - if err != nil { - errs = append(errs, err) - } - } - - if repo.objects != nil { - err := repo.objects.Close() - if err != nil { - errs = append(errs, err) - } - } - - if repo.objectsLooseForWritingOnly != nil { - err := repo.objectsLooseForWritingOnly.Close() - if err != nil { - errs = append(errs, err) - } - } - - return errors.Join(errs...) -} diff --git a/repository/read_stored.go b/repository/stored.go index 1e92dc40..1e92dc40 100644 --- a/repository/read_stored.go +++ b/repository/stored.go diff --git a/repository/traversal_bench_test.go b/repository/traversal_bench_test.go deleted file mode 100644 index ada0f8d8..00000000 --- a/repository/traversal_bench_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package repository_test - -import ( - "os" - "strings" - "testing" - - "codeberg.org/lindenii/furgit/object" - "codeberg.org/lindenii/furgit/repository" -) - -const benchRepoPathEnv = "FURGIT_BENCH_REPO" - -// BenchmarkTraverseHeadTree measures iterative traversal of HEAD's root tree. -// -// Set FURGIT_BENCH_REPO to a repository path (typically .git or a bare repo) -// before running this benchmark. -func BenchmarkTraverseHeadTree(b *testing.B) { - repoPath := strings.TrimSpace(os.Getenv(benchRepoPathEnv)) - if repoPath == "" { - b.Fatalf("missing %s", benchRepoPathEnv) - } - - root, err := os.OpenRoot(repoPath) - if err != nil { - b.Fatalf("os.OpenRoot(%q): %v", repoPath, err) - } - - b.Cleanup(func() { - _ = root.Close() - }) - - repo, err := repository.Open(root) - if err != nil { - b.Fatalf("repository.Open(root for %q): %v", repoPath, err) - } - - b.Cleanup(func() { - _ = repo.Close() - }) - - head, err := repo.Refs().ResolveFully("HEAD") - if err != nil { - b.Fatalf("ResolveRefFully(HEAD): %v", err) - } - - stored, err := repo.ReadStored(head.ID) - if err != nil { - b.Fatalf("ReadStored(%s): %v", head.ID, err) - } - - commit, ok := stored.Object().(*object.Commit) - if !ok { - b.Fatalf("HEAD object type %T, want *object.Commit", stored.Object()) - } - - b.ReportAllocs() - b.ResetTimer() - - var lastCount int - for b.Loop() { - lastCount, err = traverseTreeIter(repo, commit.Tree) - if err != nil { - b.Fatalf("traverseTreeIter: %v", err) - } - } - - b.StopTimer() - - if lastCount <= 0 { - b.Fatalf("traverseTreeIter count = %d, want > 0", lastCount) - } -} diff --git a/repository/traversal_helpers_test.go b/repository/traversal_helpers_test.go deleted file mode 100644 index 143d3b62..00000000 --- a/repository/traversal_helpers_test.go +++ /dev/null @@ -1,102 +0,0 @@ -package repository_test - -import ( - "codeberg.org/lindenii/furgit/object" - "codeberg.org/lindenii/furgit/objectid" - "codeberg.org/lindenii/furgit/repository" -) - -type treeWalkFrame struct { - id objectid.ObjectID - isTree bool -} - -func traverseTreeIter(repo *repository.Repository, root objectid.ObjectID) (int, error) { - stack := []treeWalkFrame{{id: root, isTree: true}} - total := 0 - - for len(stack) > 0 { - frame := stack[len(stack)-1] - stack = stack[:len(stack)-1] - id := frame.id - - if !frame.isTree { - _, err := repo.Objects().ReadSize(id) - if err != nil { - return 0, err - } - - total++ - - continue - } - - tree, err := repo.ReadStoredTree(id) - if err != nil { - return 0, err - } - - total++ - - for i := len(tree.Tree().Entries) - 1; i >= 0; i-- { - entry := tree.Tree().Entries[i] - if entry.Mode == object.FileModeGitlink { - continue - } - - stack = append(stack, treeWalkFrame{ - id: entry.ID, - isTree: entry.Mode == object.FileModeDir, - }) - } - } - - 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] - - _, ok := visited[id] - if 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 -} diff --git a/repository/traversal_test.go b/repository/traversal_test.go index 47300e7f..ff3614dc 100644 --- a/repository/traversal_test.go +++ b/repository/traversal_test.go @@ -8,6 +8,7 @@ import ( "testing" "codeberg.org/lindenii/furgit/internal/testgit" + "codeberg.org/lindenii/furgit/object" "codeberg.org/lindenii/furgit/objectid" "codeberg.org/lindenii/furgit/repository" ) @@ -131,3 +132,50 @@ func walkRepositoryFromHead(t *testing.T, repoPath string) { t.Fatalf("no objects were enumerated from HEAD (%s)", fmt.Sprintf("%q", repoPath)) } } + +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] + + _, ok := visited[id] + if 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 +} diff --git a/repository/tree_resolve.go b/repository/tree.go index d4ef529e..d4ef529e 100644 --- a/repository/tree_resolve.go +++ b/repository/tree.go |
