2021-10-27 10:00:35 +00:00
|
|
|
package netmap
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
|
2022-12-13 14:36:35 +00:00
|
|
|
"github.com/TrueCloudLab/frostfs-api-go/v2/netmap"
|
|
|
|
"github.com/TrueCloudLab/hrw"
|
2021-10-27 10:00:35 +00:00
|
|
|
)
|
|
|
|
|
2022-06-07 08:25:34 +00:00
|
|
|
// context of a placement build process.
|
2022-05-20 12:45:12 +00:00
|
|
|
type context struct {
|
2022-06-07 08:25:34 +00:00
|
|
|
// network map to operate on
|
|
|
|
netMap NetMap
|
|
|
|
|
|
|
|
// cache of processed filters
|
|
|
|
processedFilters map[string]*netmap.Filter
|
|
|
|
|
|
|
|
// cache of processed selectors
|
|
|
|
processedSelectors map[string]*netmap.Selector
|
|
|
|
|
|
|
|
// stores results of selector processing
|
|
|
|
selections map[string][]nodes
|
|
|
|
|
|
|
|
// cache of parsed numeric values
|
2022-03-11 09:13:08 +00:00
|
|
|
numCache map[string]uint64
|
2022-06-07 08:25:34 +00:00
|
|
|
|
|
|
|
hrwSeed []byte
|
|
|
|
|
|
|
|
// hrw.Hash of hrwSeed
|
|
|
|
hrwSeedHash uint64
|
|
|
|
|
|
|
|
// weightFunc is a weighting function for determining node priority
|
|
|
|
// which combines low price and high performance
|
2021-10-27 10:00:35 +00:00
|
|
|
weightFunc weightFunc
|
2022-06-07 08:25:34 +00:00
|
|
|
|
|
|
|
// container backup factor
|
2021-10-27 10:00:35 +00:00
|
|
|
cbf uint32
|
|
|
|
}
|
|
|
|
|
|
|
|
// Various validation errors.
|
|
|
|
var (
|
2022-06-07 08:25:34 +00:00
|
|
|
errInvalidFilterName = errors.New("filter name is invalid")
|
|
|
|
errInvalidNumber = errors.New("invalid number")
|
|
|
|
errInvalidFilterOp = errors.New("invalid filter operation")
|
|
|
|
errFilterNotFound = errors.New("filter not found")
|
|
|
|
errNonEmptyFilters = errors.New("simple filter contains sub-filters")
|
|
|
|
errNotEnoughNodes = errors.New("not enough nodes to SELECT from")
|
|
|
|
errUnnamedTopFilter = errors.New("unnamed top-level filter")
|
2021-10-27 10:00:35 +00:00
|
|
|
)
|
|
|
|
|
2022-06-07 08:25:34 +00:00
|
|
|
// newContext returns initialized context.
|
|
|
|
func newContext(nm NetMap) *context {
|
2022-05-20 12:45:12 +00:00
|
|
|
return &context{
|
2022-06-07 08:25:34 +00:00
|
|
|
netMap: nm,
|
|
|
|
processedFilters: make(map[string]*netmap.Filter),
|
|
|
|
processedSelectors: make(map[string]*netmap.Selector),
|
|
|
|
selections: make(map[string][]nodes),
|
2021-10-27 10:00:35 +00:00
|
|
|
|
2022-03-11 09:13:08 +00:00
|
|
|
numCache: make(map[string]uint64),
|
2022-06-07 06:01:25 +00:00
|
|
|
weightFunc: defaultWeightFunc(nm.nodes),
|
2021-10-27 10:00:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-20 12:45:12 +00:00
|
|
|
func (c *context) setPivot(pivot []byte) {
|
2021-10-27 10:00:35 +00:00
|
|
|
if len(pivot) != 0 {
|
2022-06-07 08:25:34 +00:00
|
|
|
c.hrwSeed = pivot
|
|
|
|
c.hrwSeedHash = hrw.Hash(pivot)
|
2021-10-27 10:00:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-20 12:45:12 +00:00
|
|
|
func (c *context) setCBF(cbf uint32) {
|
2021-10-27 10:00:35 +00:00
|
|
|
if cbf == 0 {
|
2022-06-07 08:25:34 +00:00
|
|
|
c.cbf = 3
|
2021-10-27 10:00:35 +00:00
|
|
|
} else {
|
|
|
|
c.cbf = cbf
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-07 06:01:25 +00:00
|
|
|
func defaultWeightFunc(ns nodes) weightFunc {
|
2021-10-27 10:00:35 +00:00
|
|
|
mean := newMeanAgg()
|
|
|
|
min := newMinAgg()
|
|
|
|
|
|
|
|
for i := range ns {
|
2022-06-07 02:12:39 +00:00
|
|
|
mean.Add(float64(ns[i].capacity()))
|
2022-06-07 08:25:34 +00:00
|
|
|
min.Add(float64(ns[i].Price()))
|
2021-10-27 10:00:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return newWeightFunc(
|
|
|
|
newSigmoidNorm(mean.Compute()),
|
|
|
|
newReverseMinNorm(min.Compute()))
|
|
|
|
}
|