| 141 | } |
| 142 | |
| 143 | fn get(&mut self, input: &MultiStream) -> Option<(StreamKey, usize, usize)> { |
| 144 | while self.current_stream < self.streams.len() { |
| 145 | let stream_key = self.streams[self.current_stream]; |
| 146 | let stream_len = input.streams[&stream_key].bytes.len(); |
| 147 | |
| 148 | if self.remove_offset < stream_len { |
| 149 | self.attempts = self.attempts.saturating_sub(1); |
| 150 | // Adjust the ending length to handle removal at the end of the stream. |
| 151 | let remove_len = self.remove_len.min(stream_len - self.remove_offset); |
| 152 | return Some((stream_key, self.remove_offset, remove_len)); |
| 153 | } |
| 154 | |
| 155 | // Check if we should attempt removing smaller chunks of the same stream. |
| 156 | let min_remove_size = |
| 157 | usize::max(stream_len.next_power_of_two() / TRIM_END_STEPS, TRIM_MIN_BYTES); |
| 158 | if self.remove_len > min_remove_size && self.attempts > 0 { |
| 159 | self.remove_offset = 0; // @todo: adjust the removal location to start at the cursor position. |
| 160 | self.remove_len /= 2; |
| 161 | continue; |
| 162 | } |
| 163 | |
| 164 | // Move to the next stream. |
| 165 | self.current_stream += 1; |
| 166 | if self.current_stream >= self.streams.len() { |
| 167 | break; |
| 168 | } |
| 169 | |
| 170 | self.attempts = MAX_FAILED_ATTEMPTS_FOR_STREAM; |
| 171 | let stream_addr = self.streams[self.current_stream]; |
| 172 | let stream_len = input.streams[&stream_addr].bytes.len(); |
| 173 | self.remove_len = usize::max(stream_len.next_power_of_two() / 2, TRIM_MIN_BYTES); |
| 174 | self.remove_offset = 0; |
| 175 | } |
| 176 | |
| 177 | None |
| 178 | } |
| 179 | |
| 180 | /// Update the cursor assuming that the current location has been removed. |
| 181 | fn remove_current(&mut self) { |