lilyball / swift-deque

A double-ended queue collection for Swift
Apache License 2.0
8 stars 1 forks source link

Swap storage with empty during withContiguousMutableStorageIfAvailable #5

Closed lilyball closed 3 years ago

lilyball commented 3 years ago

During a call to withContiguousMutableStorageIfAvailable we may want to swap our deque's storage out for the empty storage, so accesses to the deque from inside the block can't interfere with our mutable buffer. This is necessary because, being a mutating function, it won't retain the buffer and therefore any direct mutation of the Deque won't trigger CoW. This also helps protect us from reads of the Deque if we've put the buffer into a temporarily-inconsistent state (e.g. uninitializing some elements).

Doing this will match Array's behavior, though I'm not sure how much of Array's behavior is motivated by an array optimization we won't have access to. Strictly speaking, users shouldn't be touching the Deque from inside the closure given to this method, but it's pretty cheap to protect them (swapping the pointer twice, and a retain/release of the empty storage buffer if Swift can't optimize that out) so we may as well.

lilyball commented 3 years ago

Done.