How to model objects with comparable fields in protobuf - protocol-buffers

Given 3 objects A, B and C where:
A and B share a number of fields, but also each have unique fields
all fields of both A and B are in C, which also some extra unique fields
Obviously I could model this in protobuf by creating separate messages for every object:
message A {
uint32 A_B = 1;
uint32 A_C = 2;
}
message B {
uint32 A_B = 1;
uint32 B_C = 2;
}
message C {
uint32 A_B = 1;
uint32 A_C = 2;
uint32 B_C = 3;
uint32 onlyC = 4;
}
But I was wondering whether it makes sense to create a single, generic message for all three objects and add a field that tells me which specific object I'm dealing with?
message Generic {
enum Specific{
A = 1;
B = 2;
C = 3;
}
Specific obj = 1;
uint32 A_B = 2;
uint32 A_C = 3;
uint32 B_C = 4;
uint32 onlyC = 5;
}
I know both options are possible from a technical point of view, but is the second one somehow not according to how things should be done in protobuf?
Note: in my specific case, the objects represent API call argument lists that won't change in the future.

Related

Protobuf structure with bytes field

There is a protobuf structures
message A {
bytes B = 1;
}
message B {
int32 c = 1;
int64 d = 2;
string x = 3;
}
If we put the bytes of the same encoded proto-buffer in the A.B field
and decode or encode
pseudocode:
newA = &A{}
newB = &B{x:"123",c:1,d:3}
bytes_of_B = marshall(type(B), newB)
newA.B = bytes_of_B
bytes_of_A = marshall(type(A), newA)
pseudocode:
newA = unmarshall(bytes_of_A, type(A))
newB = unmarshall(newA.B, type(B))
how true is this and what may be the consequences of this
At the wire/payload level, this scenario is 100% identical to
message A {
B B = 1;
}
So: no consequences as such, but telling A to expect a B may be more convenient.

How can I record constant values on omnet++?

How can I get constant values from a message and show these values in a result (histogram)?
My message structure is:
message msgCLAS
{
int Singclas = 2206;
int Singlial = 3009;
int Verifclas = 5403;
int Veriflial = 6406;
int Aggreclas = 2;
int Aggrelial = 2;
int Verifagclas = 1833;
int Verifaglial = 1857;
}

How to format protobuf file more nicely using clang-format?

I am formatting my porotbuf file nicely, here is a example:
message StealCache {
string CurStealTargetUID = 1;
uint32 CurStealMoney = 2;
repeated TargetList TargetLists = 3;
uint32 Count = 4;
uint32 Timestamp = 5;
StealTreasureBox StealBox = 6;
uint32 ExtraStealMoney = 7;
}
The current clang-format style tag is:
{BasedOnStyle: Google,
AlignConsecutiveDeclarations: true,
AlignConsecutiveAssignments: true,
ColumnLimit: 0,
IndentWidth: 4}
But what I want is like this:
message StealCache {
string CurStealTargetUID = 1;
uint32 CurStealMoney = 2;
repeated TargetList TargetLists = 3;
uint32 Count = 4;
uint32 Timestamp = 5;
StealTreasureBox StealBox = 6;
uint32 ExtraStealMoney = 7;
}
How could I modify my clang-format style?
This problem was resolved when llvm(9.0.0) upgraded.

Fast GCF algorithm using linked list

