/* * 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 . */ 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}) } }