mod tensor;
mod spatial;
mod text;
mod timestamp;
mod table;
pub use tensor::Tensor;
pub use spatial::{Geometry, Point, Point3D, BoundingBox, BoundingBox3D};
pub use text::{Text, TextDoc};
pub use timestamp::Timestamp;
pub use table::{TableSchema, ColumnDef, ColumnType, IndexDef, IndexType, TableType, TTLDuration};
use serde::{Deserialize, Serialize, Deserializer, Serializer};
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq)]
pub struct ArcVec(pub Arc<Vec<f32>>);
impl ArcVec {
pub fn new(vec: Vec<f32>) -> Self {
ArcVec(Arc::new(vec))
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn iter(&self) -> std::slice::Iter<'_, f32> {
self.0.iter()
}
pub fn to_vec(&self) -> Vec<f32> {
(*self.0).clone()
}
pub fn as_slice(&self) -> &[f32] {
self.0.as_ref()
}
}
impl Serialize for ArcVec {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.as_ref().serialize(serializer)
}
}
impl<'de> Deserialize<'de> for ArcVec {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let vec = Vec::<f32>::deserialize(deserializer)?;
Ok(ArcVec(Arc::new(vec)))
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Value {
Integer(i64),
Float(f64),
Bool(bool),
Text(String),
Vector(ArcVec),
Tensor(Tensor),
Spatial(Geometry),
TextDoc(Text),
Timestamp(Timestamp),
Null,
}
impl PartialOrd for Value {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match (self, other) {
(Value::Integer(a), Value::Integer(b)) => a.partial_cmp(b),
(Value::Float(a), Value::Float(b)) => a.partial_cmp(b),
(Value::Text(a), Value::Text(b)) => a.partial_cmp(b),
(Value::Bool(a), Value::Bool(b)) => a.partial_cmp(b),
(Value::Timestamp(a), Value::Timestamp(b)) => a.partial_cmp(b),
(Value::Integer(a), Value::Float(b)) => (*a as f64).partial_cmp(b),
(Value::Float(a), Value::Integer(b)) => a.partial_cmp(&(*b as f64)),
(Value::Timestamp(a), Value::Integer(b)) => a.as_micros().partial_cmp(b),
(Value::Integer(a), Value::Timestamp(b)) => a.partial_cmp(&b.as_micros()),
(Value::Timestamp(a), Value::Float(b)) => (a.as_micros() as f64).partial_cmp(b),
(Value::Float(a), Value::Timestamp(b)) => a.partial_cmp(&(b.as_micros() as f64)),
_ => None,
}
}
}
impl PartialEq for Value {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Value::Integer(a), Value::Integer(b)) => a == b,
(Value::Float(a), Value::Float(b)) => a == b,
(Value::Text(a), Value::Text(b)) => a == b,
(Value::Bool(a), Value::Bool(b)) => a == b,
(Value::Null, Value::Null) => true,
(Value::Timestamp(a), Value::Timestamp(b)) => a == b,
(Value::Integer(a), Value::Float(b)) => (*a as f64) == *b,
(Value::Float(a), Value::Integer(b)) => *a == (*b as f64),
_ => false,
}
}
}
impl Eq for Value {}
impl std::hash::Hash for Value {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
std::mem::discriminant(self).hash(state);
match self {
Value::Integer(i) => i.hash(state),
Value::Float(f) => f.to_bits().hash(state),
Value::Text(s) => s.hash(state),
Value::Bool(b) => b.hash(state),
Value::Timestamp(t) => t.as_micros().hash(state),
Value::Null => {}
other => format!("{:?}", other).hash(state),
}
}
}
impl Value {
pub fn to_hash_key(&self) -> String {
match self {
Value::Integer(i) => format!("i:{}", i),
Value::Float(f) => format!("f:{}", f.to_bits()),
Value::Text(s) => format!("t:{}", s),
Value::Bool(b) => format!("b:{}", b),
Value::Timestamp(t) => format!("ts:{}", t.as_micros()),
_ => format!("{:?}", self),
}
}
}
pub type Row = Vec<Value>;
pub type SqlRow = std::collections::HashMap<String, Value>;
pub type RowId = u64;
pub type PartitionId = u8;