aboutsummaryrefslogtreecommitdiff
path: root/reachability
diff options
context:
space:
mode:
Diffstat (limited to 'reachability')
-rw-r--r--reachability/domain.go11
-rw-r--r--reachability/helpers.go72
-rw-r--r--reachability/integration_test.go3
-rw-r--r--reachability/reachability.go12
-rw-r--r--reachability/unit_test.go15
-rw-r--r--reachability/walk_expand_commits.go24
-rw-r--r--reachability/walk_expand_objects.go37
-rw-r--r--reachability/walk_seq.go2
-rw-r--r--reachability/walk_verify.go10
9 files changed, 46 insertions, 140 deletions
diff --git a/reachability/domain.go b/reachability/domain.go
index 9fcf721e..1fe24fe8 100644
--- a/reachability/domain.go
+++ b/reachability/domain.go
@@ -1,5 +1,7 @@
package reachability
+import "fmt"
+
// Domain specifies which graph edges are traversed.
type Domain uint8
@@ -9,3 +11,12 @@ const (
// DomainObjects traverses full commit/tree/blob objects.
DomainObjects
)
+
+func validateDomain(domain Domain) error {
+ switch domain {
+ case DomainCommits, DomainObjects:
+ return nil
+ default:
+ return fmt.Errorf("reachability: invalid domain %d", domain)
+ }
+}
diff --git a/reachability/helpers.go b/reachability/helpers.go
deleted file mode 100644
index d2459f36..00000000
--- a/reachability/helpers.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package reachability
-
-import (
- "errors"
- "fmt"
-
- giterrors "codeberg.org/lindenii/furgit/errors"
- objectid "codeberg.org/lindenii/furgit/object/id"
- objectstore "codeberg.org/lindenii/furgit/object/store"
- objecttype "codeberg.org/lindenii/furgit/object/type"
-)
-
-func validateDomain(domain Domain) error {
- switch domain {
- case DomainCommits, DomainObjects:
- return nil
- default:
- return fmt.Errorf("reachability: invalid domain %d", domain)
- }
-}
-
-func containsOID(set map[objectid.ObjectID]struct{}, id objectid.ObjectID) bool {
- if len(set) == 0 {
- return false
- }
-
- _, ok := set[id]
-
- return ok
-}
-
-// The following helpers exist because we don't have unified error handling across the entire project.
-// This will be fixed later.
-
-func (walk *Walk) readHeaderType(id objectid.ObjectID) (objecttype.Type, error) {
- return walk.reachability.readHeaderType(id)
-}
-
-func (r *Reachability) readHeaderType(id objectid.ObjectID) (objecttype.Type, error) {
- ty, _, err := r.store.ReadHeader(id)
- if err != nil {
- if errors.Is(err, objectstore.ErrObjectNotFound) {
- return objecttype.TypeInvalid, &giterrors.ObjectMissingError{OID: id}
- }
-
- return objecttype.TypeInvalid, err
- }
-
- return ty, nil
-}
-
-func (walk *Walk) readBytesContent(id objectid.ObjectID) ([]byte, error) {
- content, err := walk.reachability.readBytesContent(id)
- if err != nil {
- return nil, err
- }
-
- return content, nil
-}
-
-func (r *Reachability) readBytesContent(id objectid.ObjectID) ([]byte, error) {
- _, content, err := r.store.ReadBytesContent(id)
- if err != nil {
- if errors.Is(err, objectstore.ErrObjectNotFound) {
- return nil, &giterrors.ObjectMissingError{OID: id}
- }
-
- return nil, err
- }
-
- return content, nil
-}
diff --git a/reachability/integration_test.go b/reachability/integration_test.go
index 4e4b3918..20d9e3f7 100644
--- a/reachability/integration_test.go
+++ b/reachability/integration_test.go
@@ -11,6 +11,7 @@ import (
giterrors "codeberg.org/lindenii/furgit/errors"
"codeberg.org/lindenii/furgit/internal/testgit"
+ objectfetch "codeberg.org/lindenii/furgit/object/fetch"
objectid "codeberg.org/lindenii/furgit/object/id"
"codeberg.org/lindenii/furgit/reachability"
)
@@ -249,7 +250,7 @@ func TestWalkOnPackedOnlyRepo(t *testing.T) {
func openReachabilityFromTestRepo(t *testing.T, testRepo *testgit.TestRepo) *reachability.Reachability {
t.Helper()
- return reachability.New(testRepo.OpenObjectStore(t), nil)
+ return reachability.New(objectfetch.New(testRepo.OpenObjectStore(t)), nil)
}
func oidSetFromSeq(seq func(func(objectid.ObjectID) bool)) map[objectid.ObjectID]struct{} {
diff --git a/reachability/reachability.go b/reachability/reachability.go
index 6a0f2583..fd4d00e5 100644
--- a/reachability/reachability.go
+++ b/reachability/reachability.go
@@ -2,21 +2,21 @@ package reachability
import (
commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read"
- objectstore "codeberg.org/lindenii/furgit/object/store"
+ objectfetch "codeberg.org/lindenii/furgit/object/fetch"
)
// Reachability provides graph traversal over objects in one object store.
//
// Labels: MT-Safe.
type Reachability struct {
- store objectstore.Reader
- graph *commitgraphread.Reader
+ fetcher *objectfetch.Fetcher
+ graph *commitgraphread.Reader
}
-// New builds a Reachability over one object store with an optional
+// New builds a Reachability over one object fetcher with an optional
// commit-graph reader for faster commit-domain traversal.
//
// Labels: Deps-Borrowed, Life-Parent.
-func New(store objectstore.Reader, graph *commitgraphread.Reader) *Reachability {
- return &Reachability{store: store, graph: graph}
+func New(fetcher *objectfetch.Fetcher, graph *commitgraphread.Reader) *Reachability {
+ return &Reachability{fetcher: fetcher, graph: graph}
}
diff --git a/reachability/unit_test.go b/reachability/unit_test.go
index e5517a66..1f761108 100644
--- a/reachability/unit_test.go
+++ b/reachability/unit_test.go
@@ -9,6 +9,7 @@ import (
giterrors "codeberg.org/lindenii/furgit/errors"
"codeberg.org/lindenii/furgit/internal/testgit"
+ objectfetch "codeberg.org/lindenii/furgit/object/fetch"
objectid "codeberg.org/lindenii/furgit/object/id"
"codeberg.org/lindenii/furgit/object/store/memory"
"codeberg.org/lindenii/furgit/object/tree"
@@ -118,7 +119,7 @@ func TestWalkDomainCommitsIncludesTagNodes(t *testing.T) {
t.Fatal(err)
}
- r := reachability.New(store, nil)
+ r := reachability.New(objectfetch.New(store), nil)
walk := r.Walk(reachability.DomainCommits, nil, map[objectid.ObjectID]struct{}{tag2: {}})
got := collectSeq(walk.Seq())
@@ -162,7 +163,7 @@ func TestWalkExcludesHavesCompletely(t *testing.T) {
t.Fatal(err)
}
- r := reachability.New(store, nil)
+ r := reachability.New(objectfetch.New(store), nil)
walk := r.Walk(reachability.DomainCommits, map[objectid.ObjectID]struct{}{commit: {}}, map[objectid.ObjectID]struct{}{commit: {}})
got := collectSeq(walk.Seq())
@@ -203,7 +204,7 @@ func TestWalkDomainCommitsRejectsNonCommitRootAfterPeel(t *testing.T) {
t.Fatal(err)
}
- r := reachability.New(store, nil)
+ r := reachability.New(objectfetch.New(store), nil)
walk := r.Walk(reachability.DomainCommits, nil, map[objectid.ObjectID]struct{}{tag: {}})
_ = collectSeq(walk.Seq())
@@ -263,7 +264,7 @@ func TestWalkDomainCommitsHaveTagStopsTraversal(t *testing.T) {
t.Fatal(err)
}
- r := reachability.New(store, nil)
+ r := reachability.New(objectfetch.New(store), nil)
walk := r.Walk(
reachability.DomainCommits,
map[objectid.ObjectID]struct{}{tag1: {}},
@@ -327,7 +328,7 @@ func TestWalkDomainObjectsRecursesTreesAndSkipsBlobContentReads(t *testing.T) {
t.Fatal(err)
}
- r := reachability.New(store, nil)
+ r := reachability.New(objectfetch.New(store), nil)
walk := r.Walk(reachability.DomainObjects, nil, map[objectid.ObjectID]struct{}{commit: {}})
got := collectSeq(walk.Seq())
@@ -377,7 +378,7 @@ func TestCheckConnectedReturnsConcreteMissingObject(t *testing.T) {
t.Fatal(err)
}
- r := reachability.New(store, nil)
+ r := reachability.New(objectfetch.New(store), nil)
err = r.CheckConnected(reachability.DomainCommits, nil, map[objectid.ObjectID]struct{}{commit: {}})
if err == nil {
@@ -399,7 +400,7 @@ func TestWalkInvalidDomainReturnsPlainError(t *testing.T) {
t.Parallel()
testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { //nolint:thelper
- r := reachability.New(newCountingMemStore(algo), nil)
+ r := reachability.New(objectfetch.New(newCountingMemStore(algo)), nil)
walk := r.Walk(reachability.Domain(99), nil, nil)
_ = collectSeq(walk.Seq())
diff --git a/reachability/walk_expand_commits.go b/reachability/walk_expand_commits.go
index 8cb93279..eaeb4e72 100644
--- a/reachability/walk_expand_commits.go
+++ b/reachability/walk_expand_commits.go
@@ -4,8 +4,6 @@ import (
"fmt"
"codeberg.org/lindenii/furgit/errors"
- objectcommit "codeberg.org/lindenii/furgit/object/commit"
- objecttag "codeberg.org/lindenii/furgit/object/tag"
objecttype "codeberg.org/lindenii/furgit/object/type"
)
@@ -28,41 +26,31 @@ func (walk *Walk) expandCommits(item walkItem) ([]walkItem, error) {
}
}
- ty, err := walk.readHeaderType(item.id)
+ ty, _, err := walk.reachability.fetcher.Header(item.id)
if err != nil {
return nil, err
}
switch ty {
case objecttype.TypeCommit:
- content, err := walk.readBytesContent(item.id)
+ commit, err := walk.reachability.fetcher.ExactCommit(item.id)
if err != nil {
return nil, err
}
- commit, err := objectcommit.Parse(content, item.id.Algorithm())
- if err != nil {
- return nil, err
- }
-
- next := make([]walkItem, 0, len(commit.Parents))
- for _, parent := range commit.Parents {
+ next := make([]walkItem, 0, len(commit.Object().Parents))
+ for _, parent := range commit.Object().Parents {
next = append(next, walkItem{id: parent, want: objecttype.TypeInvalid})
}
return next, nil
case objecttype.TypeTag:
- content, err := walk.readBytesContent(item.id)
- if err != nil {
- return nil, err
- }
-
- tag, err := objecttag.Parse(content, item.id.Algorithm())
+ tag, err := walk.reachability.fetcher.ExactTag(item.id)
if err != nil {
return nil, err
}
- return []walkItem{{id: tag.Target, want: objecttype.TypeInvalid}}, nil
+ return []walkItem{{id: tag.Object().Target, want: objecttype.TypeInvalid}}, nil
case objecttype.TypeTree, objecttype.TypeBlob, objecttype.TypeInvalid,
objecttype.TypeFuture, objecttype.TypeOfsDelta, objecttype.TypeRefDelta:
return nil, &errors.ObjectTypeError{OID: item.id, Got: ty, Want: objecttype.TypeCommit}
diff --git a/reachability/walk_expand_objects.go b/reachability/walk_expand_objects.go
index 9c5ed439..8b479021 100644
--- a/reachability/walk_expand_objects.go
+++ b/reachability/walk_expand_objects.go
@@ -4,14 +4,12 @@ import (
"fmt"
"codeberg.org/lindenii/furgit/errors"
- objectcommit "codeberg.org/lindenii/furgit/object/commit"
- objecttag "codeberg.org/lindenii/furgit/object/tag"
objecttree "codeberg.org/lindenii/furgit/object/tree"
objecttype "codeberg.org/lindenii/furgit/object/type"
)
func (walk *Walk) expandObjects(item walkItem) ([]walkItem, error) {
- ty, err := walk.readHeaderType(item.id)
+ ty, _, err := walk.reachability.fetcher.Header(item.id)
if err != nil {
return nil, err
}
@@ -24,37 +22,27 @@ func (walk *Walk) expandObjects(item walkItem) ([]walkItem, error) {
case objecttype.TypeBlob:
return nil, nil
case objecttype.TypeCommit:
- content, err := walk.readBytesContent(item.id)
+ commit, err := walk.reachability.fetcher.ExactCommit(item.id)
if err != nil {
return nil, err
}
- commit, err := objectcommit.Parse(content, item.id.Algorithm())
- if err != nil {
- return nil, err
- }
+ next := make([]walkItem, 0, len(commit.Object().Parents)+1)
- next := make([]walkItem, 0, len(commit.Parents)+1)
-
- next = append(next, walkItem{id: commit.Tree, want: objecttype.TypeTree})
- for _, parent := range commit.Parents {
+ next = append(next, walkItem{id: commit.Object().Tree, want: objecttype.TypeTree})
+ for _, parent := range commit.Object().Parents {
next = append(next, walkItem{id: parent, want: objecttype.TypeCommit})
}
return next, nil
case objecttype.TypeTree:
- content, err := walk.readBytesContent(item.id)
- if err != nil {
- return nil, err
- }
-
- tree, err := objecttree.Parse(content, item.id.Algorithm())
+ tree, err := walk.reachability.fetcher.ExactTree(item.id)
if err != nil {
return nil, err
}
- next := make([]walkItem, 0, len(tree.Entries))
- for _, entry := range tree.Entries {
+ next := make([]walkItem, 0, len(tree.Object().Entries))
+ for _, entry := range tree.Object().Entries {
switch entry.Mode {
case objecttree.FileModeGitlink:
continue
@@ -67,17 +55,12 @@ func (walk *Walk) expandObjects(item walkItem) ([]walkItem, error) {
return next, nil
case objecttype.TypeTag:
- content, err := walk.readBytesContent(item.id)
- if err != nil {
- return nil, err
- }
-
- tag, err := objecttag.Parse(content, item.id.Algorithm())
+ tag, err := walk.reachability.fetcher.ExactTag(item.id)
if err != nil {
return nil, err
}
- return []walkItem{{id: tag.Target, want: tag.TargetType}}, nil
+ return []walkItem{{id: tag.Object().Target, want: tag.Object().TargetType}}, nil
case objecttype.TypeInvalid, objecttype.TypeFuture, objecttype.TypeOfsDelta, objecttype.TypeRefDelta:
return nil, &errors.ObjectTypeError{OID: item.id, Got: ty, Want: item.want}
}
diff --git a/reachability/walk_seq.go b/reachability/walk_seq.go
index e28427a2..669166f5 100644
--- a/reachability/walk_seq.go
+++ b/reachability/walk_seq.go
@@ -37,7 +37,7 @@ func (walk *Walk) Seq() iter.Seq[objectid.ObjectID] {
item := stack[len(stack)-1]
stack = stack[:len(stack)-1]
- if containsOID(walk.haves, item.id) {
+ if _, ok := walk.haves[item.id]; ok {
continue
}
diff --git a/reachability/walk_verify.go b/reachability/walk_verify.go
index c1409ba7..c4ac6ecf 100644
--- a/reachability/walk_verify.go
+++ b/reachability/walk_verify.go
@@ -2,13 +2,12 @@ package reachability
import (
"codeberg.org/lindenii/furgit/errors"
- objectcommit "codeberg.org/lindenii/furgit/object/commit"
objectid "codeberg.org/lindenii/furgit/object/id"
objecttype "codeberg.org/lindenii/furgit/object/type"
)
func (walk *Walk) validateCommitObject(id objectid.ObjectID) error {
- ty, err := walk.readHeaderType(id)
+ ty, _, err := walk.reachability.fetcher.Header(id)
if err != nil {
return err
}
@@ -17,12 +16,7 @@ func (walk *Walk) validateCommitObject(id objectid.ObjectID) error {
return &errors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeCommit}
}
- content, err := walk.readBytesContent(id)
- if err != nil {
- return err
- }
-
- _, err = objectcommit.Parse(content, id.Algorithm())
+ _, err = walk.reachability.fetcher.ExactCommit(id)
return err
}