Skip to content

Commit

Permalink
Merge pull request #33 from spl/rm-clone-trait-bound
Browse files Browse the repository at this point in the history
Minimize the Clone trait bound in src/structure/*
  • Loading branch information
matko committed Feb 19, 2020
2 parents 0fcaa9c + 0f398b0 commit 077f2d9
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 44 deletions.
20 changes: 13 additions & 7 deletions src/structure/adjacencylist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ use super::logarray::*;
use crate::storage::*;

#[derive(Clone)]
pub struct AdjacencyList<M: AsRef<[u8]> + Clone> {
pub struct AdjacencyList<M: AsRef<[u8]>> {
pub nums: LogArray<M>,
pub bits: BitIndex<M>,
}

impl<M: AsRef<[u8]> + Clone> AdjacencyList<M> {
impl<M: AsRef<[u8]>> AdjacencyList<M> {
pub fn from_parts(nums: LogArray<M>, bits: BitIndex<M>) -> AdjacencyList<M> {
debug_assert_eq!(nums.len(), bits.len());
AdjacencyList { nums, bits }
Expand Down Expand Up @@ -74,7 +74,10 @@ impl<M: AsRef<[u8]> + Clone> AdjacencyList<M> {
(left, right)
}

pub fn get(&self, index: u64) -> LogArraySlice<M> {
pub fn get(&self, index: u64) -> LogArraySlice<M>
where
M: Clone,
{
if index < 1 {
panic!("minimum index has to be 1");
}
Expand All @@ -86,7 +89,10 @@ impl<M: AsRef<[u8]> + Clone> AdjacencyList<M> {
self.nums.slice(start as usize, length as usize)
}

pub fn iter(&self) -> AdjacencyListIterator<M> {
pub fn iter(&self) -> AdjacencyListIterator<M>
where
M: Clone,
{
AdjacencyListIterator {
pos: 0,
left: 1,
Expand All @@ -104,14 +110,14 @@ impl<M: AsRef<[u8]> + Clone> AdjacencyList<M> {
}
}

pub struct AdjacencyListIterator<M: AsRef<[u8]> + Clone> {
pub struct AdjacencyListIterator<M: AsRef<[u8]>> {
pos: usize,
left: u64,
bits: BitIndex<M>,
nums: LogArray<M>,
}

impl<M: AsRef<[u8]> + Clone> Iterator for AdjacencyListIterator<M> {
impl<M: AsRef<[u8]>> Iterator for AdjacencyListIterator<M> {
type Item = (u64, u64);

fn next(&mut self) -> Option<(u64, u64)> {
Expand Down Expand Up @@ -175,7 +181,7 @@ impl<S: Stream<Item = bool, Error = std::io::Error>> Stream for AdjacencyBitCoun
}
}

pub fn adjacency_list_stream_pairs<F: FileLoad + Clone>(
pub fn adjacency_list_stream_pairs<F: FileLoad>(
bits_file: F,
nums_file: F,
) -> impl Stream<Item = (u64, u64), Error = std::io::Error> {
Expand Down
8 changes: 3 additions & 5 deletions src/structure/bitarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use tokio::codec::{Decoder, FramedRead};
use tokio::prelude::*;

#[derive(Clone)]
pub struct BitArray<M: AsRef<[u8]> + Clone> {
pub struct BitArray<M: AsRef<[u8]>> {
bits: M,
/// how many bits are being used in the last 8 bytes?
count: u64,
}

impl<M: AsRef<[u8]> + Clone> BitArray<M> {
impl<M: AsRef<[u8]>> BitArray<M> {
pub fn from_bits(bits: M) -> BitArray<M> {
if bits.as_ref().len() < 8 || bits.as_ref().len() % 8 != 0 {
panic!("unexpected bitarray length");
Expand Down Expand Up @@ -182,9 +182,7 @@ fn block_bits(block: u64) -> Vec<bool> {
result
}

pub fn bitarray_stream_bits<F: FileLoad + Clone>(
f: F,
) -> impl Stream<Item = bool, Error = std::io::Error> {
pub fn bitarray_stream_bits<F: FileLoad>(f: F) -> impl Stream<Item = bool, Error = std::io::Error> {
bitarray_count_from_file(f.clone())
.into_stream()
.map(move |count| {
Expand Down
4 changes: 2 additions & 2 deletions src/structure/bitindex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ const SBLOCK_SIZE: usize = 52;

/// A bitarray with an index, supporting rank and select queries.
#[derive(Clone)]
pub struct BitIndex<M: AsRef<[u8]> + Clone> {
pub struct BitIndex<M: AsRef<[u8]>> {
array: BitArray<M>,
blocks: LogArray<M>,
sblocks: LogArray<M>,
}

impl<M: AsRef<[u8]> + Clone> BitIndex<M> {
impl<M: AsRef<[u8]>> BitIndex<M> {
pub fn from_maps(bitarray_map: M, blocks_map: M, sblocks_map: M) -> BitIndex<M> {
let bitarray = BitArray::from_bits(bitarray_map);
let blocks_logarray = LogArray::parse(blocks_map).unwrap();
Expand Down
25 changes: 14 additions & 11 deletions src/structure/logarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::cmp::Ordering;
use tokio::codec::{Decoder, FramedRead};

#[derive(Clone)]
pub struct LogArray<M: AsRef<[u8]> + Clone> {
pub struct LogArray<M: AsRef<[u8]>> {
len: u32,
width: u8,
len_bytes: usize,
Expand All @@ -25,13 +25,13 @@ pub enum LogArrayError {
InvalidCoding,
}

pub struct LogArrayIterator<'a, M: AsRef<[u8]> + Clone> {
pub struct LogArrayIterator<'a, M: AsRef<[u8]>> {
logarray: &'a LogArray<M>,
pos: usize,
end: usize,
}

impl<'a, M: AsRef<[u8]> + Clone> Iterator for LogArrayIterator<'a, M> {
impl<'a, M: AsRef<[u8]>> Iterator for LogArrayIterator<'a, M> {
type Item = u64;
fn next(&mut self) -> Option<u64> {
if self.pos == self.end {
Expand All @@ -45,13 +45,13 @@ impl<'a, M: AsRef<[u8]> + Clone> Iterator for LogArrayIterator<'a, M> {
}
}

pub struct OwnedLogArrayIterator<M: AsRef<[u8]> + Clone> {
pub struct OwnedLogArrayIterator<M: AsRef<[u8]>> {
logarray: LogArray<M>,
pos: usize,
end: usize,
}

impl<M: AsRef<[u8]> + Clone> Iterator for OwnedLogArrayIterator<M> {
impl<M: AsRef<[u8]>> Iterator for OwnedLogArrayIterator<M> {
type Item = u64;
fn next(&mut self) -> Option<u64> {
if self.pos == self.end {
Expand All @@ -65,7 +65,7 @@ impl<M: AsRef<[u8]> + Clone> Iterator for OwnedLogArrayIterator<M> {
}
}

impl<M: AsRef<[u8]> + Clone> LogArray<M> {
impl<M: AsRef<[u8]>> LogArray<M> {
pub fn parse(data: M) -> Result<LogArray<M>, LogArrayError> {
let len = BigEndian::read_u32(&data.as_ref()[data.as_ref().len() - 8..]);
let width = data.as_ref()[data.as_ref().len() - 4];
Expand Down Expand Up @@ -162,7 +162,10 @@ impl<M: AsRef<[u8]> + Clone> LogArray<M> {
}
}

pub fn slice(&self, offset: usize, length: usize) -> LogArraySlice<M> {
pub fn slice(&self, offset: usize, length: usize) -> LogArraySlice<M>
where
M: Clone,
{
if self.len() < offset + length {
panic!("slice out of bounds");
}
Expand All @@ -175,13 +178,13 @@ impl<M: AsRef<[u8]> + Clone> LogArray<M> {
}

#[derive(Clone)]
pub struct LogArraySlice<M: AsRef<[u8]> + Clone> {
pub struct LogArraySlice<M: AsRef<[u8]>> {
original: LogArray<M>,
offset: usize,
length: usize,
}

impl<M: AsRef<[u8]> + Clone> LogArraySlice<M> {
impl<M: AsRef<[u8]>> LogArraySlice<M> {
pub fn len(&self) -> usize {
self.length
}
Expand Down Expand Up @@ -405,9 +408,9 @@ pub fn logarray_stream_entries<F: FileLoad>(
}

#[derive(Clone)]
pub struct MonotonicLogArray<M: AsRef<[u8]> + Clone>(LogArray<M>);
pub struct MonotonicLogArray<M: AsRef<[u8]>>(LogArray<M>);

impl<M: AsRef<[u8]> + Clone> MonotonicLogArray<M> {
impl<M: AsRef<[u8]>> MonotonicLogArray<M> {
pub fn from_logarray(logarray: LogArray<M>) -> MonotonicLogArray<M> {
if cfg!(debug_assertions) {
let mut iter = logarray.iter();
Expand Down
20 changes: 10 additions & 10 deletions src/structure/pfc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,21 @@ impl Into<std::io::Error> for PfcError {
}

#[derive(Clone)]
pub struct PfcBlock<M: AsRef<[u8]> + Clone> {
pub struct PfcBlock<M: AsRef<[u8]>> {
encoded_strings: M,
n_strings: usize,
}

const BLOCK_SIZE: usize = 8;

pub struct PfcBlockIterator<'a, M: AsRef<[u8]> + Clone> {
pub struct PfcBlockIterator<'a, M: AsRef<[u8]>> {
block: &'a PfcBlock<M>,
count: usize,
pos: usize,
string: Vec<u8>,
}

impl<'a, M: AsRef<[u8]> + Clone> Iterator for PfcBlockIterator<'a, M> {
impl<'a, M: AsRef<[u8]>> Iterator for PfcBlockIterator<'a, M> {
type Item = String;

fn next(&mut self) -> Option<String> {
Expand Down Expand Up @@ -90,14 +90,14 @@ impl<'a, M: AsRef<[u8]> + Clone> Iterator for PfcBlockIterator<'a, M> {
}

// the owned version is pretty much equivalent. There should be a way to make this one implementation with generics but I haven't figured out how!
pub struct OwnedPfcBlockIterator<M: AsRef<[u8]> + Clone> {
pub struct OwnedPfcBlockIterator<M: AsRef<[u8]>> {
block: PfcBlock<M>,
count: usize,
pos: usize,
string: Vec<u8>,
}

impl<M: AsRef<[u8]> + Clone> Iterator for OwnedPfcBlockIterator<M> {
impl<M: AsRef<[u8]>> Iterator for OwnedPfcBlockIterator<M> {
type Item = String;

fn next(&mut self) -> Option<String> {
Expand Down Expand Up @@ -135,7 +135,7 @@ impl<M: AsRef<[u8]> + Clone> Iterator for OwnedPfcBlockIterator<M> {
}
}

impl<M: AsRef<[u8]> + Clone> PfcBlock<M> {
impl<M: AsRef<[u8]>> PfcBlock<M> {
pub fn parse(data: M) -> Result<PfcBlock<M>, PfcError> {
Ok(PfcBlock {
encoded_strings: data,
Expand Down Expand Up @@ -196,19 +196,19 @@ impl<M: AsRef<[u8]> + Clone> PfcBlock<M> {
}

#[derive(Clone)]
pub struct PfcDict<M: AsRef<[u8]> + Clone> {
pub struct PfcDict<M: AsRef<[u8]>> {
n_strings: u64,
block_offsets: LogArray<M>,
blocks: M,
}

pub struct PfcDictIterator<'a, M: AsRef<[u8]> + Clone> {
pub struct PfcDictIterator<'a, M: AsRef<[u8]>> {
dict: &'a PfcDict<M>,
block_index: usize,
block: Option<OwnedPfcBlockIterator<&'a [u8]>>,
}

impl<'a, M: AsRef<[u8]> + Clone> Iterator for PfcDictIterator<'a, M> {
impl<'a, M: AsRef<[u8]>> Iterator for PfcDictIterator<'a, M> {
type Item = String;

fn next(&mut self) -> Option<String> {
Expand Down Expand Up @@ -250,7 +250,7 @@ impl<'a, M: AsRef<[u8]> + Clone> Iterator for PfcDictIterator<'a, M> {
}
}

impl<M: AsRef<[u8]> + Clone> PfcDict<M> {
impl<M: AsRef<[u8]>> PfcDict<M> {
pub fn parse(blocks: M, offsets: M) -> Result<PfcDict<M>, PfcError> {
let n_strings = BigEndian::read_u64(&blocks.as_ref()[blocks.as_ref().len() - 8..]);

Expand Down
30 changes: 21 additions & 9 deletions src/structure/wavelettree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use tokio::prelude::*;
/// rounded up to make it an integer. Since we're encoding u64 values,
/// the number of layers can never be larger than 64.
#[derive(Clone)]
pub struct WaveletTree<M: AsRef<[u8]> + Clone> {
pub struct WaveletTree<M: AsRef<[u8]>> {
bits: BitIndex<M>,
num_layers: u8,
}
Expand All @@ -25,14 +25,14 @@ pub struct WaveletTree<M: AsRef<[u8]> + Clone> {
/// positions out of a wavelet tree, allowing for quick iteration over
/// all positions for a given entry.
#[derive(Clone)]
pub struct WaveletLookup<M: AsRef<[u8]> + Clone> {
pub struct WaveletLookup<M: AsRef<[u8]>> {
/// the entry this lookup was created for.
pub entry: u64,
tree: WaveletTree<M>,
slices: Vec<(bool, u64, u64)>,
}

impl<M: AsRef<[u8]> + Clone> WaveletLookup<M> {
impl<M: AsRef<[u8]>> WaveletLookup<M> {
/// Returns the amount of positions found in this lookup.
pub fn len(&self) -> usize {
let (b, start, end) = *self.slices.last().unwrap();
Expand Down Expand Up @@ -75,13 +75,16 @@ impl<M: AsRef<[u8]> + Clone> WaveletLookup<M> {
}

/// Returns an Iterator over all positions for the entry of this lookup
pub fn iter(&self) -> impl Iterator<Item = u64> {
pub fn iter(&self) -> impl Iterator<Item = u64>
where
M: Clone,
{
let cloned = self.clone();
(0..self.len()).map(move |i| cloned.entry(i))
}
}

impl<M: AsRef<[u8]> + Clone> WaveletTree<M> {
impl<M: AsRef<[u8]>> WaveletTree<M> {
/// Construct a wavelet tree from a bitindex and a layer count.
pub fn from_parts(bits: BitIndex<M>, num_layers: u8) -> WaveletTree<M> {
if num_layers != 0 && bits.len() % num_layers as usize != 0 {
Expand All @@ -106,7 +109,10 @@ impl<M: AsRef<[u8]> + Clone> WaveletTree<M> {
}

/// Decode the wavelet tree to the original u64 sequence. This returns an iterator.
pub fn decode(&self) -> impl Iterator<Item = u64> {
pub fn decode(&self) -> impl Iterator<Item = u64>
where
M: Clone,
{
let owned = self.clone();
(0..self.len()).map(move |i| owned.decode_one(i))
}
Expand Down Expand Up @@ -153,7 +159,10 @@ impl<M: AsRef<[u8]> + Clone> WaveletTree<M> {
}

/// Lookup the given entry. This returns a `WaveletLookup` which can then be used to find all positions.
pub fn lookup(&self, entry: u64) -> Option<WaveletLookup<M>> {
pub fn lookup(&self, entry: u64) -> Option<WaveletLookup<M>>
where
M: Clone,
{
let width = self.len() as u64;
let mut slices = Vec::with_capacity(self.num_layers as usize);
let mut alphabet_start = 0;
Expand Down Expand Up @@ -191,7 +200,10 @@ impl<M: AsRef<[u8]> + Clone> WaveletTree<M> {
}

/// Lookup the given entry. This returns a single result, even if there's multiple.
pub fn lookup_one(&self, entry: u64) -> Option<u64> {
pub fn lookup_one(&self, entry: u64) -> Option<u64>
where
M: Clone,
{
self.lookup(entry).map(|l| l.entry(0))
}
}
Expand Down Expand Up @@ -264,7 +276,7 @@ pub fn build_wavelet_tree_from_stream<

/// Build a wavelet tree from a file storing a logarray.
pub fn build_wavelet_tree_from_logarray<
FLoad: 'static + FileLoad + Clone,
FLoad: 'static + FileLoad,
F: 'static + FileLoad + FileStore,
>(
source: FLoad,
Expand Down

0 comments on commit 077f2d9

Please sign in to comment.