Hi Kenton, 

As a follow up to the case of structs containing pointer/non-primitive 
types, might there currently exist workarounds to being able to resize 
lists of these structs (like the one below) at the back of a message: 
perhaps removing the allocated non-primitive data or embedding them inline 
in the struct?

```
struct FourPoints {
    pt1 @0 :import "vector2.capnp".Vector2f; # bottom-left
    pt2 @1 :import "vector2.capnp".Vector2f; # bottom-right
    pt3 @2 :import "vector2.capnp".Vector2f; # top-right
    pt4 @3 :import "vector2.capnp".Vector2f; # top-left
}

# the size of TagDetection is known
struct TagDetection {
    id @0 :UInt32;
    hammingDistance @1 :UInt8;
    tagSize @2 :Float32;
    areaPixel @3 :Float32; # number of pixels the tag occupies in the image

    tagCenter @4 :import "vector2.capnp".Vector2f;

    # corners
    pointsPolygon @5 :FourPoints;
    pointsUndistortedPolygon @6 :FourPoints;

    poseInCameraFrame @7 :import "se3.capnp".Se3; # in RDF camera frame
}
```

Of course, I could manually list the primitive fields of the constituent 
non-primitive types of the struct, but I'm trying to avoid having to do 
this.

- Gokul
On Monday, December 12, 2022 at 9:22:22 PM UTC+8 Hui min wrote:

> Hi Kenton,
>
> Got it, it makes sense. So if I remove `labelString` data from the 
> definition, I could use truncate function to operate my detections @4 
> :List(Detection2d); object. Thanks!
>
> On Tuesday, 6 December 2022 at 10:43:17 pm UTC+8 [email protected] 
> wrote:
>
>> Hi Hui,
>>
>> Again sorry for the slow reply.
>>
>> In fact, the functionality you suggest does exist today, in the form of 
>> `capnp::Orphan<T>::truncate()`, which can be used to resize a list 
>> (truncate *or* extend), doing so in-place if possible. If the list is at 
>> the end of the message, it's possible it can be extended in-place. To use 
>> it, you would do:
>>
>> ```
>> auto orphan = reader.disownDetections();
>> orphan.truncate(newSize);
>> reader.adoptDetections(kj::mv(orphan));
>> ```
>>
>> HOWEVER, there is a problem that might apply to your sample use case: 
>> Your `Detection2d` struct contains `labelString @1 :Text`, which is a 
>> pointer type. When you set this field to a string value, the string is 
>> allocated at the end of the message. This means your list is *not* at the 
>> end of the message anymore, so you are no longer able to resize the list to 
>> make it longer. To be able to extend your list, you will need the list to 
>> contain only primitive types, so that it stays at the end of the message.
>>
>> -Kenton
>>
>> On Sat, Nov 5, 2022 at 9:16 PM Hui min <[email protected]> wrote:
>>
>>> Hi Cap'n Proto Team,
>>>
>>> Thanks for the amazing tool you have created so far.
>>>
>>> Understand that with the current design of arena style memory 
>>> allocation, we cannot simply reuse the message, and re-init List() object 
>>> to send it again. This will cause the message to grow every time we send 
>>> (memory leak).
>>>
>>> However, sending variable length data is still pretty common practice. 
>>> If we have to reallocate a brand new heap for new message, it is quite 
>>> wasteful. In most cases however, the variable length list is just one. So I 
>>> have an idea.
>>>
>>> ```
>>> struct Detection2d {
>>>
>>>     labelIdx @0 :UInt32;
>>>     labelString @1 :Text;
>>>     xmin @2 :Float32;
>>>     xmax @3 :Float32;
>>>     ymin @4 :Float32;
>>>     ymax @5 :Float32;
>>>     confidence @6 :Float32;
>>>
>>> }
>>>
>>> struct Detections2d {
>>>
>>>     header @0 :import "header.capnp".Header;
>>>
>>>     imageData @1 :Data; # should be RGB
>>>
>>>     width @2 :UInt32;
>>>     height @3 :UInt32;
>>>
>>>    detections @4 :List(Detection2d);
>>> }
>>> ```
>>>
>>> In this case, I have put the variable length object at the vary last. 
>>> That means everything in front is fix length. Is there a way i could force 
>>> the Capnproto to discard the memory of the old List and create a new one 
>>> directly from its old memory location, with out leaking a chunk of memory 
>>> in the arena?
>>>
>>> If it is not currently possible, do you think it is a convenient 
>>> function to be added? Thanks!
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Cap'n Proto" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to [email protected].
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/capnproto/c500ece7-1871-4015-ba78-f456365a8bc3n%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/capnproto/c500ece7-1871-4015-ba78-f456365a8bc3n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/1b3e3492-ab37-4a42-8b00-dd9e4871a0fbn%40googlegroups.com.

Reply via email to