| 195 | } |
| 196 | |
| 197 | fn read_records(&mut self, num_records: usize) -> Result<usize> { |
| 198 | let mut read = 0; |
| 199 | while read < num_records { |
| 200 | let batch_id = self.get_batch_id_from_position(self.outer_position); |
| 201 | |
| 202 | // Check local cache first |
| 203 | let cached = if let Some(array) = self.local_cache.get(&batch_id) { |
| 204 | Some(Arc::clone(array)) |
| 205 | } else { |
| 206 | // If not in local cache, i.e., we are consumer, check shared cache |
| 207 | let cache_content = self |
| 208 | .shared_cache |
| 209 | .read() |
| 210 | .unwrap() |
| 211 | .get(self.column_idx, batch_id); |
| 212 | if let Some(array) = cache_content.as_ref() { |
| 213 | // Store in local cache for later use in consume_batch |
| 214 | self.local_cache.insert(batch_id, Arc::clone(array)); |
| 215 | } |
| 216 | cache_content |
| 217 | }; |
| 218 | |
| 219 | match cached { |
| 220 | Some(array) => { |
| 221 | let array_len = array.len(); |
| 222 | if array_len + batch_id.val * self.batch_size > self.outer_position { |
| 223 | // the cache batch has some records that we can select |
| 224 | let v = array_len + batch_id.val * self.batch_size - self.outer_position; |
| 225 | let select_cnt = std::cmp::min(num_records - read, v); |
| 226 | read += select_cnt; |
| 227 | self.metrics.increment_cache_reads(select_cnt); |
| 228 | self.outer_position += select_cnt; |
| 229 | self.selections.append_n(select_cnt, true); |
| 230 | } else { |
| 231 | // this is last batch and we have used all records from it |
| 232 | break; |
| 233 | } |
| 234 | } |
| 235 | None => { |
| 236 | let read_from_inner = self.fetch_batch(batch_id)?; |
| 237 | // Reached end-of-file, no more records to read |
| 238 | if read_from_inner == 0 { |
| 239 | break; |
| 240 | } |
| 241 | self.metrics.increment_inner_reads(read_from_inner); |
| 242 | let select_from_this_batch = std::cmp::min( |
| 243 | num_records - read, |
| 244 | self.inner_position - self.outer_position, |
| 245 | ); |
| 246 | read += select_from_this_batch; |
| 247 | self.outer_position += select_from_this_batch; |
| 248 | self.selections.append_n(select_from_this_batch, true); |
| 249 | if read_from_inner < self.batch_size { |
| 250 | // this is last batch from inner reader |
| 251 | break; |
| 252 | } |
| 253 | } |
| 254 | } |