Closed balusu-murali closed 3 years ago
[ep_node.h: line 16] Add type_name
field
struct ep_field_s {
ERL_NIF_TERM name;
occurrence_type_e o_type;
field_type_e type;
// ERL_NIF_TERM type_name;
ep_node_t *sub_node;
ERL_NIF_TERM sub_name;
ERL_NIF_TERM defaut_value;
uint32_t id;
uint32_t fnum;
uint32_t rnum;
uint32_t proto_v;
uint32_t is_oneof;
uint32_t packed;
};
[ep_node.c: line 195] Assign field type name
[ep_node.c: line 737] Add compare type name function
int
get_field_compare_type_name(const void *a, const void *b)
{
return (int) (*((ERL_NIF_TERM *) a) - ((ep_field_t *) b)->type_name);
}
Call bsearch function
Hope that helps. However, we cannot find the right field, if we have duplicated types.
Thank you @jg513 for getting back.
- [ep_node.c: line 195] Assign field type name
Looking at the code there.. it feels like sub_name should basically have the name set in case of oneOf fields.. correct?
However, we cannot find the right field, if we have duplicated types.
Yeah, I am okay with this restriction in our usecase.
I think that would work actually.. because for bsearch the input needs to be sorted based on the these names.
let me know what you think?
sub_name
can store field type, because oneOf type does not use it. But the field name of sub_name
is confusing.
sub_name
can store field type, because oneOf type does not use it. But the field name ofsub_name
is confusing.
Okay.
- You could loop for oneOf fields and compare, without using bsearch. Then field definition can be in any order.
I dont want to since it might hurt performance. can I pre-sort them by the type name somehow?
I guess if oneOf type contains less than 5 or 6 fields, a loop maybe faster.
If you want to sort the fields, following may help:
struct ep_node_s {
node_type_e n_type;
ERL_NIF_TERM name;
uint32_t id;
uint32_t proto_v;
uint32_t size;
uint32_t v_size;
void *fields;
void *v_fields;
};
node->fields is sorted by name node->v_fields is sorted by enum value, or by field index number
You may add another sorted fields
I see. will try that and let you know.
node->fields is sorted by name node->v_fields is sorted by enum value, or by field index number
You may add another sorted fields
I am trying to do it.. but I'm not able to sort these fields.. throws me an error and its been very hard to debug.. any suggestions on how to add a new pointer to point to a list of fields sorted based on their type?
this is what i have so far: https://github.com/HalloAppInc/enif_protobuf/pull/4
I viewed your changes, and maybe found a possible reason. In ep_node.c -> make_node, it not alloc l_fields when n_type is node_enum. But in parse_enum_fields function, the l_fields is used.
If that's not the cause, you may print out the fields
and l_fields
memory as hex, in ep_encoders.c -> get_oneof_field. And compare the content.
And I think, copy fields to l_fields is much easier, than calculating l_fields everywhere
qsort(node->fields, node->size, sizeof(ep_enum_field_t), sort_compare_enum_field);
qsort(node->l_fields, node->size, sizeof(ep_enum_field_t), sort_compare_sub_name_l_field);
qsort(node->fields, node->size, sizeof(ep_enum_field_t), sort_compare_enum_field);
// memcopy node->fields to node->l_fields, then sort node->l_fields
qsort(node->l_fields, node->size, sizeof(ep_enum_field_t), sort_compare_sub_name_l_field);
I am on our national day holiday, may not response in time.
thank you for getting back inspite of your schedule. really appreciate it.
Here's my fix: https://github.com/HalloAppInc/enif_protobuf/pull/5/commits/3a95f9b38243f2c422341cec21cfe69f42b72c2b let me know what you think?
Yes, I think that's the most simple way for your usecase.
thank you for your help.
Hi, I am using gpb create the message definitions and then loading them using enif_protobuf for the codec. The issue I face is the following:
For definition like this:
Final erlang records for
Three
would look something like this:In my case, it is guaranteed that each of these oneof fields will be different record types: in these cases, I would like to get rid of this additional tuple and make it look something like this:
I figured out the changes to do in enif_protobuf: https://github.com/HalloAppInc/enif_protobuf/pull/2/commits/01b8c607b248a85ca1a25b890d8323900d3171d7 However, the issue is when encoding we search for the field number using the field_name. [specifically, line 622-626 bsearch function call]. I want to avoid that and do the search using the types of the fields. Is there a way for me to do that? can you please let me know. any pointers would really be appreciated?
If you'd like this change, I can add it to be an option for enif_protobuf and send out a PR for this.