Skip to content

Commit 083e46c

Browse files
committed
internal/rule,gitbase: use refs indexes in squash tables
Signed-off-by: Miguel Molina <[email protected]>
1 parent 700e56b commit 083e46c

File tree

4 files changed

+162
-1
lines changed

4 files changed

+162
-1
lines changed

internal/rule/squashjoins.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,12 @@ func buildSquashedTable(
311311
if err != nil {
312312
return nil, err
313313
}
314-
iter = gitbase.NewAllRefsIter(f, false)
314+
315+
if index == nil {
316+
iter = gitbase.NewAllRefsIter(f, false)
317+
} else {
318+
iter = gitbase.NewIndexRefsIter(f, index)
319+
}
315320
default:
316321
return nil, errInvalidIteratorChain.New("refs", iter)
317322
}

internal/rule/squashjoins_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,32 @@ func TestBuildSquashedTable(t *testing.T) {
15671567
gitbase.BlobsTableName,
15681568
),
15691569
},
1570+
{
1571+
"refs with indexes",
1572+
[]sql.Table{refs, refCommits},
1573+
[]sql.Expression{
1574+
refsRefCommitsRedundantFilter,
1575+
},
1576+
nil,
1577+
map[string]sql.IndexLookup{
1578+
gitbase.ReferencesTableName: idx1,
1579+
gitbase.RefCommitsTableName: idx2,
1580+
},
1581+
nil,
1582+
newSquashedTable(
1583+
gitbase.NewRefRefCommitsIter(
1584+
gitbase.NewIndexRefsIter(nil, idx1),
1585+
nil,
1586+
),
1587+
nil,
1588+
[]sql.Expression{
1589+
refsRefCommitsRedundantFilter,
1590+
},
1591+
[]string{gitbase.ReferencesTableName},
1592+
gitbase.ReferencesTableName,
1593+
gitbase.RefCommitsTableName,
1594+
),
1595+
},
15701596
{
15711597
"ref commits with indexes",
15721598
[]sql.Table{refCommits, commits},

squash_iterator.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,109 @@ func (i *squashRefIter) Schema() sql.Schema {
552552
return RefsSchema
553553
}
554554

555+
type squashRefIndexIter struct {
556+
ctx *sql.Context
557+
index sql.IndexLookup
558+
iter sql.RowIter
559+
filters sql.Expression
560+
pool *RepositoryPool
561+
ref *Ref
562+
repo *Repository
563+
row sql.Row
564+
skipGitErrors bool
565+
}
566+
567+
// NewIndexRefsIter returns an iterator that will return all references
568+
// that match the given filters in the given index.
569+
func NewIndexRefsIter(filters sql.Expression, index sql.IndexLookup) RefsIter {
570+
return &squashRefIndexIter{filters: filters, index: index}
571+
}
572+
573+
func (i *squashRefIndexIter) Repository() *Repository { return i.repo }
574+
func (i *squashRefIndexIter) Ref() *Ref { return i.ref }
575+
func (i *squashRefIndexIter) Close() error {
576+
return i.iter.Close()
577+
}
578+
func (i *squashRefIndexIter) New(ctx *sql.Context, pool *RepositoryPool) (ChainableIter, error) {
579+
session, err := getSession(ctx)
580+
if err != nil {
581+
return nil, err
582+
}
583+
584+
values, err := i.index.Values()
585+
if err != nil {
586+
return nil, err
587+
}
588+
589+
return &squashRefIndexIter{
590+
ctx: ctx,
591+
filters: i.filters,
592+
skipGitErrors: session.SkipGitErrors,
593+
pool: pool,
594+
iter: &rowIndexIter{new(refRowKeyMapper), values},
595+
}, nil
596+
}
597+
598+
func (i *squashRefIndexIter) Row() sql.Row {
599+
return i.row
600+
}
601+
602+
func (i *squashRefIndexIter) Advance() error {
603+
for {
604+
select {
605+
case <-i.ctx.Done():
606+
return ErrSessionCanceled.New()
607+
default:
608+
}
609+
610+
var err error
611+
i.row, err = i.iter.Next()
612+
if err != nil {
613+
return err
614+
}
615+
616+
repoID := i.row[0].(string)
617+
if i.repo == nil || repoID != i.repo.ID {
618+
i.repo, err = i.pool.GetRepo(repoID)
619+
if err != nil {
620+
if i.skipGitErrors {
621+
continue
622+
}
623+
624+
return err
625+
}
626+
}
627+
628+
refName := plumbing.ReferenceName(i.row[1].(string))
629+
ref, err := i.repo.Repo.Reference(refName, true)
630+
if err != nil {
631+
if i.skipGitErrors {
632+
continue
633+
}
634+
635+
return err
636+
}
637+
638+
i.ref = &Ref{repoID, ref}
639+
640+
if i.filters != nil {
641+
ok, err := evalFilters(i.ctx, i.row, i.filters)
642+
if err != nil {
643+
return err
644+
}
645+
646+
if !ok {
647+
continue
648+
}
649+
}
650+
651+
return nil
652+
}
653+
}
654+
func (i *squashRefIndexIter) Schema() sql.Schema {
655+
return RefsSchema
656+
}
657+
555658
type squashRepoRefsIter struct {
556659
ctx *sql.Context
557660
repos ReposIter

squash_iterator_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,33 @@ func setupIterWithErrors(t *testing.T, badRepo bool, skipErrors bool) (*sql.Cont
744744
return ctx, cleanup
745745
}
746746

747+
func TestIndexRefsIter(t *testing.T) {
748+
require := require.New(t)
749+
750+
ctx, index, cleanup := setupWithIndex(t, new(referencesTable))
751+
defer cleanup()
752+
753+
it, err := NewChainableRowIter(
754+
ctx,
755+
NewAllRefsIter(nil, false),
756+
)
757+
require.NoError(err)
758+
759+
expected, err := sql.RowIterToRows(it)
760+
require.NoError(err)
761+
762+
it, err = NewChainableRowIter(
763+
ctx,
764+
NewIndexRefsIter(nil, index),
765+
)
766+
require.NoError(err)
767+
768+
rows, err := sql.RowIterToRows(it)
769+
require.NoError(err)
770+
771+
require.ElementsMatch(expected, rows)
772+
}
773+
747774
func TestIndexRefCommitsIter(t *testing.T) {
748775
require := require.New(t)
749776

0 commit comments

Comments
 (0)