Skip to content

Commit

Permalink
Use Generics from Common Library
Browse files Browse the repository at this point in the history
  • Loading branch information
spjmurray committed Nov 29, 2024
1 parent 1f7e40a commit 380dd40
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 42 deletions.
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ require (
github.com/google/uuid v1.6.0
github.com/oapi-codegen/runtime v1.1.1
github.com/spf13/pflag v1.0.5
github.com/spjmurray/go-sat v0.3.1
github.com/stretchr/testify v1.9.0
github.com/spjmurray/go-sat v0.4.0
github.com/spjmurray/go-util v0.1.2
github.com/stretchr/testify v1.10.0
github.com/unikorn-cloud/core v0.1.86
github.com/unikorn-cloud/identity v0.2.45
github.com/unikorn-cloud/kubernetes v0.2.51
Expand Down
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spjmurray/go-sat v0.3.1 h1:6EAi0GtbSUwS1fJtVJx7e8X+1q/IbClI5BQ5TAuyPgk=
github.com/spjmurray/go-sat v0.3.1/go.mod h1:PfXzQbyb3Tucoyw9jNb3/Kj0VQUrK2KQ8F1NWBvCPPk=
github.com/spjmurray/go-sat v0.4.0 h1:BFD20Ot3wKN4Rf26vVOjfosda2MJW/uJ6GrDruKiTdU=
github.com/spjmurray/go-sat v0.4.0/go.mod h1:DCU2g/lAREdvbec/Szz+Sqcg4NiO1RxzAP+nJHExoq8=
github.com/spjmurray/go-util v0.1.2 h1:dZ9ZGus+P95kcFMDY+aR/0SAj+c3WMC8ZAT/CHLa9UM=
github.com/spjmurray/go-util v0.1.2/go.mod h1:fARcBeaHio/6h9H7Ht+egZPBZMNxEwxmHC1vyjBtPbs=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/unikorn-cloud/core v0.1.86 h1:U8+V5CcTgWT0tVqM6nxlOqLmLP+43Zu0og3OzSe84aI=
Expand Down
12 changes: 6 additions & 6 deletions pkg/provisioners/managers/application/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"fmt"

"github.com/spf13/pflag"
sat "github.com/spjmurray/go-sat"
"github.com/spjmurray/go-util/pkg/set"

unikornv1 "github.com/unikorn-cloud/application/pkg/apis/unikorn/v1alpha1"
"github.com/unikorn-cloud/application/pkg/solver"
Expand Down Expand Up @@ -115,7 +115,7 @@ type schedulerVistor struct {
applications solver.ApplicationIndex
appVersions map[string]solver.AppVersion
dependers map[string][]string
seen sat.Set[string]
seen set.Set[string]
order []solver.AppVersion
}

Expand All @@ -140,7 +140,7 @@ func (v *schedulerVistor) Visit(av solver.AppVersion, enqueue func(solver.AppVer
satisfied := true

for _, dep := range version.Dependencies {
if !v.seen.Has(dep.Name) {
if !v.seen.Contains(dep.Name) {
satisfied = false

break
Expand All @@ -157,7 +157,7 @@ func (v *schedulerVistor) Visit(av solver.AppVersion, enqueue func(solver.AppVer
}

// Schedule takes a SAT solution and creates an installation order for the applications.
func Schedule(ctx context.Context, applications solver.ApplicationIndex, solution sat.Set[solver.AppVersion]) ([]solver.AppVersion, error) {
func Schedule(ctx context.Context, applications solver.ApplicationIndex, solution set.Set[solver.AppVersion]) ([]solver.AppVersion, error) {
// Okay, we need to build up a reverse map of dependencies and also
// record the packages with no dependencies as those will be installed
// first.
Expand Down Expand Up @@ -199,7 +199,7 @@ func Schedule(ctx context.Context, applications solver.ApplicationIndex, solutio
applications: applications,
appVersions: appVersions,
dependers: dependers,
seen: sat.Set[string]{},
seen: set.Set[string]{},
}

if err := graph.Walk(visitor); err != nil {
Expand Down Expand Up @@ -233,7 +233,7 @@ func (p *Provisioner) getClusterManager(ctx context.Context, cluster *unikornv1k
// removeOrphanedApplications does exactly that, we can only see what the user currently
// wants installed, so we need to inspect what the CD driver can see on the system and
// manually prune anything that's installed by shouldn't be.
func (p *Provisioner) removeOrphanedApplications(ctx context.Context, required sat.Set[solver.AppVersion]) error {
func (p *Provisioner) removeOrphanedApplications(ctx context.Context, required set.Set[solver.AppVersion]) error {
// List all applications that exist for this resource.
labels, err := p.applicationset.ResourceLabels()
if err != nil {
Expand Down
47 changes: 17 additions & 30 deletions pkg/solver/solver.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"errors"
"fmt"

sat "github.com/spjmurray/go-sat"
"github.com/spjmurray/go-sat/pkg/cdcl"
"github.com/spjmurray/go-util/pkg/queue"
"github.com/spjmurray/go-util/pkg/set"

unikornv1 "github.com/unikorn-cloud/application/pkg/apis/unikorn/v1alpha1"
unikornv1core "github.com/unikorn-cloud/core/pkg/apis/unikorn/v1alpha1"
Expand All @@ -38,25 +40,6 @@ var (
ErrConstraint = errors.New("constraint error")
)

type Queue[T any] struct {
items []T
}

func (q *Queue[T]) Empty() bool {
return len(q.items) == 0
}

func (q *Queue[T]) Push(value T) {
q.items = append(q.items, value)
}

func (q *Queue[T]) Pop() T {
value := q.items[0]
q.items = q.items[1:]

return value
}

// GraphVisitor is used to visit a node in the graph.
type GraphVisitor[T comparable] interface {
// Visit is called when a new node is encountered, it accepts
Expand All @@ -65,13 +48,14 @@ type GraphVisitor[T comparable] interface {
}

type GraphWalker[T comparable] struct {
queue Queue[T]
seen sat.Set[T]
queue *queue.Queue[T]
seen set.Set[T]
}

func NewGraphWalker[T comparable]() *GraphWalker[T] {
return &GraphWalker[T]{
seen: sat.Set[T]{},
queue: queue.New[T](),
seen: set.New[T](),
}
}

Expand All @@ -81,9 +65,12 @@ func (g *GraphWalker[T]) Enqueue(t T) {

func (g *GraphWalker[T]) Walk(visitor GraphVisitor[T]) error {
for !g.queue.Empty() {
t := g.queue.Pop()
t, err := g.queue.Pop()
if err != nil {
return err
}

if g.seen.Has(t) {
if g.seen.Contains(t) {
continue
}

Expand Down Expand Up @@ -143,7 +130,7 @@ func (i ApplicationIndex) Get(name string) (*unikornv1core.HelmApplication, erro

type solverVisitor struct {
applications ApplicationIndex
model *sat.Model[AppVersion]
model *cdcl.Model[AppVersion]
}

//nolint:cyclop
Expand Down Expand Up @@ -217,12 +204,12 @@ func (v *solverVisitor) Visit(name string, enqueue func(string)) error {
// then we have a conflict, and have to backtrack and try again with another version.
// Unlike typical SAT solver problems, choosing a different version can have the fun
// effect of changing its dependencies!
func SolveApplicationSet(ctx context.Context, applications ApplicationIndex, applicationset *unikornv1.ApplicationSet) (sat.Set[AppVersion], error) {
func SolveApplicationSet(ctx context.Context, applications ApplicationIndex, applicationset *unikornv1.ApplicationSet) (set.Set[AppVersion], error) {
// We're going to do an exhaustive walk of the dependency graph gathering
// all application/version tuples as variables, and also create any clauses along the way.
graph := NewGraphWalker[string]()

model := sat.NewModel[AppVersion]()
model := cdcl.NewModel[AppVersion]()

// Populate the work queue with any application IDs that are requested by the
// user and any clauses relevant to the solver.
Expand Down Expand Up @@ -266,12 +253,12 @@ func SolveApplicationSet(ctx context.Context, applications ApplicationIndex, app
}

// Solve the problem.
if err := sat.NewCDCLSolver().Solve(model, sat.DefaultChooser); err != nil {
if err := cdcl.New().Solve(model, cdcl.DefaultChooser); err != nil {
return nil, err
}

// Get the result.
result := sat.Set[AppVersion]{}
result := set.Set[AppVersion]{}

for av, b := range model.Variables() {
if b.Value() {
Expand Down

0 comments on commit 380dd40

Please sign in to comment.