diff options
| -rw-r--r-- | reachability/domain.go | 11 | ||||
| -rw-r--r-- | reachability/helpers.go | 72 | ||||
| -rw-r--r-- | reachability/integration_test.go | 3 | ||||
| -rw-r--r-- | reachability/reachability.go | 12 | ||||
| -rw-r--r-- | reachability/unit_test.go | 15 | ||||
| -rw-r--r-- | reachability/walk_expand_commits.go | 24 | ||||
| -rw-r--r-- | reachability/walk_expand_objects.go | 37 | ||||
| -rw-r--r-- | reachability/walk_seq.go | 2 | ||||
| -rw-r--r-- | reachability/walk_verify.go | 10 |
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 } |
