Skip to content

Commit

Permalink
Bit packing representation of ballots.
Browse files Browse the repository at this point in the history
  • Loading branch information
gendx committed Jul 7, 2024
1 parent 19abd3b commit ebc464a
Show file tree
Hide file tree
Showing 5 changed files with 701 additions and 133 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#![forbid(missing_docs, unsafe_code)]
#![cfg_attr(test, feature(test, cfg_overflow_checks, iter_array_chunks))]
#![feature(array_windows)]

#[cfg(test)]
extern crate test;
Expand Down
66 changes: 32 additions & 34 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,10 @@ mod test {
(Info, "Candidates (by nickname): [\"apple\", \"banana\", \"cherry\", \"date\", \"eggplant\"]"),
(Info, "Number of ballots: 171"),
(Info, "Election title: Vegetable contest"),
(Debug, "Allocations of 32 bytes: 8 => 256 bytes"),
(Debug, "Allocations of 192 bytes: 1 => 192 bytes"),
(Debug, "Ballots use 448 bytes in 9 allocations"),
(Debug, "Each ballot uses 112 bytes in 2.25 allocations"),
(Debug, "Allocations of 16 bytes: 1 => 16 bytes"),
(Debug, "Allocations of 32 bytes: 1 => 32 bytes"),
(Debug, "Ballots use 48 bytes in 2 allocations"),
(Debug, "Each ballot uses 12 bytes in 0.5 allocations"),
]);
}

Expand Down Expand Up @@ -403,10 +403,10 @@ mod test {
(Info, "Candidates (by nickname): [\"apple\", \"banana\", \"cherry\", \"date\", \"eggplant\"]"),
(Info, "Number of ballots: 171"),
(Info, "Election title: Vegetable contest"),
(Debug, "Allocations of 32 bytes: 8 => 256 bytes"),
(Debug, "Allocations of 192 bytes: 1 => 192 bytes"),
(Debug, "Ballots use 448 bytes in 9 allocations"),
(Debug, "Each ballot uses 112 bytes in 2.25 allocations"),
(Debug, "Allocations of 16 bytes: 1 => 16 bytes"),
(Debug, "Allocations of 32 bytes: 1 => 32 bytes"),
(Debug, "Ballots use 48 bytes in 2 allocations"),
(Debug, "Each ballot uses 12 bytes in 0.5 allocations"),
]);
}

Expand Down Expand Up @@ -461,10 +461,10 @@ mod test {
),
(Info, "Number of ballots: 1"),
(Info, "Election title: Vegetable contest"),
(Debug, "Allocations of 32 bytes: 2 => 64 bytes"),
(Debug, "Allocations of 192 bytes: 1 => 192 bytes"),
(Debug, "Ballots use 256 bytes in 3 allocations"),
(Debug, "Each ballot uses 256 bytes in 3 allocations"),
(Debug, "Allocations of 8 bytes: 1 => 8 bytes"),
(Debug, "Allocations of 32 bytes: 1 => 32 bytes"),
(Debug, "Ballots use 40 bytes in 2 allocations"),
(Debug, "Each ballot uses 40 bytes in 2 allocations"),
]);
}

Expand Down Expand Up @@ -527,11 +527,10 @@ mod test {
(Info, "Candidates (by nickname): [\"apple\", \"banana\", \"cherry\", \"date\", \"eggplant\"]"),
(Info, "Number of ballots: 188"),
(Info, "Election title: Vegetable contest"),
(Debug, "Allocations of 0 bytes: 2 => 0 bytes"),
(Debug, "Allocations of 32 bytes: 8 => 256 bytes"),
(Debug, "Allocations of 384 bytes: 1 => 384 bytes"),
(Debug, "Ballots use 640 bytes in 11 allocations"),
(Debug, "Each ballot uses 128 bytes in 2.2 allocations"),
(Debug, "Allocations of 16 bytes: 1 => 16 bytes"),
(Debug, "Allocations of 64 bytes: 1 => 64 bytes"),
(Debug, "Ballots use 80 bytes in 2 allocations"),
(Debug, "Each ballot uses 16 bytes in 0.4 allocations"),
]);
}

Expand Down Expand Up @@ -594,11 +593,10 @@ mod test {
(Info, "Candidates (by nickname): [\"apple\", \"banana\", \"cherry\", \"date\", \"eggplant\"]"),
(Info, "Number of ballots: 188"),
(Info, "Election title: Vegetable contest"),
(Debug, "Allocations of 0 bytes: 4 => 0 bytes"),
(Debug, "Allocations of 32 bytes: 6 => 192 bytes"),
(Debug, "Allocations of 384 bytes: 1 => 384 bytes"),
(Debug, "Ballots use 576 bytes in 11 allocations"),
(Debug, "Each ballot uses 115.2 bytes in 2.2 allocations"),
(Debug, "Allocations of 16 bytes: 1 => 16 bytes"),
(Debug, "Allocations of 64 bytes: 1 => 64 bytes"),
(Debug, "Ballots use 80 bytes in 2 allocations"),
(Debug, "Each ballot uses 16 bytes in 0.4 allocations"),
]);
}

