Skip to main content

scirs2_io/tiledb/
types.rs

1//! TileDB type definitions.
2//!
3//! Core types for the TileDB array storage engine, supporting both dense
4//! and sparse multidimensional arrays with configurable tiling and compression.
5
6/// Configuration for a TileDB array.
7#[derive(Debug, Clone)]
8pub struct TileDBConfig {
9    /// Maximum number of elements per tile.
10    pub tile_capacity: usize,
11    /// Compression algorithm to use for tiles.
12    pub compression: Compression,
13    /// Tile memory order.
14    pub tile_order: TileOrder,
15    /// Cell order within tiles.
16    pub cell_order: TileOrder,
17}
18
19impl Default for TileDBConfig {
20    fn default() -> Self {
21        Self {
22            tile_capacity: 1024,
23            compression: Compression::None,
24            tile_order: TileOrder::RowMajor,
25            cell_order: TileOrder::RowMajor,
26        }
27    }
28}
29
30/// Compression algorithm for tiles.
31#[non_exhaustive]
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum Compression {
34    /// No compression.
35    None,
36    /// Run-length encoding.
37    Rle,
38    /// Dictionary encoding.
39    Dictionary,
40    /// Delta encoding for sorted data.
41    Delta,
42}
43
44/// Array schema: either dense or sparse.
45#[non_exhaustive]
46#[derive(Debug, Clone)]
47pub enum ArraySchema {
48    /// Dense array with fixed-size dimensions.
49    Dense {
50        /// Dimensions defining the array shape and tiling.
51        dimensions: Vec<Dimension>,
52        /// Attributes stored at each cell.
53        attributes: Vec<Attribute>,
54    },
55    /// Sparse array with variable-occupancy cells.
56    Sparse {
57        /// Dimensions defining the coordinate space.
58        dimensions: Vec<Dimension>,
59        /// Attributes stored at each occupied cell.
60        attributes: Vec<Attribute>,
61    },
62}
63
64impl ArraySchema {
65    /// Return the dimensions of this schema.
66    pub fn dimensions(&self) -> &[Dimension] {
67        match self {
68            ArraySchema::Dense { dimensions, .. } => dimensions,
69            ArraySchema::Sparse { dimensions, .. } => dimensions,
70        }
71    }
72
73    /// Return the attributes of this schema.
74    pub fn attributes(&self) -> &[Attribute] {
75        match self {
76            ArraySchema::Dense { attributes, .. } => attributes,
77            ArraySchema::Sparse { attributes, .. } => attributes,
78        }
79    }
80
81    /// Return true if this is a dense schema.
82    pub fn is_dense(&self) -> bool {
83        matches!(self, ArraySchema::Dense { .. })
84    }
85}
86
87/// A single dimension in a TileDB array.
88#[derive(Debug, Clone)]
89pub struct Dimension {
90    /// Dimension name.
91    pub name: String,
92    /// Domain bounds (inclusive min, inclusive max).
93    pub domain: (f64, f64),
94    /// Tile extent along this dimension.
95    pub tile_extent: f64,
96}
97
98impl Dimension {
99    /// Create a new dimension.
100    pub fn new(name: &str, domain: (f64, f64), tile_extent: f64) -> Self {
101        Self {
102            name: name.to_string(),
103            domain,
104            tile_extent,
105        }
106    }
107
108    /// Return the number of cells in this dimension.
109    pub fn num_cells(&self) -> usize {
110        let span = self.domain.1 - self.domain.0 + 1.0;
111        if span <= 0.0 {
112            0
113        } else {
114            span as usize
115        }
116    }
117
118    /// Return the number of tiles along this dimension.
119    pub fn num_tiles(&self) -> usize {
120        let cells = self.num_cells() as f64;
121        if self.tile_extent <= 0.0 {
122            1
123        } else {
124            (cells / self.tile_extent).ceil() as usize
125        }
126    }
127}
128
129/// An attribute stored at each cell of the array.
130#[derive(Debug, Clone)]
131pub struct Attribute {
132    /// Attribute name.
133    pub name: String,
134    /// Data type of this attribute.
135    pub dtype: DataType,
136}
137
138impl Attribute {
139    /// Create a new attribute.
140    pub fn new(name: &str, dtype: DataType) -> Self {
141        Self {
142            name: name.to_string(),
143            dtype,
144        }
145    }
146}
147
148/// Supported data types for TileDB attributes.
149#[non_exhaustive]
150#[derive(Debug, Clone, Copy, PartialEq, Eq)]
151pub enum DataType {
152    /// 64-bit floating point.
153    Float64,
154    /// 32-bit floating point.
155    Float32,
156    /// 64-bit signed integer.
157    Int64,
158    /// 32-bit signed integer.
159    Int32,
160    /// Unsigned 8-bit integer (byte).
161    UInt8,
162}
163
164/// Memory layout order for tiles and cells.
165#[non_exhaustive]
166#[derive(Debug, Clone, Copy, PartialEq, Eq)]
167pub enum TileOrder {
168    /// Row-major (C-style) order.
169    RowMajor,
170    /// Column-major (Fortran-style) order.
171    ColMajor,
172    /// Hilbert space-filling curve order (for sparse arrays).
173    Hilbert,
174}
175
176/// Errors specific to TileDB operations.
177#[derive(Debug)]
178#[non_exhaustive]
179pub enum TileDBError {
180    /// I/O error.
181    Io(std::io::Error),
182    /// Schema mismatch or invalid schema.
183    SchemaError(String),
184    /// Out-of-bounds access.
185    OutOfBounds(String),
186    /// Invalid query or configuration.
187    InvalidQuery(String),
188    /// General error.
189    Other(String),
190}
191
192impl std::fmt::Display for TileDBError {
193    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194        match self {
195            TileDBError::Io(e) => write!(f, "TileDB I/O error: {e}"),
196            TileDBError::SchemaError(msg) => write!(f, "TileDB schema error: {msg}"),
197            TileDBError::OutOfBounds(msg) => write!(f, "TileDB out of bounds: {msg}"),
198            TileDBError::InvalidQuery(msg) => write!(f, "TileDB invalid query: {msg}"),
199            TileDBError::Other(msg) => write!(f, "TileDB error: {msg}"),
200        }
201    }
202}
203
204impl std::error::Error for TileDBError {
205    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
206        match self {
207            TileDBError::Io(e) => Some(e),
208            _ => None,
209        }
210    }
211}
212
213impl From<std::io::Error> for TileDBError {
214    fn from(e: std::io::Error) -> Self {
215        TileDBError::Io(e)
216    }
217}
218
219impl From<TileDBError> for crate::error::IoError {
220    fn from(e: TileDBError) -> Self {
221        crate::error::IoError::Other(format!("{e}"))
222    }
223}