Skip to content

Commit

Permalink
WIP - lazy load tags during fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
macneale4 committed Jan 17, 2025
1 parent 91f667f commit 8c76471
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 34 deletions.
48 changes: 48 additions & 0 deletions go/libraries/doltcore/doltdb/doltdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,54 @@ func (ddb *DoltDB) ResolveTag(ctx context.Context, tagRef ref.TagRef) (*Tag, err
return NewTag(ctx, tagRef.GetPath(), ds, ddb.vrw, ddb.ns)
}

// TagResolver is used to late bind tag resolution
type TagResolver struct {
ddb *DoltDB
ref ref.TagRef
h hash.Hash
}

func (tr *TagResolver) Addr() hash.Hash {
return tr.h
}

// Resolve resolves the tag reference to a *Tag
func (tr *TagResolver) Resolve(ctx context.Context) (*Tag, error) {
return tr.ddb.ResolveTag(ctx, tr.ref)
}

// ResolveTags takes a slice of TagRefs and returns the corresponding Tag objects.
func (ddb *DoltDB) ResolveTags(ctx context.Context, tagRefs []ref.DoltRef) ([]TagResolver, error) {
datasets, err := ddb.db.Datasets(ctx)
if err != nil {
return nil, err
}

tagMap := make(map[string]ref.TagRef)
for _, tagRef := range tagRefs {
if tr, ok := tagRef.(ref.TagRef); ok {
tagMap[tagRef.String()] = tr
} else {
panic(fmt.Sprintf("runtime error: expected TagRef, got %T", tagRef))
}
}

results := make([]TagResolver, 0, len(tagRefs))

err = datasets.IterAll(ctx, func(id string, addr hash.Hash) error {
if val, ok := tagMap[id]; ok {
tr := TagResolver{ddb: ddb, ref: val, h: addr}
results = append(results, tr)
}
return nil // NM4 - is it an error if we don't find it???? Probably need to delete it on --prune.
})
if err != nil {
return nil, err
}

return results, nil
}

// ResolveWorkingSet takes a WorkingSetRef and returns the corresponding WorkingSet object.
func (ddb *DoltDB) ResolveWorkingSet(ctx context.Context, workingSetRef ref.WorkingSetRef) (*WorkingSet, error) {
ds, err := ddb.db.GetDataset(ctx, workingSetRef.String())
Expand Down
2 changes: 1 addition & 1 deletion go/libraries/doltcore/doltdb/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func NewTag(ctx context.Context, name string, ds datas.Dataset, vrw types.ValueR
return &Tag{
Name: name,
vrw: vrw,
addr: addr,
addr: addr, // NM4 - object address which is what we actually care about.
Meta: meta,
Commit: commit,
}, nil
Expand Down
18 changes: 10 additions & 8 deletions go/libraries/doltcore/env/actions/remotes.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,8 @@ func Clone(ctx context.Context, srcDB, destDB *doltdb.DoltDB, eventCh chan<- pul
// been fetched into the destination DB.
// todo: potentially too expensive to iterate over all srcDB tags
func FetchFollowTags(ctx context.Context, tempTableDir string, srcDB, destDB *doltdb.DoltDB, progStarter ProgStarter, progStopper ProgStopper) error {
err := IterResolvedTags(ctx, srcDB, func(tag *doltdb.Tag) (stop bool, err error) {
tagHash, err := tag.GetAddr()
if err != nil {
return true, err
}
err := IterResolvedTags(ctx, srcDB, func(tag *doltdb.TagResolver) (stop bool, err error) {
tagHash := tag.Addr()

has, err := destDB.Has(ctx, tagHash)
if err != nil {
Expand All @@ -353,7 +350,12 @@ func FetchFollowTags(ctx context.Context, tempTableDir string, srcDB, destDB *do
return false, nil
}

cmHash, err := tag.Commit.HashOf()
t, err := tag.Resolve(ctx)
if err != nil {
return true, err
}

cmHash, err := t.Commit.HashOf()
if err != nil {
return true, err
}
Expand All @@ -378,7 +380,7 @@ func FetchFollowTags(ctx context.Context, tempTableDir string, srcDB, destDB *do

newCtx, cancelFunc := context.WithCancel(ctx)
wg, statsCh := progStarter(newCtx)
err = FetchTag(ctx, tempTableDir, srcDB, destDB, tag, statsCh)
err = FetchTag(ctx, tempTableDir, srcDB, destDB, t, statsCh)
progStopper(cancelFunc, wg, statsCh)
if err == nil {
cli.Println()
Expand All @@ -390,7 +392,7 @@ func FetchFollowTags(ctx context.Context, tempTableDir string, srcDB, destDB *do
return true, err
}

err = destDB.SetHead(ctx, tag.GetDoltRef(), tagHash)
err = destDB.SetHead(ctx, t.GetDoltRef(), tagHash)

return false, err
})
Expand Down
32 changes: 7 additions & 25 deletions go/libraries/doltcore/env/actions/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ package actions

import (
"context"
"fmt"
"sort"

"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
Expand Down Expand Up @@ -98,43 +96,27 @@ func DeleteTagsOnDB(ctx context.Context, ddb *doltdb.DoltDB, tagNames ...string)
}

// IterResolvedTags iterates over tags in dEnv.DoltDB from newest to oldest, resolving the tag to a commit and calling cb().
func IterResolvedTags(ctx context.Context, ddb *doltdb.DoltDB, cb func(tag *doltdb.Tag) (stop bool, err error)) error {
func IterResolvedTags(ctx context.Context, ddb *doltdb.DoltDB, cb func(tag *doltdb.TagResolver) (stop bool, err error)) error {
tagRefs, err := ddb.GetTags(ctx)

if err != nil {
return err
}

var resolved []*doltdb.Tag
for _, r := range tagRefs {
tr, ok := r.(ref.TagRef)
if !ok {
return fmt.Errorf("DoltDB.GetTags() returned non-tag DoltRef")
}

tag, err := ddb.ResolveTag(ctx, tr)
if err != nil {
return err
}

resolved = append(resolved, tag)
tagResolvers, err := ddb.ResolveTags(ctx, tagRefs)
_ = tagResolvers
if err != nil {
return err
}

// iterate newest to oldest
sort.Slice(resolved, func(i, j int) bool {
return resolved[i].Meta.Timestamp > resolved[j].Meta.Timestamp
})

for _, tag := range resolved {
stop, err := cb(tag)

for _, tagResolver := range tagResolvers {
stop, err := cb(&tagResolver)
if err != nil {
return err
}
if stop {
break
}
}

return nil
}

0 comments on commit 8c76471

Please sign in to comment.