I am using a 2 linked list to represent 2 very long integers, each digit occupy one node. I need to compute for their gcf fast but my current algorithm computes for a very long time. Please help me improve it/or if you can suggest other faster algorithms for linked list.
here's my current code:
int findGCD(number **larger, number **small, number **gcdtop){
number *a = *larger, *b = *small, *aptr, *bptr;
printlist(larger);
printlist(small);
int equal = checkEqual(a, b); //traverse through linked list a & b and compare if equal, returns 1 if true
int large=0, borrow=0, adata=0, bdata=0, i=0;
while(equal!=1){
equal = checkEqual(a, b);
if(equal==1) break;
flip(&a); //Flips the linked list
flip(&b);
large = whatGreater(&a, &b); //Checks which linkedlist is greater
flip(&a); //Flip it back
flip(&b);
borrow=0;
//Do repeated subtraction (Euclid's algorithm)
if(large==1){
aptr = a;
bptr = b;
while(a && b){
adata = a->data;
bdata = b->data;
adata = adata - borrow;
if(adata>=bdata){
a->data = (adata-bdata);
borrow=0;
}
else if(adata<bdata){
adata = adata+10;
a->data = (adata-bdata);
borrow = 1;
}
a = a->next;
b = b->next;
}
a = aptr;
b = bptr;
}
else if(large==0){
aptr = a;
bptr = b;
while(a && b){
adata = a->data;
bdata = b->data;
bdata = bdata - borrow;
if(bdata>=adata){
b->data = (bdata-adata);
borrow=0;
}
else if(bdata<adata){
bdata = bdata+10;
b->data = (bdata-adata);
borrow = 1;
}
a = a->next;
b = b->next;
}
a = aptr;
b = bptr;
}
}
I believe doing this division/modulo would be faster but I cannot implement it in linked list.
Here's a sample input: 15424832369192002264032565635067237193339888184999832384884463019917546384661904, 65227
Thank you in advance.

Left Join LINQ and using Bitwise Comparisons

Left Join LINQ and using Bitwise Comparisons.
I have a problem that can be described as (thanks to David B for clarifying this):
The goal is to return 1 row per OID from the Left Table, where the Count of the records in the left table is equal to the Count of the matching rows in the right table. A record matches when the OID, RID, and the FLAG is set in FLAGS for a row.
The Objects we are comparing have the following structure:
public class Roads : List<Road>{}
public class Road
{
public int RID;
public int OID;
public int Check = 1;
public long Flag;
}
public class Cars : List<Car> { }
public class Car
{
public int RID;
public int OID;
public long Flags;
}
The objects a filled with the following data.
Roads rs = new Roads();
Cars cs = new Cars();
Car c = new Car();
c.OID = 1;
c.RID = 1;
c.Flags = 31; // 11111
cs.Add(c);
c = new Car();
c.OID = 1;
c.RID = 2;
c.Flags = 31; //11111
cs.Add(c);
c = new Car();
c.OID = 1;
c.RID = 3;
c.Flags = 4; //00100
cs.Add(c);
Road r = new Road();
r.OID = 1;
r.RID = 1;
r.Flag = 8; //00010
rs.Add(r);
r = new Road();
r.OID = 1;
r.RID = 2;
r.Flag = 2; //01000
rs.Add(r);
r = new Road();
r.OID = 1;
r.RID = 3;
r.Flag = 4; //01000
rs.Add(r);
// r = new Road();
// r.OID = 1;
// r.RID = 3;
// r.Flag = 16; //00001
// rs.Add(r);
To see if a flag is set you do a bitwise comparison, i.e. cs[0].Flags && rs[0].Flag > 0 is TRUE, cs[0].Flags & rs[0].Flag = 0 is FALSE
I have this general query that will get me the rows where the count of OID in cs = the count of matching OID in rs. I need a modified query now where the rest of the rules are applied. Where we check if the Flag is in the Flag for the specific row match.
var carLookup = cs.ToLookup(cb => c.OID);
var roadLookup = rs.ToLookup(rb => r.OID);
var results1 = from x in carLookup
let carCount = x.Count()
let roadCount = roadLookup[x.Key].Count()
where carCount == roadCount
select new { OID = x.Key, CarCount = carCount, RoadCount = roadCount };
How can I extend this to get the additional filter conditions applied? What I am struggling with is having columns available where I need them to build the proper filter conditions. For example, I need to compare Flags && Flag. But how do I get so I have access to Flag and Flags to do the additional filter?
To Expand. I work mostly with TSQL, so I'm trying to mimic a logic flow I can easily apply in TSQL. If I was doing this with TSQL, it would look like this (note special case for 0):
SELECT cs.OID, Count(cs.OID) AS CarCount, Sum(RS.Check) AS RoadCount
FROM Cars AS cs
LEFT JOIN Roads AS RS
ON CS.oid = RS.OID
AND cs.RID = RS.RID
AND (CS.FLAGS & RS.FLAG > 0
OR (CS.FLAGS=0 AND RS.FLAG=0))
GROUP BY cs.OID
HAVING Count(cs.OID) = Sum(RS.Check)
With that statement, and the data above, the result would be
1, 3, 3.
If I were to comment the last add to Roads, and uncomment the next line, changing the Flag to 16, then the result would be:
NULL
Please comment if you need more info.
I think this should be equivalent to your SQL statement, however it didn't produce the result you mentioned since your SQL uses RS.Check but you didn't assign any Check values in your sample code (you used r.OID). I went ahead and added r.Check = 1; to each Road object and was able to get the result you mentioned.
var query = from car in cs
from road in rs
where car.OID == road.OID
&& car.RID == road.RID
&& ((car.Flags & road.Flag) > 0 || (car.Flags == 0 && road.Flag == 0))
group new { car, road } by car.OID into grouping
let CarCount = grouping.Count()
let RoadCount = grouping.Sum(o => o.road.Check)
where CarCount == RoadCount
select new { OID = grouping.Key, CarCount, RoadCount };

Resources