Created
September 20, 2020 21:51
-
-
Save Ichbinjoe/dc7dbc2781012a474ce0eabf2a31c67e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unsafe fn expand_to_fit_elements(&self, additional: usize) -> Result<Cap::Masker, ()> { | |
let logical_size = self.head.get() - self.base.get(); | |
let new_logical_size = logical_size + additional; | |
let current_capacity = self.capacity.get(); | |
let current_size = current_capacity.size(); | |
let current_mask = current_capacity.make_mask(); | |
if new_logical_size > current_capacity { | |
// We have to expand to fit the new elements | |
let new_capacity = current_capacity.increase(new_logical_size)?; | |
let new_mask = new_capacity.make_mask(); | |
let new_buffer = create_buffer(new_capacity); | |
// The elements are copied over in (up to) three shots, but generally the naive cost of | |
// doing these copies will always be the same (we only copy parts of the buffer that we | |
// are using) but generally these copies will be small enough that the real bottleneck | |
// for the system will likely be branching or some other code flow problems. This | |
// should be called infrequently enough (at least in the use I want it for :) ) that | |
// its not worth optimizing super heavily (for example in the special pow2 case, where | |
// this can be simplified to be a two part pivot). | |
let old_baser = self.capacity.get().make_base(); | |
let new_baser = new_capacity.make_base(); | |
let base = self.base.get(); | |
let head = self.head.get(); | |
let old_pivot = Cap::base(old_baser, head); | |
let new_pivot = Cap::base(new_baser, head); | |
let from_buffer = self.ring.get(); | |
let pivot1 = floored_min!(base, head, old_pivot, new_pivot); | |
copy_range(from_buffer, new_buffer, current_mask, new_mask, base, pivot1); | |
if pivot1 != head { | |
let pivot2 = floored_min!(pivot1, head, old_pivot, new_pivot); | |
copy_range(from_buffer, new_buffer, current_mask, new_mask, pivot1, pivot2); | |
if pivot2 != head { | |
let pivot3 = head; | |
copy_range(from_buffer, new_buffer, current_mask, new_mask, pivot2, head); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment