Advertisement
Guest User

Untitled

a guest
Jul 26th, 2023
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 13.41 KB | None | 0 0
  1. use std::sync::Arc;
  2.  
  3. #[derive(Debug)]
  4. pub struct Vector1d<T> {
  5.     pub data: Vec<T>,
  6. }
  7.  
  8. impl<T> Vector1d<T> {
  9.     pub fn new() -> Vector1d<T> {
  10.         Vector1d::<T> { data: vec![] }
  11.     }
  12. }
  13.  
  14. #[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
  15. pub struct Vector1dPosition {
  16.     pub index: usize,
  17.     pub offset: usize,
  18. }
  19.  
  20. impl Vector1dPosition {
  21.     pub fn new() -> Vector1dPosition {
  22.         Vector1dPosition {
  23.             index: 0,
  24.             offset: 0,
  25.         }
  26.     }
  27. }
  28.  
  29. pub type MergeCallback<T> =
  30.     fn(&mut [T], &mut [T], &mut Vec<T>) -> (usize, usize);
  31.  
  32. pub trait Merge<T> {
  33.     fn merge(
  34.         &self,
  35.         left: &mut [T],
  36.         right: &mut [T],
  37.         result: &mut Vec<T>,
  38.     ) -> (usize, usize);
  39. }
  40.  
  41. pub type MergeType<T> = Option<Arc<dyn Merge<T> + Sync + Send>>;
  42.  
  43. pub struct Merge1d<T> {
  44.     left: Vec<Vector1d<T>>,
  45.     right: Vec<Vector1d<T>>,
  46. }
  47.  
  48. pub struct MergePair<T> {
  49.     pub left: Vec<Vector1d<T>>,
  50.     pub right: Vec<Vector1d<T>>,
  51. }
  52.  
  53. impl<T> Merge1d<T>
  54. where
  55.     T: PartialOrd + Default + std::fmt::Debug,
  56. {
  57.     pub fn new(left: Vec<Vector1d<T>>, right: Vec<Vector1d<T>>) -> Merge1d<T> {
  58.         assert!(!left.is_empty());
  59.         assert!(!right.is_empty());
  60.  
  61.         Merge1d::<T> { left, right }
  62.     }
  63.  
  64.     // Pulls a pair of vectors to merge from the end. Returns None if
  65.     // no more pairs left to merge.
  66.     pub fn pull_next_merge_pair(
  67.         &mut self,
  68.         min_data_length: usize,
  69.         max_data_length: usize,
  70.     ) -> (MergePair<T>, bool) {
  71.         assert!(!self.left.is_empty() || !self.right.is_empty());
  72.  
  73.         let mut result = MergePair::<T> {
  74.             left: vec![],
  75.             right: vec![],
  76.         };
  77.  
  78.         let (left_start_pos, right_start_pos) =
  79.             self.get_start_positions(min_data_length, max_data_length);
  80.  
  81.         assert!(left_start_pos.is_some() || right_start_pos.is_some());
  82.         if let Some(left_start_pos) = left_start_pos {
  83.             result.left = Self::pull_vectors(&mut self.left, left_start_pos);
  84.         }
  85.  
  86.         if let Some(right_start_pos) = right_start_pos {
  87.             result.right =
  88.                 Self::pull_vectors(&mut self.right, right_start_pos);
  89.         }
  90.  
  91.         let last_pair = self.left.is_empty() && self.right.is_empty();
  92.         (result, last_pair)
  93.     }
  94.  
  95.     fn get_next_buffer<ValueType>(
  96.         buffers: &mut Vec<Vec<ValueType>>,
  97.         vector_size: usize,
  98.     ) -> Vec<ValueType> {
  99.         if let Some(buffer) = buffers.pop() {
  100.             return buffer;
  101.         }
  102.  
  103.         Vec::with_capacity(vector_size)
  104.     }
  105.  
  106.     fn store_buffer<ValueType>(
  107.         buffers: &mut Vec<Vec<ValueType>>,
  108.         mut buffer: Vec<ValueType>,
  109.         vector_size: usize,
  110.     ) {
  111.         if buffers.len() < 4 && buffer.capacity() == vector_size {
  112.             buffer.clear();
  113.             buffers.push(buffer);
  114.         }
  115.     }
  116.  
  117.     pub fn merge(
  118.         mut pair: MergePair<T>,
  119.         buffers: &mut Vec<Vec<T>>,
  120.         vector_size: usize,
  121.         merge_callback: MergeType<T>,
  122.     ) -> Vec<Vector1d<T>> {
  123.         if pair.left.is_empty() {
  124.             return pair.right;
  125.         }
  126.  
  127.         if pair.right.is_empty() {
  128.             return pair.left;
  129.         }
  130.  
  131.         let mut result = vec![];
  132.         let mut current_result = Self::get_next_buffer(buffers, vector_size);
  133.  
  134.         let mut left_pos = Vector1dPosition::new();
  135.         let mut right_pos = Vector1dPosition::new();
  136.         let left_end_pos = Vector1dPosition {
  137.             index: pair.left.len() - 1,
  138.             offset: pair.left[pair.left.len() - 1].data.len(),
  139.         };
  140.         let right_end_pos = Vector1dPosition {
  141.             index: pair.right.len() - 1,
  142.             offset: pair.right[pair.right.len() - 1].data.len(),
  143.         };
  144.  
  145.         assert!(merge_callback.is_some());
  146.         while left_pos < left_end_pos && right_pos < right_end_pos {
  147.             let left_inc;
  148.             let right_inc;
  149.             let merge = merge_callback.as_ref().unwrap();
  150.             (left_inc, right_inc) = merge.merge(
  151.                 &mut pair.left[left_pos.index].data[left_pos.offset..],
  152.                 &mut pair.right[right_pos.index].data[right_pos.offset..],
  153.                 &mut current_result,
  154.             );
  155.  
  156.             left_pos.offset += left_inc;
  157.             right_pos.offset += right_inc;
  158.             assert!(left_pos.offset <= pair.left[left_pos.index].data.len());
  159.             assert!(
  160.                 right_pos.offset <= pair.right[right_pos.index].data.len()
  161.             );
  162.  
  163.             if left_pos.offset == pair.left[left_pos.index].data.len() {
  164.                 Self::store_buffer(
  165.                     buffers,
  166.                     std::mem::take(&mut pair.left[left_pos.index].data),
  167.                     vector_size,
  168.                 );
  169.  
  170.                 left_pos.index += 1;
  171.                 left_pos.offset = 0;
  172.             }
  173.  
  174.             if right_pos.offset == pair.right[right_pos.index].data.len() {
  175.                 Self::store_buffer(
  176.                     buffers,
  177.                     std::mem::take(&mut pair.right[right_pos.index].data),
  178.                     vector_size,
  179.                 );
  180.  
  181.                 right_pos.index += 1;
  182.                 right_pos.offset = 0;
  183.             }
  184.  
  185.             if current_result.capacity() == current_result.len() {
  186.                 result.push(current_result);
  187.                 current_result = Self::get_next_buffer(buffers, vector_size);
  188.             }
  189.         }
  190.  
  191.         while left_pos < left_end_pos {
  192.             current_result.push(std::mem::take(
  193.                 &mut pair.left[left_pos.index].data[left_pos.offset],
  194.             ));
  195.  
  196.             left_pos.offset += 1;
  197.             if left_pos.offset == pair.left[left_pos.index].data.len() {
  198.                 Self::store_buffer(
  199.                     buffers,
  200.                     std::mem::take(&mut pair.left[left_pos.index].data),
  201.                     vector_size,
  202.                 );
  203.  
  204.                 left_pos.index += 1;
  205.                 left_pos.offset = 0;
  206.             }
  207.  
  208.             if current_result.capacity() == current_result.len() {
  209.                 result.push(current_result);
  210.                 current_result = Self::get_next_buffer(buffers, vector_size);
  211.             }
  212.         }
  213.  
  214.         while right_pos < right_end_pos {
  215.             current_result.push(std::mem::take(
  216.                 &mut pair.right[right_pos.index].data[right_pos.offset],
  217.             ));
  218.  
  219.             right_pos.offset += 1;
  220.             if right_pos.offset == pair.right[right_pos.index].data.len() {
  221.                 Self::store_buffer(
  222.                     buffers,
  223.                     std::mem::take(&mut pair.right[right_pos.index].data),
  224.                     vector_size,
  225.                 );
  226.  
  227.                 right_pos.index += 1;
  228.                 right_pos.offset = 0;
  229.             }
  230.  
  231.             if current_result.capacity() == current_result.len() {
  232.                 result.push(current_result);
  233.                 current_result = Self::get_next_buffer(buffers, vector_size);
  234.             }
  235.         }
  236.  
  237.         if !current_result.is_empty() {
  238.             result.push(current_result);
  239.         }
  240.  
  241.         let mut vec1d_result = Vec::with_capacity(result.len());
  242.         for vec in &mut result {
  243.             vec1d_result.push(Vector1d::<T> {
  244.                 data: std::mem::take(vec),
  245.             });
  246.         }
  247.  
  248.         vec1d_result
  249.     }
  250.  
  251.     fn pull_vectors(
  252.         vecs: &mut Vec<Vector1d<T>>,
  253.         start_pos: Vector1dPosition,
  254.     ) -> Vec<Vector1d<T>> {
  255.         assert!(!vecs.is_empty());
  256.         assert!(start_pos.index < vecs.len());
  257.  
  258.         let mut result: Vec<Vector1d<T>> =
  259.             Vec::with_capacity(vecs.len() - start_pos.index);
  260.         for _ in 0..(vecs.len() - start_pos.index) {
  261.             result.push(Vector1d::<T>::new());
  262.         }
  263.  
  264.         let mut index = vecs.len() - 1;
  265.         loop {
  266.             assert!(index == vecs.len() - 1);
  267.             let target_index = index - start_pos.index;
  268.             if target_index == 0 {
  269.                 if start_pos.offset == 0 {
  270.                     result[target_index] = vecs.pop().unwrap();
  271.                 } else {
  272.                     result[target_index].data =
  273.                         vecs[index].data.split_off(start_pos.offset);
  274.                 }
  275.                 break;
  276.             }
  277.  
  278.             result[target_index] = vecs.pop().unwrap();
  279.             index -= 1;
  280.         }
  281.  
  282.         result
  283.     }
  284.  
  285.     fn get_start_positions(
  286.         &self,
  287.         min_data_length: usize,
  288.         max_data_length: usize,
  289.     ) -> (Option<Vector1dPosition>, Option<Vector1dPosition>) {
  290.         if self.left.is_empty() {
  291.             return (None, Some(Vector1dPosition::new()));
  292.         }
  293.  
  294.         if self.right.is_empty() {
  295.             return (Some(Vector1dPosition::new()), None);
  296.         }
  297.  
  298.         let left_pos = Self::find_start_position_from_end_between_distance(
  299.             &self.left,
  300.             min_data_length,
  301.             max_data_length,
  302.         );
  303.  
  304.         let value = &self.left[left_pos.index].data[left_pos.offset];
  305.         let right_pos_from_value =
  306.             Self::find_position_from_value(&self.right, value);
  307.         if let Some(right_pos_from_value) = right_pos_from_value {
  308.             let distance = Self::calculate_distance_to_end_from_position(
  309.                 &self.right,
  310.                 right_pos_from_value.clone(),
  311.             );
  312.  
  313.             if distance <= max_data_length {
  314.                 return (Some(left_pos), Some(right_pos_from_value));
  315.             }
  316.         } else {
  317.             assert!(
  318.                 value < self.right[0].data.first().unwrap()
  319.                     || value
  320.                         > self.right[self.right.len() - 1]
  321.                             .data
  322.                             .last()
  323.                             .unwrap()
  324.             );
  325.  
  326.             return (Some(left_pos), None);
  327.         }
  328.  
  329.         let right_pos = Self::find_start_position_from_end_between_distance(
  330.             &self.right,
  331.             min_data_length,
  332.             max_data_length,
  333.         );
  334.  
  335.         let value = &self.right[right_pos.index].data[right_pos.offset];
  336.         let left_pos = Self::find_position_from_value(&self.left, value);
  337.         (left_pos, Some(right_pos))
  338.     }
  339.  
  340.     // Returns a position given the distance range
  341.     fn find_start_position_from_end_between_distance(
  342.         vecs: &Vec<Vector1d<T>>,
  343.         min_distance: usize,
  344.         max_distance: usize,
  345.     ) -> Vector1dPosition {
  346.         let mut index: usize = vecs.len() - 1;
  347.         let mut distance = 0;
  348.         let mut index_within_range: Option<usize> = None;
  349.         loop {
  350.             let vec_len = vecs[index].data.len();
  351.             if distance + vec_len == max_distance {
  352.                 return Vector1dPosition { index, offset: 0 };
  353.             }
  354.  
  355.             if distance + vec_len > max_distance {
  356.                 // Going to the end of this vector is too much (or
  357.                 // exact right amount).
  358.                 if let Some(index_within_range) = index_within_range {
  359.                     return Vector1dPosition {
  360.                         index: index_within_range,
  361.                         offset: 0,
  362.                     };
  363.                 }
  364.  
  365.                 let distance_needed = max_distance - distance;
  366.                 assert!(distance_needed > 0);
  367.                 assert!(distance_needed <= vec_len);
  368.  
  369.                 // Return the max distance point.
  370.                 return Vector1dPosition {
  371.                     index,
  372.                     offset: vec_len - distance_needed,
  373.                 };
  374.             }
  375.  
  376.             if distance + vec_len >= min_distance {
  377.                 index_within_range = Some(index);
  378.             }
  379.  
  380.             distance += vec_len;
  381.             if index == 0 {
  382.                 break;
  383.             }
  384.  
  385.             index -= 1;
  386.         }
  387.  
  388.         // The beginning of the vector.
  389.         Vector1dPosition::new()
  390.     }
  391.  
  392.     fn calculate_distance_to_end_from_position(
  393.         vecs: &Vec<Vector1d<T>>,
  394.         mut pos: Vector1dPosition,
  395.     ) -> usize {
  396.         let mut distance = 0;
  397.         while pos.index < vecs.len() {
  398.             distance += vecs.len() - pos.offset;
  399.             pos.offset = 0;
  400.             pos.index += 1;
  401.         }
  402.  
  403.         distance
  404.     }
  405.  
  406.     fn find_position_from_value(
  407.         vecs: &Vec<Vector1d<T>>,
  408.         value: &T,
  409.     ) -> Option<Vector1dPosition> {
  410.         let mut index = vecs.len() - 1;
  411.         loop {
  412.             let vec = &vecs[index].data;
  413.             if value > vec.last().unwrap() {
  414.                 // The value falls between the two vectors. Return the
  415.                 // start position from the next one assuming there is
  416.                 // a next one.
  417.                 if index == vecs.len() - 1 {
  418.                     return None;
  419.                 }
  420.  
  421.                 return Some(Vector1dPosition {
  422.                     index: index + 1,
  423.                     offset: 0,
  424.                 });
  425.             }
  426.  
  427.             if value >= &vec[0] {
  428.                 // The value falls within this vector
  429.                 let offset = vec.partition_point(|x| x < value);
  430.                 assert!(offset != vec.len());
  431.  
  432.                 return Some(Vector1dPosition { index, offset });
  433.             }
  434.  
  435.             if index == 0 {
  436.                 break;
  437.             }
  438.  
  439.             index -= 1;
  440.         }
  441.  
  442.         // The start since the value is before the first value.
  443.         Some(Vector1dPosition::new())
  444.     }
  445. }
  446.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement