Skip to content
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

Massive refactoring #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ erl_crash.dump
*.ez

# Ignore the output of benchmarking
/bench/results
/bench/results

# IDEA specific
native/sorted_set_nif/.idea
125 changes: 125 additions & 0 deletions native/sorted_set_nif/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions native/sorted_set_nif/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ crate-type = ["cdylib"]
rustler = "0.18.0"
rustler_codegen = "0.18.0"
lazy_static = "1.0"
failure = "0.1.5"


[profile.release]
lto = true
codegen-units = 1
60 changes: 27 additions & 33 deletions native/sorted_set_nif/src/bucket.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::cmp::Ordering;
use std::ptr;
use supported_term::SupportedTerm;
use AddResult;
use AddResult::{Added, Duplicate};
use Error;

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Default)]
pub struct Bucket {
pub data: Vec<SupportedTerm>,
}
Expand All @@ -14,12 +13,12 @@ impl Bucket {
self.data.len()
}

pub fn add(&mut self, item: SupportedTerm) -> AddResult {
pub fn add(&mut self, item: SupportedTerm) -> Result<usize, Error> {
match self.data.binary_search(&item) {
Ok(idx) => Duplicate(idx),
Ok(idx) => Err(Error::Duplicate(idx)),
Err(idx) => {
self.data.insert(idx, item);
Added(idx)
Ok(idx)
}
}
}
Expand All @@ -36,11 +35,7 @@ impl Bucket {
self.data.set_len(at);
other.set_len(other_len);

ptr::copy_nonoverlapping(
self.data.as_ptr().offset(at as isize),
other.as_mut_ptr(),
other.len(),
);
ptr::copy_nonoverlapping(self.data.as_ptr().add(at), other.as_mut_ptr(), other.len());
}

Bucket { data: other }
Expand Down Expand Up @@ -72,11 +67,10 @@ mod tests {
use bucket::Bucket;
use std::cmp::Ordering;
use supported_term::SupportedTerm;
use AddResult;

#[test]
fn test_item_compare_empty_bucket() {
let bucket = Bucket { data: Vec::new() };
let bucket = Bucket::default();

let item = SupportedTerm::Integer(5);

Expand All @@ -85,9 +79,9 @@ mod tests {

#[test]
fn test_item_compare_when_less_than_first_item() {
let mut bucket = Bucket { data: Vec::new() };
let mut bucket = Bucket::default();
let first_item = SupportedTerm::Integer(5);
assert_eq!(bucket.add(first_item), AddResult::Added(0));
assert_eq!(bucket.add(first_item).unwrap(), 0);

let item = SupportedTerm::Integer(3);

Expand All @@ -96,21 +90,21 @@ mod tests {

#[test]
fn test_item_compare_when_equal_to_first_item() {
let mut bucket = Bucket { data: Vec::new() };
let mut bucket = Bucket::default();
let first_item = SupportedTerm::Integer(5);
let item = first_item.clone();

assert_eq!(bucket.add(first_item), AddResult::Added(0));
assert_eq!(bucket.add(first_item).unwrap(), 0);
assert_eq!(bucket.item_compare(&item), Ordering::Equal);
}

#[test]
fn test_item_compare_when_greater_than_last_item() {
let mut bucket = Bucket { data: Vec::new() };
let mut bucket = Bucket::default();

assert_eq!(bucket.add(SupportedTerm::Integer(1)), AddResult::Added(0));
assert_eq!(bucket.add(SupportedTerm::Integer(2)), AddResult::Added(1));
assert_eq!(bucket.add(SupportedTerm::Integer(3)), AddResult::Added(2));
assert_eq!(bucket.add(SupportedTerm::Integer(1)).unwrap(), 0);
assert_eq!(bucket.add(SupportedTerm::Integer(2)).unwrap(), 1);
assert_eq!(bucket.add(SupportedTerm::Integer(3)).unwrap(), 2);

let item = SupportedTerm::Integer(5);

Expand All @@ -119,11 +113,11 @@ mod tests {

#[test]
fn test_item_compare_when_equal_to_last_item() {
let mut bucket = Bucket { data: Vec::new() };
let mut bucket = Bucket::default();

assert_eq!(bucket.add(SupportedTerm::Integer(1)), AddResult::Added(0));
assert_eq!(bucket.add(SupportedTerm::Integer(2)), AddResult::Added(1));
assert_eq!(bucket.add(SupportedTerm::Integer(3)), AddResult::Added(2));
assert_eq!(bucket.add(SupportedTerm::Integer(1)).unwrap(), 0);
assert_eq!(bucket.add(SupportedTerm::Integer(2)).unwrap(), 1);
assert_eq!(bucket.add(SupportedTerm::Integer(3)).unwrap(), 2);

let item = SupportedTerm::Integer(3);

Expand All @@ -132,11 +126,11 @@ mod tests {

#[test]
fn test_item_between_first_and_last_duplicate() {
let mut bucket = Bucket { data: Vec::new() };
let mut bucket = Bucket::default();

assert_eq!(bucket.add(SupportedTerm::Integer(1)), AddResult::Added(0));
assert_eq!(bucket.add(SupportedTerm::Integer(2)), AddResult::Added(1));
assert_eq!(bucket.add(SupportedTerm::Integer(3)), AddResult::Added(2));
assert_eq!(bucket.add(SupportedTerm::Integer(1)).unwrap(), 0);
assert_eq!(bucket.add(SupportedTerm::Integer(2)).unwrap(), 1);
assert_eq!(bucket.add(SupportedTerm::Integer(3)).unwrap(), 2);

let item = SupportedTerm::Integer(1);

Expand All @@ -145,11 +139,11 @@ mod tests {

#[test]
fn test_item_between_first_and_last_unique() {
let mut bucket = Bucket { data: Vec::new() };
let mut bucket = Bucket::default();

assert_eq!(bucket.add(SupportedTerm::Integer(2)), AddResult::Added(0));
assert_eq!(bucket.add(SupportedTerm::Integer(4)), AddResult::Added(1));
assert_eq!(bucket.add(SupportedTerm::Integer(6)), AddResult::Added(2));
assert_eq!(bucket.add(SupportedTerm::Integer(2)).unwrap(), 0);
assert_eq!(bucket.add(SupportedTerm::Integer(4)).unwrap(), 1);
assert_eq!(bucket.add(SupportedTerm::Integer(6)).unwrap(), 2);

let item = SupportedTerm::Integer(3);

Expand Down
25 changes: 20 additions & 5 deletions native/sorted_set_nif/src/configuration.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use std::num::NonZeroUsize;

#[derive(Debug)]
pub struct Configuration {
/// Internally we maintain buckets to reduce the cost of inserts. This configures
/// how large a bucket can grow to before it is forced to be split.
///
/// Default: 200
pub max_bucket_size: usize,
pub max_bucket_size: NonZeroUsize,

/// Similarly to a bucket, the SortedSet maintains a Vec of buckets. This lets you
/// preallocate to avoid resizing the Vector if you can anticipate the size.
Expand All @@ -15,9 +17,22 @@ pub struct Configuration {

impl Default for Configuration {
fn default() -> Self {
return Self {
max_bucket_size: 200,
initial_set_capacity: 0,
};
Self::new(200, 0)
}
}

impl Configuration {
pub fn new(max_bucket_size: usize, initial_set_capacity: usize) -> Self {
Self {
max_bucket_size: NonZeroUsize::new(max_bucket_size)
.expect("max_bucket_size must be greater than 0"),
initial_set_capacity,
}
}

// Currently used only in tests
#[allow(dead_code)]
pub fn with_max_bucket_size(max_bucket_size: usize) -> Self {
Self::new(max_bucket_size, 0)
}
}
Loading