Skip to content

Instantly share code, notes, and snippets.

@Ichbinjoe
Created September 20, 2020 21:51
Show Gist options
  • Save Ichbinjoe/dc7dbc2781012a474ce0eabf2a31c67e to your computer and use it in GitHub Desktop.
Save Ichbinjoe/dc7dbc2781012a474ce0eabf2a31c67e to your computer and use it in GitHub Desktop.
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