Skip to content

Commit

Permalink
fix compile errors
Browse files Browse the repository at this point in the history
  • Loading branch information
a10y committed Jan 28, 2025
1 parent e84c1a5 commit 669f44e
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 56 deletions.
49 changes: 28 additions & 21 deletions vortex-cli/src/browse/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ use ratatui::widgets::ListState;
use vortex::dtype::{DType, Field, Nullability, StructDType};
use vortex::error::VortexResult;
use vortex::file::{
read_initial_bytes, ExecutionMode, FileLayout, InitialRead, SplitBy, VortexOpenOptions,
CHUNKED_LAYOUT_ID, COLUMNAR_LAYOUT_ID, FLAT_LAYOUT_ID,
ExecutionMode, FileLayout, Segment, SplitBy, VortexOpenOptions, CHUNKED_LAYOUT_ID,
COLUMNAR_LAYOUT_ID, FLAT_LAYOUT_ID,
};
use vortex::io::{TokioFile, VortexReadAt};
use vortex::io::TokioFile;
use vortex::sampling_compressor::ALL_ENCODINGS_CONTEXT;
use vortex::stats::stats_from_bitset_bytes;
use vortex_layout::{LayoutData, LayoutEncodingRef};
use vortex_layout::segments::SegmentId;
use vortex_layout::{LayoutData, LayoutEncodingRef};
// Add a shared Tokio Runtime for use in the app.

