sorting_race/services/sorters/
insertion.rs1use crate::models::traits::{Sorter, StepResult, Telemetry, Markers};
4use std::any::Any;
5
6#[derive(Debug)]
8pub struct InsertionSort {
9 data: Vec<i32>,
10 current_index: usize,
11 insert_pos: usize,
12 comparisons: u64,
13 moves: u64,
14 complete: bool,
15 in_insertion: bool,
16}
17
18impl InsertionSort {
19 pub fn new() -> Self {
21 Self {
22 data: Vec::new(),
23 current_index: 1,
24 insert_pos: 0,
25 comparisons: 0,
26 moves: 0,
27 complete: false,
28 in_insertion: false,
29 }
30 }
31}
32
33impl Default for InsertionSort {
34 fn default() -> Self {
35 Self::new()
36 }
37}
38
39impl Sorter for InsertionSort {
40 fn step(&mut self, budget: usize) -> StepResult {
41 if self.complete || self.data.len() <= 1 {
42 return StepResult {
43 comparisons_used: 0,
44 moves_made: 0,
45 continued: false,
46 };
47 }
48
49 let mut comparisons_used = 0;
50 let mut moves_made = 0;
51
52 while comparisons_used < budget && !self.complete {
53 if !self.in_insertion {
54 if self.current_index >= self.data.len() {
55 self.complete = true;
56 break;
57 }
58
59 self.insert_pos = self.current_index;
60 self.in_insertion = true;
61 }
62
63 if self.in_insertion && self.insert_pos > 0 {
64 comparisons_used += 1;
66 self.comparisons += 1;
67
68 if self.data[self.insert_pos] < self.data[self.insert_pos - 1] {
69 self.data.swap(self.insert_pos, self.insert_pos - 1);
71 moves_made += 1;
72 self.moves += 1;
73 self.insert_pos -= 1;
74 } else {
75 self.in_insertion = false;
77 self.current_index += 1;
78 }
79 } else {
80 self.in_insertion = false;
82 self.current_index += 1;
83 }
84 }
85
86 StepResult {
87 comparisons_used,
88 moves_made,
89 continued: !self.complete,
90 }
91 }
92
93 fn is_complete(&self) -> bool {
94 self.complete
95 }
96
97 fn get_telemetry(&self) -> Telemetry {
98 let mut markers = Markers::default();
99
100 if !self.complete {
101 if self.in_insertion {
102 markers.cursors = vec![self.insert_pos];
103 if self.insert_pos > 0 {
104 markers.cursors.push(self.insert_pos - 1);
105 }
106 } else if self.current_index < self.data.len() {
107 markers.cursors = vec![self.current_index];
108 }
109 }
110
111 Telemetry {
112 total_comparisons: self.comparisons,
113 total_moves: self.moves,
114 memory_current: self.get_memory_usage(),
115 memory_peak: self.get_memory_usage(),
116 highlights: markers.cursors.clone(),
117 markers,
118 status_text: if self.complete {
119 "Completed".to_string()
120 } else if self.in_insertion {
121 format!("Inserting element at index {}", self.insert_pos)
122 } else {
123 format!("Processing index {}", self.current_index)
124 },
125 progress_hint: if self.data.len() <= 1 {
126 1.0
127 } else {
128 let progress = (self.current_index as f32) / (self.data.len() as f32);
129 progress.min(1.0).max(0.0) },
131 }
132 }
133
134 fn reset(&mut self, data: Vec<i32>) {
135 self.data = data;
136 self.current_index = 1;
137 self.insert_pos = 0;
138 self.comparisons = 0;
139 self.moves = 0;
140 self.complete = self.data.len() <= 1;
141 self.in_insertion = false;
142 }
143
144 fn name(&self) -> &str {
145 "Insertion Sort"
146 }
147
148 fn get_array(&self) -> &[i32] {
149 &self.data
150 }
151
152 fn get_memory_usage(&self) -> usize {
153 self.data.len() * std::mem::size_of::<i32>()
155 }
156
157 fn as_any(&self) -> &dyn Any {
158 self
159 }
160
161 fn as_any_mut(&mut self) -> &mut dyn Any {
162 self
163 }
164}