-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#504] slotmap #505
[#504] slotmap #505
Conversation
6f5a29a
to
4a64832
Compare
4a64832
to
364d62d
Compare
faa15dc
to
31aca34
Compare
31aca34
to
2b3c766
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #505 +/- ##
==========================================
- Coverage 79.22% 79.08% -0.14%
==========================================
Files 200 201 +1
Lines 23765 24139 +374
==========================================
+ Hits 18828 19091 +263
- Misses 4937 5048 +111
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good in general.
n => Some(self.data[n].as_ref().expect( | ||
"data and idx_to_data correspond and this value must be always available.", | ||
)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just use a ManuallyDrop<T>
instead of an Option<T>
if the value must always be available?
... okay, after some thinking, it would need to be a ManuallyDrop<MaybeUninit<T>>
which makes it more cumbersome to use.
pub struct FixedSizeSlotMap<T, const CAPACITY: usize> { | ||
state: RelocatableSlotMap<T>, | ||
_idx_to_data: MaybeUninit<[usize; CAPACITY]>, | ||
_idx_to_data_free_list: MaybeUninit<[FreeListEntry; CAPACITY]>, | ||
_data: MaybeUninit<[Option<T>; CAPACITY]>, | ||
_data_next_free_index: MaybeUninit<[usize; CAPACITY]>, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is something that could easily be created with a proc macro. No so sure about implementing default
via the proc macro. That might be more difficult but at least the struct members would automatically be kept in sync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are maybe right. Sooner or later we have to revisit the relocatable container concept and then we introduce something like this here. Currently, I would stick to the current approach since it is used also in the other containers - but I agree, I also do not like it at all!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if there is currently another way to do it, except having a proc macro that calculates the memory size and adds a buffer: [u8; N]
member to the struct. Anyway, without a proc macro the current way is less cumbersome and with the proc macro it doesn't really matter since it's hidden from the developer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. My advice with inpsect
tuned out to not work with Rust 1.75.
Notes for Reviewer
The
SlotMap
is required to store multiple data segments and fixed indices so that the senders and receivers of a shared memory communication can manage them (add/remove at runtime). When a sender runs out of memory a new data segment is added at the same index by every participant and this index is part of the memory offset the sender delivers to the receiver via the zero copy channel.The RelocatableContainer concept had to be cleaned up a bit in order to implement the
SlotMap
.details::Meta**
**
,Relocatable**
types are definedFixedSize**
contains aRelocatable**
and provides the memoryExample:
details::MetaQueue
(implementation).Queue
(runtime fixed-size heap version),ReloctableQueue
(runtime fixed-size shared memory version),FixedSizeQueue
(compile-time fixed-size shared memory version)The
ReloctableContainer
trait contained anew()
method where a relative position to the memory had to be provided. This was removed since it was too error prone to use. TheBumpAllocator
in combination with the already existingnew_uninit
+init(allocator)
approach was used to replace it.This is relevant for all
FixedSize**
versions.Since Rust does not allow any compile time const operations we could not use in the fixed size version pre-allocated memory in the form of
To make the code somehow readable, the actual payload members where listed after the
RelocatableVersion
in the struct definition.Also, the
RelocatableVec
had to be refactored to follow thedetails::MetaVec
,Vec
,RelocatableVec
,FixedSizeVec
pattern so that it could be used in the implementation of theSlotMap
.Pre-Review Checklist for the PR Author
SPDX-License-Identifier: Apache-2.0 OR MIT
iox2-123-introduce-posix-ipc-example
)[#123] Add posix ipc example
)task-list-completed
)Checklist for the PR Reviewer
Post-review Checklist for the PR Author
References
Closes #504