aboutsummaryrefslogtreecommitdiff
path: root/repository
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-06 01:48:44 +0800
committerGravatar Runxi Yu2026-03-06 01:48:44 +0800
commit120509f0aad0e945d8e0fc90a822fa904fb70b68 (patch)
tree20a541f059591b35795a1a5d3b7dcf48ec711b6a /repository
parentrefstore/loose: Fix package-level comment (diff)
signatureNo signature
repository: Refactor v0.1.55
Diffstat (limited to 'repository')
-rw-r--r--repository/algorithm.go (renamed from repository/open_config.go)22
-rw-r--r--repository/close.go32
-rw-r--r--repository/config.go32
-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.go54
-rw-r--r--repository/stored.go (renamed from repository/read_stored.go)0
-rw-r--r--repository/traversal_bench_test.go73
-rw-r--r--repository/traversal_helpers_test.go102
-rw-r--r--repository/traversal_test.go48
-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