Expand Down Expand Up @@ -661,10 +659,10 @@ mod test {
(Warn, "Removing ballot that is empty or contains only withdrawn candidates: 17 0"),
(Info, "Number of ballots: 171"),
(Info, "Election title: Vegetable contest"),
(Debug, "Allocations of 32 bytes: 8 => 256 bytes"),
(Debug, "Allocations of 192 bytes: 1 => 192 bytes"),
(Debug, "Ballots use 448 bytes in 9 allocations"),
(Debug, "Each ballot uses 112 bytes in 2.25 allocations"),
(Debug, "Allocations of 16 bytes: 1 => 16 bytes"),
(Debug, "Allocations of 32 bytes: 1 => 32 bytes"),
(Debug, "Ballots use 48 bytes in 2 allocations"),
(Debug, "Each ballot uses 12 bytes in 0.5 allocations"),
]);
}

Expand Down Expand Up @@ -727,10 +725,10 @@ mod test {
(Warn, "Removing ballot that is empty or contains only withdrawn candidates: 17 0"),
(Info, "Number of ballots: 129"),
(Info, "Election title: Vegetable contest"),
(Debug, "Allocations of 32 bytes: 6 => 192 bytes"),
(Debug, "Allocations of 192 bytes: 1 => 192 bytes"),
(Debug, "Ballots use 384 bytes in 7 allocations"),
(Debug, "Each ballot uses 128 bytes in 2.3333333333333335 allocations"),
(Debug, "Allocations of 16 bytes: 1 => 16 bytes"),
(Debug, "Allocations of 32 bytes: 1 => 32 bytes"),
(Debug, "Ballots use 48 bytes in 2 allocations"),
(Debug, "Each ballot uses 16 bytes in 0.6666666666666666 allocations"),
]);
}

Expand Down Expand Up @@ -772,10 +770,10 @@ mod test {
(Info, "Candidates (by nickname): [\"apple\", \"banana\"]"),
(Info, "Number of ballots: 1"),
(Info, "Election title: Vegetable contest"),
(Debug, "Allocations of 32 bytes: 2 => 64 bytes"),
(Debug, "Allocations of 192 bytes: 1 => 192 bytes"),
(Debug, "Ballots use 256 bytes in 3 allocations"),
(Debug, "Each ballot uses 256 bytes in 3 allocations"),
(Debug, "Allocations of 8 bytes: 1 => 8 bytes"),
(Debug, "Allocations of 32 bytes: 1 => 32 bytes"),
(Debug, "Ballots use 40 bytes in 2 allocations"),
(Debug, "Each ballot uses 40 bytes in 2 allocations"),
]);
}

Expand Down
49 changes: 3 additions & 46 deletions src/types/ballot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,42 +52,7 @@ pub trait BallotView: Debug {
fn order_at(&self, i: usize) -> &[impl Into<usize> + Copy + '_];
}

/// A cursor over a slice of ballots.
pub struct BallotSliceCursor<'a> {
/// Underlying slice of ballots.
pub slice: &'a [Ballot],
/// Index of the current ballot.
pub index: usize,
}

impl<'a> IntoParallelIterator for BallotSliceCursor<'a> {
type Item = &'a Ballot;
type Iter = <&'a [Ballot] as IntoParallelIterator>::Iter;

fn into_par_iter(self) -> Self::Iter {
self.slice.into_par_iter()
}
}

impl<'a> Iterator for BallotSliceCursor<'a> {
type Item = &'a Ballot;

fn next(&mut self) -> Option<Self::Item> {
let result = self.slice.get(self.index);
self.index += 1;
result
}
}

impl<'a> BallotCursor for BallotSliceCursor<'a> {
type B = &'a Ballot;
type I = <&'a [Ballot] as IntoParallelIterator>::Iter;

fn at(&self, index: usize) -> Option<Self::B> {
self.slice.get(index)
}
}

#[cfg(test)]
impl BallotView for &Ballot {
fn count(&self) -> usize {
(*self).count()
Expand Down Expand Up @@ -180,12 +145,14 @@ impl<O: Order + Clone> BallotImpl<O> {
}

/// Returns the number of successive ranks in the ballot order.
#[cfg(test)]
#[inline(always)]
pub(crate) fn order_len(&self) -> usize {
self.order.len()
}

/// Returns the rank at the given index in the ballot order.
#[cfg(test)]
#[inline(always)]
pub(crate) fn order_at(&self, i: usize) -> &[impl Into<usize> + Copy + '_] {
self.order.at(i)
Expand Down Expand Up @@ -213,16 +180,6 @@ impl<O: Order + Clone> BallotImpl<O> {
fn candidates(&self) -> impl Iterator<Item = &(impl Into<usize> + Copy + '_)> + '_ {
self.order.candidates()
}

#[inline(always)]
pub(super) fn count_allocations(&self, allocations: &mut BTreeMap<usize, usize>) {
self.order.count_allocations(allocations)
}

#[inline(always)]
pub(super) fn allocated_addresses(&self) -> impl Iterator<Item = usize> + '_ {
self.order.allocated_addresses()
}
}

/// Ordering of candidates in a ballot.
Expand Down
Loading

0 comments on commit ebc464a

Please sign in to comment.