Skip to content

Commit 4fd36ec

Browse files
author
Dave Johnston
authored
[FFM-9476]: Optimize memory usage (#126)
This change supports improved memory usage of the evaluator code. It introduces a new function on the query interface GetFlagMap(). This returns a map of flags. This is more optimal as the GetFlag function can also use a underlying map, it removes the need to maintain both a list and a map of flags for the caller of the evaluator.
1 parent 82306ec commit 4fd36ec

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

evaluation/evaluator.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package evaluation
22

33
import (
44
"encoding/json"
5+
"errors"
56
"fmt"
67
"regexp"
78
"sort"
@@ -27,11 +28,16 @@ const (
2728
equalSensitiveOperator = "equal_sensitive"
2829
)
2930

31+
var (
32+
ErrNilFlag = errors.New("flag is nil")
33+
)
34+
3035
// Query provides methods for segment and flag retrieval
3136
type Query interface {
3237
GetSegment(identifier string) (rest.Segment, error)
3338
GetFlag(identifier string) (rest.FeatureConfig, error)
3439
GetFlags() ([]rest.FeatureConfig, error)
40+
GetFlagMap() (map[string]*rest.FeatureConfig, error)
3541
}
3642

3743
// FlagVariations list of FlagVariations
@@ -329,7 +335,7 @@ func (e Evaluator) EvaluateAll(target *Target) (FlagVariations, error) {
329335
// takes uses feature store.List function to get all the flags.
330336
func (e Evaluator) evaluateAll(target *Target) ([]FlagVariation, error) {
331337
var variations []FlagVariation
332-
flags, err := e.query.GetFlags()
338+
flags, err := e.query.GetFlagMap()
333339
if err != nil {
334340
return variations, err
335341
}
@@ -358,29 +364,32 @@ func (e Evaluator) evaluate(identifier string, target *Target) (FlagVariation, e
358364
return FlagVariation{}, err
359365
}
360366

361-
variation, err := e.getVariationForTheFlag(flag, target)
367+
variation, err := e.getVariationForTheFlag(&flag, target)
362368
if err != nil {
363369
return FlagVariation{}, err
364370
}
365371
return FlagVariation{flag.Feature, flag.Kind, variation}, nil
366372
}
367373

368374
// evaluates the flag and returns a proper variation.
369-
func (e Evaluator) getVariationForTheFlag(flag rest.FeatureConfig, target *Target) (rest.Variation, error) {
375+
func (e Evaluator) getVariationForTheFlag(flag *rest.FeatureConfig, target *Target) (rest.Variation, error) {
376+
if flag == nil {
377+
return rest.Variation{}, ErrNilFlag
378+
}
370379

371380
if flag.Prerequisites != nil {
372-
prereq, err := e.checkPreRequisite(&flag, target)
381+
prereq, err := e.checkPreRequisite(flag, target)
373382
if err != nil || !prereq {
374383
return findVariation(flag.Variations, flag.OffVariation)
375384
}
376385
}
377-
variation, err := e.evaluateFlag(flag, target)
386+
variation, err := e.evaluateFlag(*flag, target)
378387
if err != nil {
379388
return rest.Variation{}, err
380389
}
381390
if e.postEvalCallback != nil {
382391
data := PostEvalData{
383-
FeatureConfig: &flag,
392+
FeatureConfig: flag,
384393
Target: target,
385394
Variation: &variation,
386395
}

evaluation/evaluator_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,14 @@ func (m TestRepository) GetFlags() ([]rest.FeatureConfig, error) {
312312
return flags, nil
313313
}
314314

315+
func (m TestRepository) GetFlagMap() (map[string]*rest.FeatureConfig, error) {
316+
var flags map[string]*rest.FeatureConfig
317+
for _, f := range m.flags {
318+
flags[f.Feature] = &f
319+
}
320+
return flags, nil
321+
}
322+
315323
func TestNewEvaluator(t *testing.T) {
316324
noOpLogger := logger.NewNoOpLogger()
317325
eval, _ := NewEvaluator(testRepo, nil, noOpLogger)

pkg/repository/repository.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type Repository interface {
1515
GetFlag(identifier string) (rest.FeatureConfig, error)
1616
GetSegment(identifier string) (rest.Segment, error)
1717
GetFlags() ([]rest.FeatureConfig, error)
18+
GetFlagMap() (map[string]*rest.FeatureConfig, error)
1819

1920
SetFlag(featureConfig rest.FeatureConfig, initialLoad bool)
2021
SetFlags(initialLoad bool, envID string, featureConfig ...rest.FeatureConfig)
@@ -120,6 +121,11 @@ func (r FFRepository) GetFlags() ([]rest.FeatureConfig, error) {
120121
return []rest.FeatureConfig{}, nil
121122
}
122123

124+
// GetFlagMap returns all flags as a mao /* Not Implemented *.
125+
func (r FFRepository) GetFlagMap() (map[string]*rest.FeatureConfig, error) {
126+
return map[string]*rest.FeatureConfig{}, nil
127+
}
128+
123129
func (r FFRepository) getSegmentAndCache(identifier string, cacheable bool) (rest.Segment, error) {
124130
segmentKey := formatSegmentKey(identifier)
125131
flag, ok := r.cache.Get(segmentKey)

0 commit comments

Comments
 (0)