On Wed, Mar 5, 2025 at 6:33 AM <arthur@xxxxxxxxxxxxxxx> wrote: > > +struct __trait_hdr { > + /* Values are stored ordered by key, immediately after the header. > + * > + * The size of each value set is stored in the header as two bits: > + * - 00: Not set. > + * - 01: 2 bytes. > + * - 10: 4 bytes. > + * - 11: 8 bytes. ... > + * - hweight(low) + hweight(high)<<1 is offset. the comment doesn't match the code > + */ > + u64 high; > + u64 low; ... > +static __always_inline int __trait_total_length(struct __trait_hdr h) > +{ > + return (hweight64(h.low) << 1) + (hweight64(h.high) << 2) > + // For size 8, we only get 4+2=6. Add another 2 in. > + + (hweight64(h.high & h.low) << 1); > +} This is really cool idea, but 2 byte size doesn't feel that useful. How about: - 00: Not set. - 01: 4 bytes. - 10: 8 bytes. - 11: 16 bytes. 4 byte may be useful for ipv4, 16 for ipv6, and 8 is just a good number. And compute the same way with 3 popcount with extra +1 to shifts.