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

[Golang] <set> does not compile #1047

Open
szymonwieloch opened this issue Jan 20, 2025 · 1 comment
Open

[Golang] <set> does not compile #1047

szymonwieloch opened this issue Jan 20, 2025 · 1 comment

Comments

@szymonwieloch
Copy link

Hi. Recently I generated golang code and discovered that it didn't compile. The problem seems quite severe - no <set> element can be correctly generated. But it's actually quite easy to fix.

Schema:

<set name="OrderFlags" encodingType="uint64">
<choice name="SomeVal">0</choice>
...
</set>

Generated code:

type OrderFlags [64]bool
type OrderFlagsChoiceValue uint8
type OrderFlagsChoiceValues struct{
    SomeVal OrderFlagsChoiceValue
...

var OrderFlagsChoice = OrderFlagsChoiceValues{uint64(0), uint64(1) ...}

Now, this has no chance of being compiled because uint64 cannot be converted into OrderFlagsChoiceValue since in golang those are different types. The last line therefore raises an error. I suspect that the intention was to generate something like this:

var OrderFlagsChoice = OrderFlagsChoiceValues{OrderFlagsChoiceValue(0), OrderFlagsChoiceValue(1) ...}

Or just the numbers as golang considers numbers to be "untyped".

Aside from the main issue: I have a question about the implementation. Since the generated code does not work anyway, could we replace it with something more efficient? If you have a look at the implementation of the Encode() and Decode() methods, you will quickly spot that the algorithm iterates 64 times over the array to generate just one set element. For a low level protocol such a SBE this operation seems to be way more costly than any other element of SBE. Instead you could just use standard binary operations.

Rough proposal:

type OrderFlags uint64
type OrderFlagsChoiceValues struct {
    SomeVal OrderFlags
    ....

var OrderFlagsChoice = OrderFlagsChoiceValues{
    SomeVal = 1 << 0,
    ...


// example use
msg.OrderFlags = proto.OrderFlagsChoice.SomeVal | proto.OrderFlagsChoice.SomeOtherVal

// check if set
if ((msg.OrderFlags & proto.OrderFlagsChoice.SomeVal) != 0){

Even move golangish version and probably a bit faster (but less consistent with other generated code):

type OrderFlags uint64
const OrderFlagsSomeVal OrderFlags = 1 << 0
....

msg.OrderFlags = proto.OrderFlagsSomeVal | proto.OrderFlagsSomeOtherVal

This way encoding and decoding becomes just a direct write of 8 bytes .

@szymonwieloch szymonwieloch changed the title [Golang} <set> does not compile [Golang] <set> does not compile Jan 20, 2025
@vyazelenko
Copy link
Contributor

/cc @ethanf

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

No branches or pull requests

2 participants