El 14/05/2017 a las 17:01, Ion Gaztañaga escribió:
Hi Joaquín,
Some additional comments about the design:
///////////////////////// // Memory indirections /////////////////////////
If I understand code correctly, the internal structure of a poly collection is approximately:
1) poly_collection stores an unordered_map
2) segment_type stores a unique_ptr
and segment_backend_is an abstract class, so roughly equivalent to unique_ptr (both packed_segment/split_segment derive from segment_backend. 3) packed_segment/split_segment stores a vector of concrete types.
So we need 3 memory hops to navigate between the "this" pointer of a PolyCollection to a pointer to a concrete type: poly_collection -> unordered node -> segment in unique_ptr -> vector value.
I think the data structure could be optimized to save one indirection. segment_type could directly hold the class derived from segment_backend as packed_segment/split_segment will need the same size and alignment requirements regardless of the ConcreteType they hold (as long as they use std::vector). This could improve insertion times and other operations. This optimization could also make easier to fix the following section (allocator propagation).
*Main question 1*: Do you find think PolyCollection should implement this optimization?
How do yo envision this could be done? Replacing the current
std::unique_ptr
///////////////////////// // Allocator propagation /////////////////////////
As mentioned in Adam Wulkiewicz's review PolyCollection currently does not propagate the allocator from the constructor argument of poly_collection to the concrete type. From a practical point of view, the key requirement is that all intermediate memory until the concrete type must be allocated using the same root allocator passed when a poly_collection was constructed, and that allocator must be propagated also to the concrete type.
We have a problem here: your key requirement can be split in two:
A. Allocator is propagated down the data structure for memory allocaion
B. allocator_traits
[...]
I think that a unique memory source for all internal structures and the correct propagation of the allocator using allocator_traits is a very interesting feature for PolyCollection.
Hopefully answered above.
[...]
*Main question 2*: Do you think PolyCollection should support stateful allocator using the scoped allocator model?
Now, the scoped allocator model is an even stronger requirement than we have discussed so far. I don't have the necessary expertise in this, but I fail to see the applicability to PolyCollection from a cursory glance at N2554.
Some specific notes that might show places where the scoped allocator model has problems.:
[...]
- The "emplace" operation uses a placement new to wrapped in a lambda which is type-erased with a captureless lambda. It looks to me that instead of delegating the work into the value_holder, the type erasure arguments should be treated by the segment so that internal vectors propagate the allocator when needed.
I don't see how this could be done: type erasure must happen before segment is used, and actual args types are then unknown to segment... Care to elaborate? Joaquín M López Muñoz