use trait to simplify and consolidate cumulative code (#17852)
This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							32742df1b4
						
					
				
				
					commit
					2dc6969858
				
			@@ -108,6 +108,22 @@ impl CumulativeOffset {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait ExtractSliceFromRawData<'b, T: 'b> {
 | 
			
		||||
    fn extract<'a>(&'b self, offset: &'a CumulativeOffset, start: usize) -> &'b [T];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'b, T: 'b> ExtractSliceFromRawData<'b, T> for Vec<Vec<T>> {
 | 
			
		||||
    fn extract<'a>(&'b self, offset: &'a CumulativeOffset, start: usize) -> &'b [T] {
 | 
			
		||||
        &self[offset.index[0]][start..]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'b, T: 'b> ExtractSliceFromRawData<'b, T> for Vec<Vec<Vec<T>>> {
 | 
			
		||||
    fn extract<'a>(&'b self, offset: &'a CumulativeOffset, start: usize) -> &'b [T] {
 | 
			
		||||
        &self[offset.index[0]][offset.index[1]][start..]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Allow retrieving &[start..end] from a logical src: Vec<T>, where src is really Vec<Vec<T>> (or later Vec<Vec<Vec<T>>>)
 | 
			
		||||
// This model prevents callers from having to flatten which saves both working memory and time.
 | 
			
		||||
#[derive(Default, Debug)]
 | 
			
		||||
@@ -163,32 +179,28 @@ impl CumulativeOffsets {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn find(&self, start: usize) -> (usize, &CumulativeOffset) {
 | 
			
		||||
    fn find_index(&self, start: usize) -> usize {
 | 
			
		||||
        assert!(!self.cumulative_offsets.is_empty());
 | 
			
		||||
        let index = match self.cumulative_offsets[..]
 | 
			
		||||
            .binary_search_by(|index| index.start_offset.cmp(&start))
 | 
			
		||||
        {
 | 
			
		||||
        match self.cumulative_offsets[..].binary_search_by(|index| index.start_offset.cmp(&start)) {
 | 
			
		||||
            Ok(index) => index,
 | 
			
		||||
            Err(index) => index - 1, // we would insert at index so we are before the item at index
 | 
			
		||||
        };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn find(&self, start: usize) -> (usize, &CumulativeOffset) {
 | 
			
		||||
        let index = self.find_index(start);
 | 
			
		||||
        let index = &self.cumulative_offsets[index];
 | 
			
		||||
        let start = start - index.start_offset;
 | 
			
		||||
        (start, index)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // return the biggest slice possible that starts at 'start'
 | 
			
		||||
    pub fn get_slice<'a, T>(&self, raw: &'a [Vec<T>], start: usize) -> &'a [T] {
 | 
			
		||||
    pub fn get_slice<'a, 'b, T, U>(&'a self, raw: &'b U, start: usize) -> &'b [T]
 | 
			
		||||
    where
 | 
			
		||||
        U: ExtractSliceFromRawData<'b, T> + 'b,
 | 
			
		||||
    {
 | 
			
		||||
        let (start, index) = self.find(start);
 | 
			
		||||
        const DIMENSION: usize = 0;
 | 
			
		||||
        &raw[index.index[DIMENSION]][start..]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // return the biggest slice possible that starts at 'start'
 | 
			
		||||
    pub fn get_slice_2d<'a, T>(&self, raw: &'a [Vec<Vec<T>>], start: usize) -> &'a [T] {
 | 
			
		||||
        let (start, index) = self.find(start);
 | 
			
		||||
        const DIMENSION_0: usize = 0;
 | 
			
		||||
        const DIMENSION_1: usize = 1;
 | 
			
		||||
        &raw[index.index[DIMENSION_0]][index.index[DIMENSION_1]][start..]
 | 
			
		||||
        raw.extract(index, start)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -751,7 +763,7 @@ impl AccountsHash {
 | 
			
		||||
            // move tail hashes that don't evenly hash into a 1d vector for next time
 | 
			
		||||
            let mut i = hash_total - left_over_hashes;
 | 
			
		||||
            while i < hash_total {
 | 
			
		||||
                let data = cumulative.get_slice_2d(&hashes, i);
 | 
			
		||||
                let data = cumulative.get_slice(&hashes, i);
 | 
			
		||||
                next_pass.remaining_unhashed.extend(data);
 | 
			
		||||
                i += data.len();
 | 
			
		||||
            }
 | 
			
		||||
@@ -769,7 +781,7 @@ impl AccountsHash {
 | 
			
		||||
                hash_total, // note this does not include the ones that didn't divide evenly, unless we're in the last iteration
 | 
			
		||||
                MERKLE_FANOUT,
 | 
			
		||||
                Some(TARGET_FANOUT_LEVEL),
 | 
			
		||||
                |start| cumulative.get_slice_2d(&hashes, start),
 | 
			
		||||
                |start| cumulative.get_slice(&hashes, start),
 | 
			
		||||
                Some(TARGET_FANOUT_LEVEL),
 | 
			
		||||
            )
 | 
			
		||||
            .1;
 | 
			
		||||
@@ -1636,7 +1648,7 @@ pub mod tests {
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_accountsdb_cumulative_offsets2_d() {
 | 
			
		||||
        let input = vec![vec![vec![0, 1], vec![], vec![2, 3, 4], vec![]]];
 | 
			
		||||
        let input: Vec<Vec<Vec<u64>>> = vec![vec![vec![0, 1], vec![], vec![2, 3, 4], vec![]]];
 | 
			
		||||
        let cumulative = CumulativeOffsets::from_raw_2d(&input);
 | 
			
		||||
 | 
			
		||||
        let src: Vec<_> = input
 | 
			
		||||
@@ -1661,7 +1673,7 @@ pub mod tests {
 | 
			
		||||
        assert_eq!(cumulative.cumulative_offsets[1].start_offset, 2);
 | 
			
		||||
 | 
			
		||||
        for start in 0..len {
 | 
			
		||||
            let slice = cumulative.get_slice_2d(&input, start);
 | 
			
		||||
            let slice: &[u64] = cumulative.get_slice(&input, start);
 | 
			
		||||
            let len = slice.len();
 | 
			
		||||
            assert!(len > 0);
 | 
			
		||||
            assert_eq!(&src[start..(start + len)], slice);
 | 
			
		||||
@@ -1690,7 +1702,7 @@ pub mod tests {
 | 
			
		||||
        assert_eq!(cumulative.cumulative_offsets[1].start_offset, 2);
 | 
			
		||||
 | 
			
		||||
        for start in 0..len {
 | 
			
		||||
            let slice = cumulative.get_slice_2d(&input, start);
 | 
			
		||||
            let slice: &[u64] = cumulative.get_slice(&input, start);
 | 
			
		||||
            let len = slice.len();
 | 
			
		||||
            assert!(len > 0);
 | 
			
		||||
            assert_eq!(&src[start..(start + len)], slice);
 | 
			
		||||
@@ -1731,7 +1743,7 @@ pub mod tests {
 | 
			
		||||
        assert_eq!(cumulative.cumulative_offsets[1].start_offset, 2);
 | 
			
		||||
 | 
			
		||||
        for start in 0..len {
 | 
			
		||||
            let slice = cumulative.get_slice_2d(&input, start);
 | 
			
		||||
            let slice: &[u64] = cumulative.get_slice(&input, start);
 | 
			
		||||
            let len = slice.len();
 | 
			
		||||
            assert!(len > 0);
 | 
			
		||||
            assert_eq!(&src[start..(start + len)], slice);
 | 
			
		||||
@@ -1903,7 +1915,7 @@ pub mod tests {
 | 
			
		||||
                ];
 | 
			
		||||
                let offsets = CumulativeOffsets::from_raw_2d(&src);
 | 
			
		||||
 | 
			
		||||
                let get_slice = |start: usize| -> &[Hash] { offsets.get_slice_2d(&src, start) };
 | 
			
		||||
                let get_slice = |start: usize| -> &[Hash] { offsets.get_slice(&src, start) };
 | 
			
		||||
                let result2 = AccountsHash::compute_merkle_root_from_slices(
 | 
			
		||||
                    offsets.total_count,
 | 
			
		||||
                    fanout,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user