use crate::*;
pub trait Strategy where Self: Sized {
fn new_unit_count() -> (Self, usize);
fn with_unit_count(unit_count: usize) -> Self;
fn add<Container: Static>(
&mut self, units: &mut Vec<Option<Container>>, container: Container
);
}
#[derive(Clone, Debug)]
pub struct Binary;
impl Strategy for Binary {
fn new_unit_count() -> (Self, usize) {
(Binary, 8)
}
fn with_unit_count(_unit_count: usize) -> Self {
Binary
}
fn add<Container: Static>(
&mut self,
units: &mut Vec<Option<Container>>,
mut container: Container)
{
let len = container.len();
let mut unit_size = 1;
let mut index = 0;
while unit_size < len {
index += 1;
unit_size *= 2;
}
while units.len() <= index {
units.push(None);
}
for unit in &mut units[index..] {
let content = core::mem::replace(unit, None);
match content {
None => {
*unit = Some(container);
return;
}
Some(other) => {
container = container.merge_with(other);
if container.len() <= unit_size {
*unit = Some(container);
return;
}
}
}
}
units.push(Some(container));
}
}
#[derive(Clone, Debug)]
pub struct SimpleBinary;
impl Strategy for SimpleBinary {
fn new_unit_count() -> (Self, usize) {
(SimpleBinary, 8)
}
fn with_unit_count(_unit_count: usize) -> Self {
SimpleBinary
}
fn add<Container: Static>(
&mut self,
units: &mut Vec<Option<Container>>,
mut container: Container)
{
for unit in &mut *units {
let content = core::mem::replace(unit, None);
match content {
None => {
*unit = Some(container);
return;
}
Some(other) => {
container = container.merge_with(other);
}
}
}
units.push(Some(container));
}
}
#[derive(Clone, Debug)]
pub struct SkewBinary {
last_merge: usize
}
impl Strategy for SkewBinary {
fn new_unit_count() -> (Self, usize) {
(SkewBinary { last_merge: 0 }, 8)
}
fn with_unit_count(unit_count: usize) -> Self {
assert!(unit_count > 0);
SkewBinary {
last_merge: 0,
}
}
fn add<Container: Static>(
&mut self,
units: &mut Vec<Option<Container>>,
mut container: Container)
{
if units.len() == 0 {
units.push(Some(container));
return;
}
let unit = &mut units[self.last_merge];
let content = core::mem::replace(unit, None);
match content {
None => {
*unit = Some(container);
return;
}
Some(other) => {
container = container.merge_with(other);
}
}
let new_index = self.last_merge + 1;
if units.len() == new_index {
units.push(Some(container));
self.last_merge = 0;
return;
}
let unit = &mut units[new_index];
let content = core::mem::replace(unit, None);
match content {
None => {
*unit = Some(container);
self.last_merge = 0;
}
Some(other) => {
*unit = Some(container.merge_with(other));
self.last_merge = new_index;
}
}
}
}