Advertisement
Guest User

Untitled

a guest
Jan 9th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 8.03 KB | None | 0 0
  1. // this is the benchmark for overlapping tables, 5 to 1995
  2.  
  3. extern crate rand;
  4.  
  5. use rand::Rng;
  6. use std::cmp;
  7.  
  8. struct ESubTable {
  9.     itablePtrs: Vec<Option<u32>>
  10. }
  11.  
  12. // fn collapse_right(x: u32) -> u32 {
  13. //  if x == 0 {
  14. //      return 0
  15. //  }
  16. //  let mut num_shifts = 0;
  17. //  loop {
  18. //      let num_shifts_is_fine = ((x >> num_shifts) << num_shifts) == x;
  19. //      let num_shifts_plus_one_is_fine =((x >> (num_shifts + 1)) << (num_shifts + 1)) == x;
  20. //      if !num_shifts_is_fine {
  21. //          panic!();
  22. //      }
  23. //      if num_shifts_is_fine && !num_shifts_plus_one_is_fine {
  24. //          return x >> num_shifts;
  25. //      } else {
  26. //          num_shifts = num_shifts + 1;
  27. //      }
  28. //  }
  29. // }
  30.  
  31. // fn get_span(mut x: u32) -> i32 {
  32. //  if x == 0 {
  33. //      return 0;
  34. //  }
  35. //  x = collapse_right(x);
  36.  
  37. //  for i in 0..32 {
  38. //      if x >> i == 0 {
  39. //          return i;
  40. //      }
  41. //  }
  42. //  panic!();
  43. // }
  44.  
  45. fn trim_array(original: &Vec<Option<u32>>) -> (Vec<Option<u32>>, u32, u32) {
  46.     let mut trimmed_left = 0;
  47.     let mut trimmed_right = 0;
  48.     let mut array = original.clone();
  49.     while array.len() > 0 && array[0] == None {
  50.         array.remove(0);
  51.         trimmed_left = trimmed_left + 1;
  52.     }
  53.     while array.len() > 0 && array[array.len() - 1] == None {
  54.         let l = array.len();
  55.         array.remove(l - 1);
  56.         trimmed_right = trimmed_right + 1;
  57.     }
  58.     return (array, trimmed_left, trimmed_right);
  59. }
  60.  
  61. fn compare_esubtable(a: &ESubTable, b: &ESubTable) -> std::cmp::Ordering {
  62.     let (a_trimmed, _, _) = trim_array(&a.itablePtrs);
  63.     let (b_trimmed, _, _) = trim_array(&b.itablePtrs);
  64.     let a_span = a_trimmed.len();
  65.     let b_span = b_trimmed.len();
  66.     if a_span < b_span {
  67.         return std::cmp::Ordering::Less;
  68.     }
  69.     if a_span > b_span {
  70.         return std::cmp::Ordering::Greater;
  71.     }
  72.     let a_num_members = count_array_members(&a_trimmed);
  73.     let b_num_members = count_array_members(&b_trimmed);
  74.     if a_num_members < b_num_members {
  75.         return std::cmp::Ordering::Less;
  76.     }
  77.     if a_num_members > b_num_members {
  78.         return std::cmp::Ordering::Greater;
  79.     }
  80.     return std::cmp::Ordering::Equal;
  81. }
  82.  
  83. fn merges_without_collisions(
  84.         combined: &Vec<Option<u32>>,
  85.         addition: &Vec<Option<u32>>,
  86.         addition_start_index_in_combined: u32) -> bool {
  87.     for i in 0..addition.len() {
  88.         let i_in_combined = addition_start_index_in_combined + i as u32;
  89.         if i_in_combined >= combined.len() as u32 {
  90.             // no collision
  91.         } else if combined[i_in_combined as usize] == None {
  92.             // no collision
  93.         } else if addition[i as usize] == None {
  94.             // no collision
  95.         } else {
  96.             // collision!
  97.             return false;
  98.         }
  99.     }
  100.     return true;
  101. }
  102.  
  103. fn merge_into(combined: &mut Vec<Option<u32>>, addition: &Vec<Option<u32>>) -> u32 {
  104.     let mut addition_start_index_in_combined: u32 = 0;
  105.     for i in 0..(combined.len() + 1) {
  106.         addition_start_index_in_combined = i as u32;
  107.         if merges_without_collisions(&combined, &addition, i as u32) {
  108.             break;
  109.         }
  110.     }
  111.     // println!("will try merge!");
  112.     // println!("combined: ");
  113.     // print_array(&combined);
  114.     // println!("addition: ");
  115.     // print_array(&addition);
  116.     // println!("index: {}", addition_start_index_in_combined);
  117.  
  118.     let combined_num_members_before = count_array_members(&combined);
  119.  
  120.     for i in 0..addition.len() {
  121.         if addition_start_index_in_combined + i as u32 >= combined.len() as u32 {
  122.             combined.push(None); // will be overwritten below
  123.         }
  124.         if addition[i] != None {
  125.             combined[(addition_start_index_in_combined + i as u32) as usize] = addition[i];
  126.         }
  127.     }
  128.  
  129.     let combined_num_members_after = count_array_members(&combined);
  130.     if combined_num_members_after != combined_num_members_before + count_array_members(&addition) {
  131.         panic!();
  132.     }
  133.  
  134.     return addition_start_index_in_combined;
  135. }
  136.  
  137. fn print_array(array: &Vec<Option<u32>>) {
  138.     print!("(");
  139.     for opt in array.iter() {
  140.         match opt {
  141.             &Some(i) => {
  142.                 print!("Some({}) ", i);
  143.             }
  144.             &None => {
  145.                 print!("None ");
  146.             }
  147.         }
  148.     }
  149.     println!(")");
  150. }
  151.  
  152. fn combine_etables(etable: &Vec<ESubTable>) -> Vec<Option<u32>> {
  153.     let mut esubtables_sorted: Vec<&ESubTable> = Vec::new();
  154.     for esubtable in etable {
  155.         esubtables_sorted.push(&esubtable);
  156.     }
  157.     esubtables_sorted.sort_by(|a, b| compare_esubtable(a, b));
  158.  
  159.     let mut combined: Vec<Option<u32>> = Vec::new();
  160.     for i in 0..etable.len() {
  161.         if etable[i].itablePtrs.len() > 0 {
  162.             combined.push(Some(0xFFFFFFFF));
  163.         } else {
  164.             combined.push(None);
  165.         }
  166.     }
  167.  
  168.     // print_array(&combined);
  169.     for esubtable in etable {
  170.         merge_into(&mut combined, &esubtable.itablePtrs);
  171.         // print_array(&combined);
  172.     }
  173.     return combined;
  174. }
  175.  
  176. fn make_none_vec_with_size(capacity: u32) -> Vec<Option<u32>> {
  177.     let mut vec: Vec<Option<u32>> = Vec::new();
  178.     for _ in 0..capacity {
  179.         vec.push(None);
  180.     }
  181.     return vec;
  182. }
  183.  
  184. fn make_esubtable_with(capacity: u32) -> ESubTable {
  185.     let esubtable = ESubTable {
  186.         itablePtrs: make_none_vec_with_size(capacity)
  187.     };
  188.     return esubtable;
  189. }
  190.  
  191. fn make_zero_etable(capacity: u32) -> Vec<ESubTable> {
  192.     let mut etable: Vec<ESubTable> = Vec::new();
  193.     for _ in 0..capacity {
  194.         etable.push(make_esubtable_with(capacity));
  195.     }
  196.     return etable;
  197. }
  198.  
  199. fn insert_into_esubtable(esubtable: &mut ESubTable, id: u32) {
  200.     let esubindex = (id % esubtable.itablePtrs.len() as u32) as usize;
  201.     esubtable.itablePtrs[esubindex] = Some(id)
  202. }
  203.  
  204. fn bucket_into_esubtable(esubtable: &mut ESubTable, id: u32) {
  205.     esubtable.itablePtrs.push(Some(id))
  206. }
  207.  
  208. fn bucket_into_etable(etable: &mut Vec<ESubTable>, id: u32) {
  209.     let etopindex = (id % (etable.len() as u32)) as usize;
  210.     let mut esubtable = &mut etable[etopindex];
  211.     bucket_into_esubtable(&mut esubtable, id);
  212. }
  213.  
  214. fn hashify_esubtable(esubtable: &mut ESubTable) {
  215.     let ids = get_array_members(&esubtable.itablePtrs);
  216.  
  217.     let mut size = ids.len() as u32;
  218.     loop {
  219.         esubtable.itablePtrs = make_none_vec_with_size(size);
  220.         for id in &ids {
  221.             insert_into_esubtable(esubtable, *id);
  222.         }
  223.         if get_array_members(&esubtable.itablePtrs).len() == ids.len() {
  224.             break;
  225.         }
  226.         size = size + 1;
  227.     }
  228. }
  229.  
  230. fn get_array_members(array: &Vec<Option<u32>>) -> Vec<u32> {
  231.     let mut members: Vec<u32> = Vec::new();
  232.     for j in 0..array.len() {
  233.         match array[j as usize] {
  234.             Some(id) => {
  235.                 members.push(id);
  236.             }
  237.             None => {}
  238.         }
  239.     }
  240.     return members;
  241. }
  242.  
  243. fn count_array_members(esubtable: &Vec<Option<u32>>) -> u32 {
  244.     return get_array_members(esubtable).len() as u32;
  245. }
  246.  
  247. fn generate_etable(ids: &Vec<u32>) -> (Vec<Option<u32>>) {
  248.     let mut capacity = ((ids.len() as f64).sqrt() / 2.0) as u32;
  249.     // if ids.len() > 170 {
  250.     //  capacity = ((ids.len() as f32) * 1.5f32) as u32;
  251.     // }
  252.     // if ids.len() > 250 {
  253.     //  capacity = (ids.len() as u32) * 2;
  254.     // }
  255.  
  256.     loop {
  257.         let mut etable = make_zero_etable(capacity);
  258.  
  259.         for id in ids.iter() {
  260.             bucket_into_etable(&mut etable, *id);
  261.         }
  262.         for mut esubtable in &mut etable {
  263.             hashify_esubtable(&mut esubtable);
  264.         }
  265.         let combined = combine_etables(&etable);
  266.         // return combined;
  267.         println!("with capacity {}, end result {}", capacity, combined.len());
  268.  
  269.         capacity = capacity + 10;
  270.  
  271.         if capacity as usize >= ids.len() * 2 {
  272.             return combined;
  273.         }
  274.     }
  275. }
  276.  
  277.  
  278.  
  279. fn main() {
  280.     let mut rng = rand::thread_rng();
  281.  
  282.     let increment = 1000;
  283.     let stop = 1000;
  284.     let mut num_elements = 0;
  285.     loop {
  286.         num_elements = num_elements + increment;
  287.  
  288.         let mut sum_of_sizes_for_average: u64 = 0;
  289.         let num_trials = 10;
  290.         let mut worst_size_option: Option<u32> = None;
  291.  
  292.         for _ in 0..num_trials {
  293.             let mut ids: Vec<u32> = Vec::new();
  294.             for _ in 0..num_elements {
  295.                 ids.push(rng.gen::<u32>());
  296.             }
  297.             let etable = generate_etable(&ids);
  298.  
  299.             let size = etable.len() as u32;
  300.  
  301.             sum_of_sizes_for_average = sum_of_sizes_for_average + size as u64;
  302.             match worst_size_option {
  303.                 None => {
  304.                     worst_size_option = Some(size);
  305.                 }
  306.                 Some(previously_worst_size) => {
  307.                     worst_size_option = Some(cmp::max(previously_worst_size, size));
  308.                 }
  309.             }
  310.         }
  311.  
  312.         let average_size = sum_of_sizes_for_average as f64 / num_trials as f64;
  313.         let worst_size = worst_size_option.unwrap_or(0);
  314.  
  315.         println!("For {} elements, average size {} and worst size {}", num_elements, average_size, worst_size);
  316.  
  317.         if num_elements >= stop {
  318.             break;
  319.         }
  320.     }
  321. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement