pub fn simulate(&mut self) {
        let mut current_path: Option<usize> = None;
        let mut hit_soc_cache_pair: (Hit, CacheLevel) = (Hit {
            index: 0,
            ratio: 0.0,
            cache_level: CacheLevel::LevelOne,
            path: 0,
            width: 0,
            height: 0,
        }, CacheLevel::LevelOne);
        for (k, user_fov) in self.user_fov_list.iter().enumerate() {
            // Variables for soc calculation
            let mut max_ratio: f64 = f64::NEG_INFINITY;
            let mut max_ratio_path: Option<usize> = None;
            let mut temp_viewport: Option<&Viewport> = None;
            let width = self.fov_width;
            let height = self.fov_height;

            // Variables for wifi calculation
//            let resend_flag = false;

            if self.path_list.len() > k {
                for (path, path_viewport) in self.path_list[k].iter().enumerate() {
                    let current_ratio = path_viewport.get_cover_result(user_fov);
                    if max_ratio < current_ratio {
                        max_ratio = current_ratio;
                        max_ratio_path = Some(path);
                        temp_viewport = Some(path_viewport);
                    }
                }

                // Compute SOC
                if k % self.segment == 0 {
                    // the first frame in the segment
                    current_path = max_ratio_path;
                    hit_soc_cache_pair = self.compare_from_level_one(&temp_viewport.unwrap(), &user_fov, k, max_ratio_path.unwrap(), width, height);
                } else {
                    // the rest frames except for the first one in the segment
//                    println!("k: {}, path: {}, ratio: {}", k, max_ratio_path.unwrap(), max_ratio);

                    if self.is_hierarchical() {
                        // hierarchical
                        match hit_soc_cache_pair.1 {
                            CacheLevel::LevelOne => {
                                if current_path == max_ratio_path {
                                    hit_soc_cache_pair = self.compare_from_level_one(&temp_viewport.unwrap(), &user_fov, k, max_ratio_path.unwrap(), width, height);
                                } else {
                                    hit_soc_cache_pair = self.compare_from_level_three(k, max_ratio_path.unwrap());
                                }
                            }
                            CacheLevel::LevelTwo => {
                                if current_path == max_ratio_path {
                                    hit_soc_cache_pair = self.compare_from_level_two(&temp_viewport.unwrap(), &user_fov, k, max_ratio_path.unwrap());
                                } else {
                                    hit_soc_cache_pair = self.compare_from_level_three(k, current_path.unwrap());
                                }
                            }
                            CacheLevel::LevelThree => {
                                hit_soc_cache_pair = self.compare_from_level_three(k, current_path.unwrap());
                            }
                        }
                    } else {
                        match hit_soc_cache_pair.1 {
                            CacheLevel::LevelOne => {
                                if current_path == max_ratio_path {
                                    hit_soc_cache_pair = self.compare_from_level_one(&temp_viewport.unwrap(), &user_fov, k, max_ratio_path.unwrap(), width, height);
                                } else {
                                    hit_soc_cache_pair = self.compare_from_level_three(k, max_ratio_path.unwrap());
                                }
                            }
                            CacheLevel::LevelTwo => assert!(false),
                            CacheLevel::LevelThree => hit_soc_cache_pair = self.compare_from_level_three(k, current_path.unwrap()),
                        }
                    }
                }
                self.hit_list_for_soc.push(hit_soc_cache_pair.0.clone());
            }

            // Count resend segments for network power calculation
            if k % self.segment == self.segment - 1 {
                match hit_soc_cache_pair.1 {
                    CacheLevel::LevelThree =>  self.segment_resend_counter += 1,
                    _ => ()
                }
            }
        }

        self.segment_count = (self.hit_list_for_soc.len() as f64 / self.segment as f64).ceil() as usize;

//        assert_eq!(self.hit_list.len(), self.user_fov_list.len());
//        println!("total segment: {}, segment_resend_counter: {}", self.user_fov_list.len() / 20, self.segment_resend_counter);

        // fill wifi_pc and soc_pc
        self.power_consumption();
    }