#[derive(Default, Copy, Clone, Eq, PartialEq)]
Expand Down Expand Up @@ -56,22 +56,24 @@ impl From<u16> for Encoding {
/// The pointer wraps an InitialRead.
pub struct LayoutCursor {
path: Vec<usize>,
initial_read: FileLayout,
file_layout: FileLayout,
layout: LayoutData,
segment_map: Arc<[Segment]>,
}

impl LayoutCursor {
pub fn new(layout: FileLayout) -> Self {
Self {
initial_read,
path: Vec::new(),
layout: layout.root_layout().clone(),
segment_map: Arc::clone(layout.segment_map()),
file_layout: layout,
}
}

pub fn new_with_path(initial_read: FileLayout, path: Vec<usize>) -> Self {
let mut layout = initial_read.root_layout().clone();
let mut dtype = initial_read.dtype().clone();
pub fn new_with_path(file_layout: FileLayout, path: Vec<usize>) -> Self {
let mut layout = file_layout.root_layout().clone();
let mut dtype = file_layout.dtype().clone();
// Traverse the layout tree at each element of the path.
for component in path.iter().copied() {
// Find the DType of the child based on the DType of the current node.
Expand Down Expand Up @@ -114,15 +116,13 @@ impl LayoutCursor {
_ => todo!("unknown DType"),
};

layout = layout
.child(component, dtype.clone())
.expect("children")
.get(component);
layout = layout.child(component, dtype.clone()).expect("children");
}

Self {
segment_map: Arc::clone(file_layout.segment_map()),
path,
initial_read,
file_layout,
layout,
}
}
Expand All @@ -133,14 +133,14 @@ impl LayoutCursor {
let mut path = self.path.clone();
path.push(n);

Self::new_with_path(self.initial_read.clone(), path)
Self::new_with_path(self.file_layout.clone(), path)
}

pub fn parent(&self) -> Self {
let mut path = self.path.clone();
path.pop();

Self::new_with_path(self.initial_read.clone(), path)
Self::new_with_path(self.file_layout.clone(), path)
}

pub fn dtype(&self) -> &DType {
Expand All @@ -155,7 +155,9 @@ impl LayoutCursor {
&self.layout
}

pub fn segment(&self, id: SegmentId) -> &Segment
pub fn segment(&self, id: SegmentId) -> &Segment {
&self.segment_map[*id as usize]
}
}

/// State saved across all Tabs.
Expand All @@ -171,8 +173,14 @@ pub struct AppState {
}

impl AppState {
// Read the given byte range.
// We're cheating by doing the reads synchronously since we're given byte offsets.
// Read a specific segment by SegmentId.
pub fn read_segment(&self, segment: SegmentId) -> Bytes {
let segment = self.cursor.segment(segment);
let range = segment.offset..(segment.offset + segment.length as u64);
self.read_bytes_sync(range)
}

// Read the provided byte range
pub fn read_bytes_sync(&self, range: Range<u64>) -> Bytes {
let mut buf = BytesMut::zeroed((range.end - range.start).try_into().expect("zeroed"));
self.reader
Expand All @@ -186,11 +194,10 @@ impl AppState {
/// Create an app backed from a file path.
pub async fn create_file_app(path: impl AsRef<Path>) -> VortexResult<AppState> {
let reader = TokioFile::open(path)?;
let size = reader.size().await?;
let file = VortexOpenOptions::new(ALL_ENCODINGS_CONTEXT.clone())
.with_execution_mode(ExecutionMode::Inline)
.with_split_by(SplitBy::Layout)
.open(reader)
.open(reader.clone())
.await?;

let cursor = LayoutCursor::new(file.file_layout().clone());
Expand Down
55 changes: 25 additions & 30 deletions vortex-cli/src/browse/ui/layouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ use ratatui::widgets::{
};
use vortex::dtype::{DType, Field};
use vortex::error::{vortex_bail, VortexResult};
use vortex::file::{CHUNKED_LAYOUT_ID, COLUMNAR_LAYOUT_ID, FLAT_LAYOUT_ID};
use vortex::ipc::messages::{BufMessageReader, DecoderMessage};
use vortex::sampling_compressor::ALL_ENCODINGS_CONTEXT;
use vortex::stats::stats_from_bitset_bytes;
use vortex::{ArrayData, Context};

use crate::browse::app::{AppState, Encoding, LayoutCursor};
use crate::browse::app::{AppState, LayoutCursor};

/// Render the Layouts tab.
pub fn render_layouts(app_state: &mut AppState, area: Rect, buf: &mut Buffer) {
Expand All @@ -26,7 +27,7 @@ pub fn render_layouts(app_state: &mut AppState, area: Rect, buf: &mut Buffer) {
render_layout_header(&app_state.cursor, header_area, buf);

// Render the list view if the layout has children
if app_state.cursor.encoding() == Encoding::Flat {
if app_state.cursor.encoding().id() == FLAT_LAYOUT_ID {
render_array(app_state, detail_area, buf);
} else {
render_children_list(
Expand All @@ -45,16 +46,16 @@ fn render_layout_header(cursor: &LayoutCursor, area: Rect, buf: &mut Buffer) {
// .margin(10)
// .areas(area);

let layout_kind = match cursor.encoding() {
Encoding::Flat => "FLAT".to_string(),
Encoding::Chunked => "CHUNKED".to_string(),
Encoding::Columnar => "COLUMNAR".to_string(),
Encoding::Unknown => "UNKNOWN".to_string(),
let layout_kind = match cursor.encoding().id() {
FLAT_LAYOUT_ID => "FLAT".to_string(),
CHUNKED_LAYOUT_ID => "CHUNKED".to_string(),
COLUMNAR_LAYOUT_ID => "COLUMNAR".to_string(),
_ => "UNKNOWN".to_string(),
};

// If using a FlatLayout, read the array and parse the metadata.

let row_count = cursor.layout_fb().row_count();
let row_count = cursor.layout().row_count();

let mut rows = vec![
Text::from(format!("Kind: {layout_kind}")).bold(),
Expand All @@ -64,18 +65,10 @@ fn render_layout_header(cursor: &LayoutCursor, area: Rect, buf: &mut Buffer) {
.green(),
];

if cursor.encoding() == Encoding::Chunked {
if cursor.encoding().id() == CHUNKED_LAYOUT_ID {
// Push any columnar stats.
if cursor.layout_fb().metadata().is_none() {
rows.push(Text::from("No chunk statistics found"));
} else {
let available_stats = stats_from_bitset_bytes(
cursor
.layout_fb()
.metadata()
.expect("layout_fb metadata")
.bytes(),
);
if let Some(metadata) = cursor.layout().metadata() {
let available_stats = stats_from_bitset_bytes(&metadata);
let mut line = String::new();
line.push_str("Statistics: ");
for stat in available_stats {
Expand All @@ -84,6 +77,8 @@ fn render_layout_header(cursor: &LayoutCursor, area: Rect, buf: &mut Buffer) {
}

rows.push(Text::from(line));
} else {
rows.push(Text::from("No chunk statistics found"));
}
}

Expand All @@ -107,8 +102,7 @@ fn render_array(app: &AppState, area: Rect, buf: &mut Buffer) {
.layout()
.segment_id(0)
.expect("FlatLayout must have exactly 1 segment");
app.cursor.layout()
let bytes = app.read_bytes_sync(segment_id.begin()..segment_id.end());
let bytes = app.read_segment(segment_id);
let array = array_from_bytes(
bytes,
ALL_ENCODINGS_CONTEXT.clone(),
Expand Down Expand Up @@ -138,9 +132,10 @@ fn render_children_list(
state: &mut ListState,
) {
// TODO: add selection state.
let layout = cursor.layout_fb();
if let Some(child_layouts) = layout.children() {
let list_items: Vec<String> = (0..child_layouts.len())
let layout = cursor.layout();

if layout.nchildren() > 0 {
let list_items: Vec<String> = (0..layout.nchildren())
.map(|idx| child_name(cursor, idx))
.collect();

Expand All @@ -166,8 +161,8 @@ fn render_children_list(
}

fn child_name(cursor: &LayoutCursor, nth: usize) -> String {
match cursor.encoding() {
Encoding::Columnar => {
match cursor.encoding().id() {
COLUMNAR_LAYOUT_ID => {
let field_info = cursor
.dtype()
.as_struct()
Expand All @@ -178,19 +173,19 @@ fn child_name(cursor: &LayoutCursor, nth: usize) -> String {
let field_dtype = field_info.dtype.value().expect("dtype value");
format!("Column {nth} - {field_name} ({field_dtype})")
}
Encoding::Chunked => {
CHUNKED_LAYOUT_ID => {
// 0th child of a ChunkedLayout is the chunk stats array.
// The rest of the chunks are child arrays
if cursor.layout_fb().metadata().is_none() {
if cursor.layout().metadata().is_none() {
format!("Chunk {nth}")
} else if nth == 0 {
"Chunk Statistics".to_string()
} else {
format!("Chunk {}", nth - 1)
}
}
Encoding::Flat => format!("Page {nth}"),
Encoding::Unknown => format!("Unknown {nth}"),
FLAT_LAYOUT_ID => format!("Page {nth}"),
_ => format!("Unknown {nth}"),
}
}

Expand Down
2 changes: 1 addition & 1 deletion vortex-file/src/footer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ mod segment;

pub use file_layout::*;
pub(crate) use postscript::*;
pub(crate) use segment::*;
pub use segment::*;
6 changes: 3 additions & 3 deletions vortex-file/src/footer/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use vortex_flatbuffers::footer2 as fb;
/// The location of a segment within a Vortex file.
#[derive(Clone, Debug)]
pub struct Segment {
pub(crate) offset: u64,
pub(crate) length: u32,
pub(crate) alignment: Alignment,
pub offset: u64,
pub length: u32,
pub alignment: Alignment,
}

impl From<&Segment> for fb::Segment {
Expand Down
2 changes: 1 addition & 1 deletion vortex-file/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ mod tests;
mod writer;

pub use file::*;
pub use footer::FileLayout;
pub use footer::{FileLayout, Segment};
pub use forever_constant::*;
pub use open::*;
pub use writer::*;
Expand Down

0 comments on commit 669f44e

Please sign in to comment.