Skip to content

Add fields order - #550

Merged
rs merged 3 commits into
rs:masterfrom
madkins23:add-fields-order
May 4, 2024
Merged

rs merged 3 commits into
rs:masterfrom
madkins23:add-fields-order

Conversation

@madkins23

Copy link
Copy Markdown
Contributor

After I did this work I saw PR 170 which is apparently languishing. My bad for not checking first. On the other hand this PR currently has no merge issues and I have time to respond to comments.

Comment thread console.go Outdated
isOrdered = true
break
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a map would make this check more efficient. I often end up using simple map[string]bool type maps so I can quickly do if _, found := myMap[key]; found {...} type logic with efficiency.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree and would have done it that way (and maybe saved the map on the ConsoleWriter for reuse) but the surrounding code was just iterating in a loop (see FieldsExclude just above) and I didn't want to break with the original author's style. Or worse yet start randomly fixing the existing loop(s).

That said, I don't mind making any reasonable change that will help the PR get accepted and merged.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood - for FieldsOrder is would probably make sense though for the performance benefit, especially as this is likely to be a lot larger than FieldsExclude; but I certainly understand the concern of matching style.
Any how...just my $0.02 FWIW.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got a round toit.

Comment thread .gitignore

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should remove this commit, because this is irrelevant with the feature we want to implement.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread go.mod

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dependencies should not be updated by an feature implementing pull request for same reason: this is irrelevant with the feature we want to implement.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@rs

rs commented Mar 2, 2024

Copy link
Copy Markdown
Owner

Could you please make this change not allocating additional memory on each write if the feature is not used?

@madkins23

Copy link
Copy Markdown
Contributor Author

Good idea. That also cleaned up the code a lot. Not sure what I was thinking when I did all that before. :-(

I stored a map[string]bool on the ConsoleWriter to speed up subsequent calls. It won't get created until the first call to orderFields so it's just a wasted pointer otherwise, and ConsoleWriter shouldn't be created a bunch of times unless I'm missing something.

BTW, there's another similar situation with FieldsExclude at the beginning of ConsoleWriter.writeFields that could be solved the same way. The current solution iterates over w.FieldsExclude for each field which feels like O(n^2). I don't mind writing the PR if you agree @rs.

Both of those last two notes assume that ConsoleWriter fields don't get changed over time. If that is not true then I need to remove that tweak on this PR. The w.FieldsExclude issue might still benefit from being converted to a map[string]bool at the beginning of ConsoleWriter.writeFields.

@rs rs left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider the suggested changes to avoid allocations.

Comment thread console.go
Comment on lines 193 to +198
sort.Strings(fields)

if len(w.FieldsOrder) > 0 {
fields = w.orderFields(fields)
}

@rs rs Mar 3, 2024 •

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
sort.Strings(fields)
if len(w.FieldsOrder) > 0 {
fields = w.orderFields(fields)
}
if len(w.FieldsOrder) > 0 {
w.orderFields(fields)
} else {
sort.Strings(fields)
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread console.go Outdated
Comment on lines +334 to +355
if w.fieldIsOrdered == nil {
w.fieldIsOrdered = make(map[string]bool)
for _, fieldName := range w.FieldsOrder {
w.fieldIsOrdered[fieldName] = true
}
}
hasOrderedField := make(map[string]bool)
otherFields := make([]string, 0, len(fields))
for _, fieldName := range fields {
if w.fieldIsOrdered[fieldName] {
hasOrderedField[fieldName] = true
} else {
otherFields = append(otherFields, fieldName)
}
}
result := make([]string, 0, len(fields))
for _, fieldName := range w.FieldsOrder {
if hasOrderedField[fieldName] {
result = append(result, fieldName)
}
}
return append(result, otherFields...)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if w.fieldIsOrdered == nil {
w.fieldIsOrdered = make(map[string]bool)
for _, fieldName := range w.FieldsOrder {
w.fieldIsOrdered[fieldName] = true
}
}
hasOrderedField := make(map[string]bool)
otherFields := make([]string, 0, len(fields))
for _, fieldName := range fields {
if w.fieldIsOrdered[fieldName] {
hasOrderedField[fieldName] = true
} else {
otherFields = append(otherFields, fieldName)
}
}
result := make([]string, 0, len(fields))
for _, fieldName := range w.FieldsOrder {
if hasOrderedField[fieldName] {
result = append(result, fieldName)
}
}
return append(result, otherFields...)
if w.fieldIsOrdered == nil {
w.fieldIsOrdered = make(map[string]int)
for i, fieldName := range w.FieldsOrder {
w.fieldIsOrdered[fieldName] = i
}
}
sort.Slice(fields, func(i, j int) bool {
ii, iOrdered := w.fieldIsOrdered[fields[i]]
jj, jOrdered := w.fieldIsOrdered[fields[j]]
if iOrdered && jOrdered {
return ii < jj
}
if iOrdered {
return true
}
if jOrdered {
return false
}
return fields[i] < fields[j]
})

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@rs
rs merged commit c78e50e into rs:master May 4, 2024
@madkins23
madkins23 deleted the add-fields-order branch May 4, 2024 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants