solvar/relation.go

80 lines
1.8 KiB
Go

/*
* This file is part of solvar. (https://git.redxen.eu/caskd/solvar)
* Copyright (c) 2022 Alex-David Denes
*
* solvar is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* solvar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with solvar. If not, see <https://www.gnu.org/licenses/>.
*/
package solvar
import (
"golang.org/x/exp/slices"
)
type internalRelation struct {
o *internalObject
t RelationType
}
type RelationType uint
const (
RelationTypeNeed RelationType = iota
RelationTypeReject
)
type Relation struct {
Id Identifier
T RelationType
}
func (d *DependencyGraph) solveRelation(np *[]*Object, rel *Relation, cb chan callbackSolver) {
var err error
var rio []*internalObject
// Setup deferred callback
defer func(e *error, i *[]*internalObject, cbc chan callbackSolver) {
cbc <- callbackSolver{e: *e, io: *i}
}(&err, &rio, cb)
var obs []*Object
if obs, err = d.ic.Query(rel.Id); err != nil {
return
}
var tmp []*Object
for _, obv := range obs {
// Remove already visited objects
if !slices.Contains(*np, obv) {
tmp = append(tmp, obv)
}
}
obs = tmp
if rel.T == RelationTypeNeed {
lcb := make(chan callbackSolver, len(obs))
for _, ob := range obs {
go d.solveObject(np, ob, rel.T, lcb)
}
for range obs {
cb := <-lcb
if cb.e != nil {
return
}
rio = append(rio, cb.io...)
}
} else {
rio = append(rio, &internalObject{r: obs})
}
}