// simulate with hierarchical or non-hierarchical with segment and threshold implicitly
simulate with hierarchical or non-hierarchical with segment and threshold implicitly
simulate with hierarchical or non - hierarchical with segment and threshold implicitly
pub fn simulate(&mut self) {
        let mut current_path: Option<usize> = None;
        let mut hit_soc_cache_pair: (Hit, CacheLevel) = (Hit {
            index: 0,
            ratio: 0.0,
            cache_level: CacheLevel::LevelOne,
            path: 0,
            width: 0,
            height: 0,
        }, CacheLevel::LevelOne);
        for (k, user_fov) in self.user_fov_list.iter().enumerate() {
            // Variables for soc calculation
            let mut max_ratio: f64 = f64::NEG_INFINITY;
            let mut max_ratio_path: Option<usize> = None;
            let mut temp_viewport: Option<&Viewport> = None;
            let width = self.fov_width;
            let height = self.fov_height;
            // Variables for wifi calculation
//            let resend_flag = false;
            if self.path_list.len() > k {
                for (path, path_viewport) in self.path_list[k].iter().enumerate() {
                    let current_ratio = path_viewport.get_cover_result(user_fov);
                    if max_ratio < current_ratio {
                        max_ratio = current_ratio;
                        max_ratio_path = Some(path);
                        temp_viewport = Some(path_viewport);
                    }
                }
                // Compute SOC
                if k % self.segment == 0 {
                    // the first frame in the segment
                    current_path = max_ratio_path;
                    hit_soc_cache_pair = self.compare_from_level_one(&temp_viewport.unwrap(), &user_fov, k, max_ratio_path.unwrap(), width, height);
                } else {
                    // the rest frames except for the first one in the segment
//                    println!("k: {}, path: {}, ratio: {}", k, max_ratio_path.unwrap(), max_ratio);
                    if self.is_hierarchical() {
                        // hierarchical
                        match hit_soc_cache_pair.1 {
                            CacheLevel::LevelOne => {
                                if current_path == max_ratio_path {
                                    hit_soc_cache_pair = self.compare_from_level_one(&temp_viewport.unwrap(), &user_fov, k, max_ratio_path.unwrap(), width, height);
                                } else {
                                    hit_soc_cache_pair = self.compare_from_level_three(k, max_ratio_path.unwrap());
                                }
                            }
                            CacheLevel::LevelTwo => {
                                if current_path == max_ratio_path {
                                    hit_soc_cache_pair = self.compare_from_level_two(&temp_viewport.unwrap(), &user_fov, k, max_ratio_path.unwrap());
                                } else {
                                    hit_soc_cache_pair = self.compare_from_level_three(k, current_path.unwrap());
                                }
                            }
                            CacheLevel::LevelThree => {
                                hit_soc_cache_pair = self.compare_from_level_three(k, current_path.unwrap());
                            }
                        }
                    } else {
                        match hit_soc_cache_pair.1 {
                            CacheLevel::LevelOne => {
                                if current_path == max_ratio_path {
                                    hit_soc_cache_pair = self.compare_from_level_one(&temp_viewport.unwrap(), &user_fov, k, max_ratio_path.unwrap(), width, height);
                                } else {
                                    hit_soc_cache_pair = self.compare_from_level_three(k, max_ratio_path.unwrap());
                                }
                            }
                            CacheLevel::LevelTwo => assert!(false),
                            CacheLevel::LevelThree => hit_soc_cache_pair = self.compare_from_level_three(k, current_path.unwrap()),
                        }
                    }
                }
                self.hit_list_for_soc.push(hit_soc_cache_pair.0.clone());
            }
            // Count resend segments for network power calculation
            if k % self.segment == self.segment - 1 {
                match hit_soc_cache_pair.1 {
                    CacheLevel::LevelThree =>  self.segment_resend_counter += 1,
                    _ => ()
                }
            }
        }
        self.segment_count = (self.hit_list_for_soc.len() as f64 / self.segment as f64).ceil() as usize;
//        assert_eq!(self.hit_list.len(), self.user_fov_list.len());
//        println!("total segment: {}, segment_resend_counter: {}", self.user_fov_list.len() / 20, self.segment_resend_counter);
        // fill wifi_pc and soc_pc
        self.power_consumption();
    }
