vortex_file/segments/
source.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::sync::Arc;
5
6use futures::{FutureExt, TryFutureExt};
7use vortex_error::{VortexError, vortex_err};
8use vortex_io::VortexReadAt;
9use vortex_layout::segments::{SegmentFuture, SegmentId, SegmentSource};
10
11use crate::SegmentSpec;
12
13pub struct FileSegmentSource {
14    segments: Arc<[SegmentSpec]>,
15    read: Arc<dyn VortexReadAt>,
16}
17
18impl FileSegmentSource {
19    pub fn new(segments: Arc<[SegmentSpec]>, read: Arc<dyn VortexReadAt>) -> Self {
20        Self { segments, read }
21    }
22}
23
24impl SegmentSource for FileSegmentSource {
25    fn request(&self, id: SegmentId) -> SegmentFuture {
26        // We eagerly create the read future here assuming the behaviour of [`FileRead`], where
27        // coalescing becomes effective prior to the future being polled.
28        let maybe_fut = self.segments.get(*id as usize).cloned().map(|spec| {
29            self.read
30                .clone()
31                .read_at(spec.offset, spec.length as usize, spec.alignment)
32                .map_err(VortexError::from)
33        });
34
35        async move {
36            maybe_fut
37                .ok_or_else(|| vortex_err!("Missing segment: {}", id))?
38                .await
39        }
40        .boxed()
41    }
42}