1use std::path::PathBuf;
7
8use serde::Serialize;
9use vortex::error::VortexResult;
10use vortex::file::OpenOptionsSessionExt;
11use vortex::session::VortexSession;
12
13use crate::segment_tree::collect_segment_tree;
14
15#[derive(Debug, clap::Parser)]
17pub struct SegmentsArgs {
18 pub file: PathBuf,
20}
21
22#[derive(Serialize)]
23struct SegmentsOutput {
24 columns: Vec<ColumnInfo>,
26}
27
28#[derive(Serialize)]
29struct ColumnInfo {
30 name: String,
32 segments: Vec<SegmentInfo>,
34}
35
36#[derive(Serialize)]
37struct SegmentInfo {
38 name: String,
40 row_offset: u64,
42 row_count: u64,
44 byte_offset: u64,
46 byte_length: u32,
48 alignment: usize,
50 byte_gap: u64,
52}
53
54pub async fn exec_segments(session: &VortexSession, args: SegmentsArgs) -> VortexResult<()> {
60 let vxf = session.open_options().open_path(args.file).await?;
61 let footer = vxf.footer();
62
63 let mut segment_tree = collect_segment_tree(footer.layout().as_ref(), footer.segment_map());
64
65 let columns: Vec<ColumnInfo> = segment_tree
67 .segment_ordering
68 .iter()
69 .filter_map(|name| {
70 let mut segments = segment_tree.segments.remove(name)?;
71
72 segments.sort_by(|a, b| a.spec.offset.cmp(&b.spec.offset));
74
75 let mut current_offset = 0u64;
77 let segment_infos: Vec<SegmentInfo> = segments
78 .into_iter()
79 .map(|seg| {
80 let byte_gap = if current_offset == 0 {
81 0
82 } else {
83 seg.spec.offset.saturating_sub(current_offset)
84 };
85 current_offset = seg.spec.offset + seg.spec.length as u64;
86
87 SegmentInfo {
88 name: seg.name.to_string(),
89 row_offset: seg.row_offset,
90 row_count: seg.row_count,
91 byte_offset: seg.spec.offset,
92 byte_length: seg.spec.length,
93 alignment: *seg.spec.alignment,
94 byte_gap,
95 }
96 })
97 .collect();
98
99 Some(ColumnInfo {
100 name: name.to_string(),
101 segments: segment_infos,
102 })
103 })
104 .collect();
105
106 let output = SegmentsOutput { columns };
107
108 let json_output = serde_json::to_string_pretty(&output)
109 .map_err(|e| vortex::error::vortex_err!("Failed to serialize JSON: {e}"))?;
110 println!("{json_output}");
111
112 Ok(())
113}