[#354] api/netmap: Return a slice of parameters directly

`IterateParameters` does a poor job:
- it doesn't encapsulate well, because it returns a pointer,
- it has a clunky interface, compared to range loop.

I have decided to return parameter slice and not `iter.Seq` for 2
reasons:
1. There already is `SetParameters`, so `NetworkConfig` struct is
   expected to be modified.
2. This iterator uses pointers, so even with this interface the slice
   can already be changed.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2025-04-05 08:22:49 +03:00 committed by Evgenii Stratonikov
parent 661adf17bb
commit 16fd3bafe0
3 changed files with 38 additions and 53 deletions

View file

@ -577,6 +577,8 @@ type NetworkConfig struct {
} }
// NumberOfParameters returns number of network parameters. // NumberOfParameters returns number of network parameters.
//
// Deprecated: use [NetworkConfig.Parameters] instead.
func (x *NetworkConfig) NumberOfParameters() int { func (x *NetworkConfig) NumberOfParameters() int {
if x != nil { if x != nil {
return len(x.ps) return len(x.ps)
@ -585,10 +587,20 @@ func (x *NetworkConfig) NumberOfParameters() int {
return 0 return 0
} }
// Parameters returns an iterator over network parameters.
func (x *NetworkConfig) Parameters() []NetworkParameter {
if x != nil {
return x.ps
}
return nil
}
// IterateParameters iterates over network parameters. // IterateParameters iterates over network parameters.
// Breaks iteration on f's true return. // Breaks iteration on f's true return.
// //
// Handler must not be nil. // Handler must not be nil.
//
// Deprecated: use [NetworkConfig.Parameters] instead.
func (x *NetworkConfig) IterateParameters(f func(*NetworkParameter) bool) { func (x *NetworkConfig) IterateParameters(f func(*NetworkParameter) bool) {
if x != nil { if x != nil {
for i := range x.ps { for i := range x.ps {

View file

@ -30,20 +30,19 @@ func (x *NetworkInfo) readFromV2(m netmap.NetworkInfo, checkFieldPresence bool)
return errors.New("missing network config") return errors.New("missing network config")
} }
if checkFieldPresence && c.NumberOfParameters() <= 0 { if checkFieldPresence && len(c.Parameters()) == 0 {
return errors.New("missing network parameters") return errors.New("missing network parameters")
} }
var err error var err error
mNames := make(map[string]struct{}, c.NumberOfParameters()) mNames := make(map[string]struct{}, len(c.Parameters()))
c.IterateParameters(func(prm *netmap.NetworkParameter) bool { for _, prm := range c.Parameters() {
name := string(prm.GetKey()) name := string(prm.GetKey())
_, was := mNames[name] _, was := mNames[name]
if was { if was {
err = fmt.Errorf("duplicated parameter name: %s", name) return fmt.Errorf("duplicated parameter name: %s", name)
return true
} }
mNames[name] = struct{}{} mNames[name] = struct{}{}
@ -67,14 +66,8 @@ func (x *NetworkInfo) readFromV2(m netmap.NetworkInfo, checkFieldPresence bool)
} }
if err != nil { if err != nil {
err = fmt.Errorf("invalid %s parameter: %w", name, err) return fmt.Errorf("invalid %s parameter: %w", name, err)
} }
return err != nil
})
if err != nil {
return err
} }
x.m = m x.m = m
@ -152,41 +145,29 @@ func (x *NetworkInfo) setConfig(name string, val []byte) {
return return
} }
found := false prms := c.Parameters()
prms := make([]netmap.NetworkParameter, 0, c.NumberOfParameters()) for i := range prms {
if bytes.Equal(prms[i].GetKey(), []byte(name)) {
c.IterateParameters(func(prm *netmap.NetworkParameter) bool { prms[i].SetValue(val)
found = bytes.Equal(prm.GetKey(), []byte(name)) return
if found {
prm.SetValue(val)
} else {
prms = append(prms, *prm)
} }
return found
})
if !found {
prms = append(prms, netmap.NetworkParameter{})
prms[len(prms)-1].SetKey([]byte(name))
prms[len(prms)-1].SetValue(val)
c.SetParameters(prms...)
} }
prms = append(prms, netmap.NetworkParameter{})
prms[len(prms)-1].SetKey([]byte(name))
prms[len(prms)-1].SetValue(val)
c.SetParameters(prms...)
} }
func (x NetworkInfo) configValue(name string) (res []byte) { func (x NetworkInfo) configValue(name string) (res []byte) {
x.m.GetNetworkConfig().IterateParameters(func(prm *netmap.NetworkParameter) bool { for _, prm := range x.m.GetNetworkConfig().Parameters() {
if string(prm.GetKey()) == name { if string(prm.GetKey()) == name {
res = prm.GetValue() return prm.GetValue()
return true
} }
}
return false return nil
})
return
} }
// SetRawNetworkParameter sets named FrostFS network parameter whose value is // SetRawNetworkParameter sets named FrostFS network parameter whose value is
@ -218,7 +199,7 @@ func (x *NetworkInfo) RawNetworkParameter(name string) []byte {
func (x *NetworkInfo) IterateRawNetworkParameters(f func(name string, value []byte)) { func (x *NetworkInfo) IterateRawNetworkParameters(f func(name string, value []byte)) {
c := x.m.GetNetworkConfig() c := x.m.GetNetworkConfig()
c.IterateParameters(func(prm *netmap.NetworkParameter) bool { for _, prm := range c.Parameters() {
name := string(prm.GetKey()) name := string(prm.GetKey())
switch name { switch name {
default: default:
@ -237,9 +218,7 @@ func (x *NetworkInfo) IterateRawNetworkParameters(f func(name string, value []by
configHomomorphicHashingDisabled, configHomomorphicHashingDisabled,
configMaintenanceModeAllowed: configMaintenanceModeAllowed:
} }
}
return false
})
} }
func (x *NetworkInfo) setConfigUint64(name string, num uint64) { func (x *NetworkInfo) setConfigUint64(name string, num uint64) {

View file

@ -76,16 +76,10 @@ func testConfigValue(t *testing.T,
var m netmap.NetworkInfo var m netmap.NetworkInfo
x.WriteToV2(&m) x.WriteToV2(&m)
require.EqualValues(t, 1, m.GetNetworkConfig().NumberOfParameters()) var p netmap.NetworkParameter
found := false p.SetKey([]byte(v2Key))
m.GetNetworkConfig().IterateParameters(func(prm *netmap.NetworkParameter) bool { p.SetValue(v2Val(exp))
require.False(t, found) require.Equal(t, []netmap.NetworkParameter{p}, m.GetNetworkConfig().Parameters())
require.Equal(t, []byte(v2Key), prm.GetKey())
require.Equal(t, v2Val(exp), prm.GetValue())
found = true
return false
})
require.True(t, found)
} }
setter(&x, val1) setter(&x, val1)