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 ken...@cloudflare.com 
> 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 <cgz...@sina.com> 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 capnproto+...@googlegroups.com.
>>> 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 capnproto+unsubscr...@googlegroups.com.
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