Any way to manipulate fat pointers generically?

I'm thinking about how to extend my internment crate to support interning of dynamically sized types. I can see how to do this by holding a &'static T in the Intern<T>, which is safe and fits with the current implementation.

However, storing a reference to a DST doubles the size of the Intern<T> for DSTs relative to an optimal implementation, because the reference is a fat pointer which stores both the data and its size. For ordinary references or Box<T> this is not a problem, but the point of interning your type is to have fast comparison and hashing, under the assumption that you will have many references to the same datum. So storing the size on the heap alongside the data would make a lot more sense than storing the size alongside every pointer to that data.

For individual DST types there tends to be an unsafe from_raw_parts method that allows to construct a reference from size and pointer. But I'm wondering if there is any way to do so in a correct and sound manner for a generic unsized type?

I think this is what the Pointee trait (on nightly) is meant to allow. pointer::to_raw_parts will split apart an arbitrary pointer into its two fields, and std::ptr::from_raw_parts{,_mut} will put them back together again.

1 Like

You can wrap it in a newtype which only uses data pointer for comparison and hashing. If the size is stired on the heap, Intern<str> => &str conversion will trigger more cache misses.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.