From a893a124f26002a53e39bc6610f70f23c5113e48 Mon Sep 17 00:00:00 2001 From: Andrew Duffy Date: Mon, 16 Dec 2024 09:36:27 -0500 Subject: [PATCH] SharedArrayData -> SharedPtr --- src/components/array.rs | 33 ++++++++++++------------ src/components/array_info/dict.rs | 9 +++++++ src/components/array_info/fsst.rs | 9 +++++++ src/components/array_info/mod.rs | 43 ++++++++++++++++++++++++++++++- src/main.rs | 30 +++++++++++++-------- src/vortex_file.rs | 11 -------- 6 files changed, 96 insertions(+), 39 deletions(-) create mode 100644 src/components/array_info/dict.rs create mode 100644 src/components/array_info/fsst.rs delete mode 100644 src/vortex_file.rs diff --git a/src/components/array.rs b/src/components/array.rs index 823a21c..a4d3168 100644 --- a/src/components/array.rs +++ b/src/components/array.rs @@ -1,19 +1,22 @@ use std::{collections::VecDeque, sync::Arc}; use dioxus::{logger::tracing, prelude::*}; -use vortex::{stats::ArrayStatistics, validity::ArrayValidity, ArrayDType}; +use vortex::{stats::ArrayStatistics, validity::ArrayValidity, ArrayDType, ArrayData}; use crate::{ components::{dtype::DTypeInfo, stats::Statistics, Heading}, - SharedArrayData, + SharedPtr, }; /// Show some basic info about an ArrayView. #[component] -pub fn ArrayView(file_name: String, history_stack: Signal>) -> Element { +pub fn ArrayView( + file_name: String, + history_stack: Signal>>, +) -> Element { // Use the history stack to take data from the front/back of the stack let array = history_stack()[0].clone(); - let stats = array.inner.statistics().to_set(); + let stats = array.statistics().to_set(); rsx! { div { class: "flex flex-col mt-4", @@ -43,11 +46,11 @@ pub fn ArrayView(file_name: String, history_stack: Signal Element { - let size = humansize::format_size(array.inner.nbytes(), humansize::BINARY); - let row_count = array.inner.len(); - let encoding_id = array.inner.encoding().id().to_string(); - let null_count = array.inner.logical_validity().null_count()?; +fn ArraySummary(array: SharedPtr, file_name: String) -> Element { + let size = humansize::format_size(array.nbytes(), humansize::BINARY); + let row_count = array.len(); + let encoding_id = array.encoding().id().to_string(); + let null_count = array.logical_validity().null_count()?; let null_pct: f64 = 100. * (null_count as f64) / (row_count as f64); rsx! { @@ -137,7 +140,7 @@ fn ArraySummary(array: SharedArrayData, file_name: String) -> Element { } #[component] -pub fn ArrayChildren(mut history_stack: Signal>) -> Element { +pub fn ArrayChildren(mut history_stack: Signal>>) -> Element { let array = history_stack()[0].clone(); rsx! { Heading { text: "Child Arrays" } @@ -149,7 +152,7 @@ pub fn ArrayChildren(mut history_stack: Signal>) -> El table { class: "table-auto w-full min-w-max max-h-96 overflow-y-scroll text-left border-collapse", tbody { class: "border-b border-1 border-zinc-50/10", - for (idx , child) in array.inner.children().iter().cloned().enumerate() { + for (idx , child) in array.children().iter().cloned().enumerate() { tr { class: "font-normal border-b border-1 border-zinc-50/10", // Interactivity @@ -161,9 +164,7 @@ pub fn ArrayChildren(mut history_stack: Signal>) -> El tracing::info!("descending into the {idx} child"); history_stack .write() - .push_front(SharedArrayData { - inner: Arc::new(child), - }); + .push_front(SharedPtr(Arc::new(child))); }, td { class: "p-2", p { class: "block font-sans text-sm antialiased leading-normal", diff --git a/src/components/array_info/dict.rs b/src/components/array_info/dict.rs new file mode 100644 index 0000000..483143b --- /dev/null +++ b/src/components/array_info/dict.rs @@ -0,0 +1,9 @@ +use dioxus::prelude::*; +use vortex::dict::DictArray; + +use crate::SharedPtr; + +#[component] +pub fn DictInfo(array: SharedPtr) -> Element { + rsx! {} +} diff --git a/src/components/array_info/fsst.rs b/src/components/array_info/fsst.rs new file mode 100644 index 0000000..3225827 --- /dev/null +++ b/src/components/array_info/fsst.rs @@ -0,0 +1,9 @@ +use dioxus::prelude::*; +use vortex::fsst::FSSTArray; + +use crate::SharedPtr; + +#[component] +pub fn FSSTInfo(array: SharedPtr) -> Element { + rsx! {} +} diff --git a/src/components/array_info/mod.rs b/src/components/array_info/mod.rs index 60c6262..1f3354f 100644 --- a/src/components/array_info/mod.rs +++ b/src/components/array_info/mod.rs @@ -1 +1,42 @@ -pub mod chunked; +use std::sync::Arc; + +use dict::DictInfo; +use dioxus::prelude::*; +use fsst::FSSTInfo; +use vortex::{ + dict::{DictArray, DictEncoding}, + encoding::Encoding, + fsst::{FSSTArray, FSSTEncoding}, + ArrayData, +}; + +use crate::SharedPtr; + +pub mod dict; +pub mod fsst; + +/// Show encoding-specific information about an array. +/// +/// This is a parent component that will dynamically delegate to the encoding-specific child component. +#[component] +pub fn EncodingInfo(array: SharedPtr) -> Element { + let array = (*array).clone(); + let encoding = array.encoding().id(); + + if encoding == FSSTEncoding::ID { + // Show FSST symbol table info. + let array = SharedPtr(Arc::new(FSSTArray::try_from(array)?)); + rsx! { + FSSTInfo { array } + } + } else if encoding == DictEncoding::ID { + // Show dictionary size, value sample, histogram + let array = SharedPtr(Arc::new(DictArray::try_from(array)?)); + rsx! { + DictInfo { array } + } + } else { + // Empty component + rsx! {} + } +} diff --git a/src/main.rs b/src/main.rs index 00e5f26..37659aa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ -use std::collections::VecDeque; use std::sync::Arc; +use std::{collections::VecDeque, ops::Deref}; use bytes::Bytes; use components::{array::ArrayView, AppHeader, ErrorMessage}; @@ -12,7 +12,6 @@ use vortex::{ }; mod components; -mod vortex_file; const FAVICON: Asset = asset!("/assets/favicon.ico"); const MAIN_CSS: Asset = asset!("/assets/main.css"); @@ -40,7 +39,7 @@ fn Home() -> Element { let mut read_error = use_signal::>(|| None); // Push the latest history for each of these elements. - let mut history_stack: Signal> = use_signal(VecDeque::new); + let mut history_stack: Signal>> = use_signal(VecDeque::new); let read_files = move |file_engine: Arc| async move { file_name.set(file_engine.files()[0].clone()); @@ -61,9 +60,7 @@ fn Home() -> Element { Ok(array) => { *read_error.write() = None; // Push onto the front of the stack. - history_stack.write().push_front(SharedArrayData { - inner: Arc::new(array), - }); + history_stack.write().push_front(SharedPtr(Arc::new(array))); } Err(err) => *read_error.write() = Some(err.to_string()), }, @@ -102,14 +99,25 @@ fn Home() -> Element { } } +/// Wrapper around any Arc to make it usable as a Dioxus Prop. +/// +/// In Dioxus, all props need must be `PartialEq`. Not all of the Vortex types implement that trait, +/// so this makes it easy for us to pass anything as a component prop at the expense of an added allocation. #[derive(Clone)] -pub struct SharedArrayData { - inner: Arc, +pub struct SharedPtr(pub Arc); + +// Deref impl allowing us to call immutable methods on `T` directly without unwrapping. +impl Deref for SharedPtr { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.0.deref() + } } -// impl PartialEq so we can use it as a Prop. -impl PartialEq for SharedArrayData { +// Impl PartialEq that ensures two SharedPtr's have the same pointee. +impl PartialEq for SharedPtr { fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.inner, &other.inner) + Arc::ptr_eq(&self.0, &other.0) } } diff --git a/src/vortex_file.rs b/src/vortex_file.rs deleted file mode 100644 index 177bf8f..0000000 --- a/src/vortex_file.rs +++ /dev/null @@ -1,11 +0,0 @@ -use dioxus::prelude::*; - -use crate::SharedArrayData; - -#[component] -pub fn VortexArray(array: SharedArrayData) -> Element { - let encoding = array.inner.encoding().id().to_string(); - rsx! { - "Array with encoding: {encoding}" - } -}