Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg/dumps.DumpTree: split to reduce complexity #3001

Merged
merged 2 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
linters-settings:
cyclop:
# lower this after refactoring
max-complexity: 48
max-complexity: 45

gci:
sections:
Expand All @@ -18,11 +18,11 @@ linters-settings:

gocognit:
# lower this after refactoring
min-complexity: 145
min-complexity: 128

gocyclo:
# lower this after refactoring
min-complexity: 48
min-complexity: 45

funlen:
# Checks the number of lines in a function.
Expand Down Expand Up @@ -55,7 +55,7 @@ linters-settings:

nestif:
# lower this after refactoring
min-complexity: 28
min-complexity: 24

nlreturn:
block-size: 5
Expand Down
84 changes: 53 additions & 31 deletions pkg/dumps/parser_dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,79 +92,101 @@
return &pdump, nil
}

func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpOpts) {
type tree struct {
// note : we can use line -> time as the unique identifier (of acquisition)
state := make(map[time.Time]map[string]map[string]ParserResult)
assoc := make(map[time.Time]string, 0)
parser_order := make(map[string][]string)
state map[time.Time]map[string]map[string]ParserResult
assoc map[time.Time]string
parserOrder map[string][]string
}

func newTree() *tree {
return &tree{
state: make(map[time.Time]map[string]map[string]ParserResult),
assoc: make(map[time.Time]string),
parserOrder: make(map[string][]string),
}

Check warning on line 107 in pkg/dumps/parser_dump.go

View check run for this annotation

Codecov / codecov/patch

pkg/dumps/parser_dump.go#L107

Added line #L107 was not covered by tests
}

func DumpTree(parserResults ParserResults, bucketPour BucketPourInfo, opts DumpOpts) {
t := newTree()
t.processEvents(parserResults)
t.processBuckets(bucketPour)
t.displayResults(opts)
}

func (t *tree) processEvents(parserResults ParserResults) {
for stage, parsers := range parserResults {
// let's process parsers in the order according to idx
parser_order[stage] = make([]string, len(parsers))
t.parserOrder[stage] = make([]string, len(parsers))

for pname, parser := range parsers {
if len(parser) > 0 {
parser_order[stage][parser[0].Idx-1] = pname
t.parserOrder[stage][parser[0].Idx-1] = pname
}
}

for _, parser := range parser_order[stage] {
for _, parser := range t.parserOrder[stage] {
results := parsers[parser]
for _, parserRes := range results {
evt := parserRes.Evt
if _, ok := state[evt.Line.Time]; !ok {
state[evt.Line.Time] = make(map[string]map[string]ParserResult)
assoc[evt.Line.Time] = evt.Line.Raw
if _, ok := t.state[evt.Line.Time]; !ok {
t.state[evt.Line.Time] = make(map[string]map[string]ParserResult)
t.assoc[evt.Line.Time] = evt.Line.Raw
}

if _, ok := state[evt.Line.Time][stage]; !ok {
state[evt.Line.Time][stage] = make(map[string]ParserResult)
if _, ok := t.state[evt.Line.Time][stage]; !ok {
t.state[evt.Line.Time][stage] = make(map[string]ParserResult)
}

state[evt.Line.Time][stage][parser] = ParserResult{Evt: evt, Success: parserRes.Success}
t.state[evt.Line.Time][stage][parser] = ParserResult{Evt: evt, Success: parserRes.Success}
}
}
}
}

func (t *tree) processBuckets(bucketPour BucketPourInfo) {
for bname, evtlist := range bucketPour {
for _, evt := range evtlist {
if evt.Line.Raw == "" {
continue
}

// it might be bucket overflow being reprocessed, skip this
if _, ok := state[evt.Line.Time]; !ok {
state[evt.Line.Time] = make(map[string]map[string]ParserResult)
assoc[evt.Line.Time] = evt.Line.Raw
if _, ok := t.state[evt.Line.Time]; !ok {
t.state[evt.Line.Time] = make(map[string]map[string]ParserResult)
t.assoc[evt.Line.Time] = evt.Line.Raw

Check warning on line 157 in pkg/dumps/parser_dump.go

View check run for this annotation

Codecov / codecov/patch

pkg/dumps/parser_dump.go#L156-L157

Added lines #L156 - L157 were not covered by tests
}

// there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
// we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
if _, ok := state[evt.Line.Time]["buckets"]; !ok {
state[evt.Line.Time]["buckets"] = make(map[string]ParserResult)
if _, ok := t.state[evt.Line.Time]["buckets"]; !ok {
t.state[evt.Line.Time]["buckets"] = make(map[string]ParserResult)
}

state[evt.Line.Time]["buckets"][bname] = ParserResult{Success: true}
t.state[evt.Line.Time]["buckets"][bname] = ParserResult{Success: true}
}
}
}

func (t *tree) displayResults(opts DumpOpts) {
yellow := color.New(color.FgYellow).SprintFunc()
red := color.New(color.FgRed).SprintFunc()
green := color.New(color.FgGreen).SprintFunc()
whitelistReason := ""

Check warning on line 176 in pkg/dumps/parser_dump.go

View check run for this annotation

Codecov / codecov/patch

pkg/dumps/parser_dump.go#L176

Added line #L176 was not covered by tests
// get each line
for tstamp, rawstr := range assoc {
for tstamp, rawstr := range t.assoc {
if opts.SkipOk {
if _, ok := state[tstamp]["buckets"]["OK"]; ok {
if _, ok := t.state[tstamp]["buckets"]["OK"]; ok {

Check warning on line 180 in pkg/dumps/parser_dump.go

View check run for this annotation

Codecov / codecov/patch

pkg/dumps/parser_dump.go#L180

Added line #L180 was not covered by tests
continue
}
}

fmt.Printf("line: %s\n", rawstr)

skeys := make([]string, 0, len(state[tstamp]))
skeys := make([]string, 0, len(t.state[tstamp]))

for k := range state[tstamp] {
for k := range t.state[tstamp] {
// there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
// we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
if k == "buckets" {
Expand All @@ -180,18 +202,18 @@
var prevItem types.Event

for _, stage := range skeys {
parsers := state[tstamp][stage]
parsers := t.state[tstamp][stage]

sep := "├"
presep := "|"

fmt.Printf("\t%s %s\n", sep, stage)

for idx, parser := range parser_order[stage] {
for idx, parser := range t.parserOrder[stage] {
res := parsers[parser].Success
sep := "├"

if idx == len(parser_order[stage])-1 {
if idx == len(t.parserOrder[stage])-1 {
sep = "└"
}

Expand Down Expand Up @@ -278,12 +300,12 @@

sep := "└"

if len(state[tstamp]["buckets"]) > 0 {
if len(t.state[tstamp]["buckets"]) > 0 {
sep = "├"
}

// did the event enter the bucket pour phase ?
if _, ok := state[tstamp]["buckets"]["OK"]; ok {
if _, ok := t.state[tstamp]["buckets"]["OK"]; ok {
fmt.Printf("\t%s-------- parser success %s\n", sep, emoji.GreenCircle)
} else if whitelistReason != "" {
fmt.Printf("\t%s-------- parser success, ignored by whitelist (%s) %s\n", sep, whitelistReason, emoji.GreenCircle)
Expand All @@ -292,13 +314,13 @@
}

// now print bucket info
if len(state[tstamp]["buckets"]) > 0 {
if len(t.state[tstamp]["buckets"]) > 0 {
fmt.Printf("\t├ Scenarios\n")
}

bnames := make([]string, 0, len(state[tstamp]["buckets"]))
bnames := make([]string, 0, len(t.state[tstamp]["buckets"]))

for k := range state[tstamp]["buckets"] {
for k := range t.state[tstamp]["buckets"] {
// there is a trick : to know if an event successfully exit the parsers, we check if it reached the pour() phase
// we thus use a fake stage "buckets" and a fake parser "OK" to know if it entered
if k == "OK" {
Expand Down
Loading