pub fn simulate ( & mut self ) { let mut current_path : Option < usize > = None ; let mut hit_soc_cache_pair : ( Hit , CacheLevel ) = ( Hit { index : 0 , ratio : 0.0 , cache_level : CacheLevel :: LevelOne , path : 0 , width : 0 , height : 0 , } , CacheLevel :: LevelOne ) ; for ( k , user_fov ) in self . user_fov_list . iter ( ) . enumerate ( ) { // Variables for soc calculation let mut max_ratio : f64 = f64 :: NEG_INFINITY ; let mut max_ratio_path : Option < usize > = None ; let mut temp_viewport : Option < & Viewport > = None ; let width = self . fov_width ; let height = self . fov_height ; // Variables for wifi calculation //            let resend_flag = false; if self . path_list . len ( ) > k { for ( path , path_viewport ) in self . path_list [ k ] . iter ( ) . enumerate ( ) { let current_ratio = path_viewport . get_cover_result ( user_fov ) ; if max_ratio < current_ratio { max_ratio = current_ratio ; max_ratio_path = Some ( path ) ; temp_viewport = Some ( path_viewport ) ; } } // Compute SOC if k % self . segment == 0 { // the first frame in the segment current_path = max_ratio_path ; hit_soc_cache_pair = self . compare_from_level_one ( & temp_viewport . unwrap ( ) , & user_fov , k , max_ratio_path . unwrap ( ) , width , height ) ; } else { // the rest frames except for the first one in the segment //                    println!("k: {}, path: {}, ratio: {}", k, max_ratio_path.unwrap(), max_ratio); if self . is_hierarchical ( ) { // hierarchical match hit_soc_cache_pair . 1 { CacheLevel :: LevelOne => { if current_path == max_ratio_path { hit_soc_cache_pair = self . compare_from_level_one ( & temp_viewport . unwrap ( ) , & user_fov , k , max_ratio_path . unwrap ( ) , width , height ) ; } else { hit_soc_cache_pair = self . compare_from_level_three ( k , max_ratio_path . unwrap ( ) ) ; } } CacheLevel :: LevelTwo => { if current_path == max_ratio_path { hit_soc_cache_pair = self . compare_from_level_two ( & temp_viewport . unwrap ( ) , & user_fov , k , max_ratio_path . unwrap ( ) ) ; } else { hit_soc_cache_pair = self . compare_from_level_three ( k , current_path . unwrap ( ) ) ; } } CacheLevel :: LevelThree => { hit_soc_cache_pair = self . compare_from_level_three ( k , current_path . unwrap ( ) ) ; } } } else { match hit_soc_cache_pair . 1 { CacheLevel :: LevelOne => { if current_path == max_ratio_path { hit_soc_cache_pair = self . compare_from_level_one ( & temp_viewport . unwrap ( ) , & user_fov , k , max_ratio_path . unwrap ( ) , width , height ) ; } else { hit_soc_cache_pair = self . compare_from_level_three ( k , max_ratio_path . unwrap ( ) ) ; } } CacheLevel :: LevelTwo => assert ! ( false ) , CacheLevel :: LevelThree => hit_soc_cache_pair = self . compare_from_level_three ( k , current_path . unwrap ( ) ) , } } } self . hit_list_for_soc . push ( hit_soc_cache_pair . 0 . clone ( ) ) ; } // Count resend segments for network power calculation if k % self . segment == self . segment - 1 { match hit_soc_cache_pair . 1 { CacheLevel :: LevelThree => self . segment_resend_counter += 1 , _ => ( ) } } } self . segment_count = ( self . hit_list_for_soc . len ( ) as f64 / self . segment as f64 ) . ceil ( ) as usize ; //        assert_eq!(self.hit_list.len(), self.user_fov_list.len()); //        println!("total segment: {}, segment_resend_counter: {}", self.user_fov_list.len() / 20, self.segment_resend_counter); // fill wifi_pc and soc_pc self . power_consumption ( ) ; }
simulate with hierarchical or non-hierarchical with segment and threshold implicitly
simulate with hierarchical or non - hierarchical with segment and threshold implicitly
&mut self