mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-06 13:22:57 +00:00
feat: Implement PrimitiveType and PrimitiveVector
This commit is contained in:
@@ -1 +1,7 @@
|
||||
/// Bytes buffer.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Bytes(Vec<u8>);
|
||||
|
||||
/// String buffer with arbitrary encoding.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct StringBytes(Vec<u8>);
|
||||
|
||||
@@ -6,3 +6,6 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
common = { path = "../common" }
|
||||
arrow2 = "0.10"
|
||||
paste = "1.0"
|
||||
|
||||
18
src/datatypes/src/data_type.rs
Normal file
18
src/datatypes/src/data_type.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::type_id::LogicalTypeId;
|
||||
use crate::value::Value;
|
||||
|
||||
/// Data type abstraction.
|
||||
pub trait DataType: std::fmt::Debug {
|
||||
/// Name of this data type.
|
||||
fn name(&self) -> &str;
|
||||
|
||||
/// Returns id of the Logical data type.
|
||||
fn logical_type_id(&self) -> LogicalTypeId;
|
||||
|
||||
/// Returns the default value of this type.
|
||||
fn default_value(&self) -> Value;
|
||||
}
|
||||
|
||||
pub type DataTypeRef = Arc<dyn DataType>;
|
||||
@@ -1 +1,6 @@
|
||||
mod data_type;
|
||||
mod schema;
|
||||
pub mod type_id;
|
||||
mod types;
|
||||
pub mod value;
|
||||
pub mod vectors;
|
||||
|
||||
30
src/datatypes/src/type_id.rs
Normal file
30
src/datatypes/src/type_id.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
/// Unique identifier for logical data type.
|
||||
#[derive(Debug)]
|
||||
pub enum LogicalTypeId {
|
||||
Null,
|
||||
|
||||
// Numeric types:
|
||||
Boolean,
|
||||
Int8,
|
||||
Int16,
|
||||
Int32,
|
||||
Int64,
|
||||
UInt8,
|
||||
UInt16,
|
||||
UInt32,
|
||||
UInt64,
|
||||
Float32,
|
||||
Float64,
|
||||
|
||||
// String types:
|
||||
String,
|
||||
Binary,
|
||||
|
||||
// Date & Time types:
|
||||
/// Date representing the elapsed time since UNIX epoch (1970-01-01)
|
||||
/// in days (32 bits).
|
||||
Date,
|
||||
/// Datetime representing the elapsed time since UNIX epoch (1970-01-01) in
|
||||
/// seconds/milliseconds/microseconds/nanoseconds, determined by precision.
|
||||
DateTime,
|
||||
}
|
||||
2
src/datatypes/src/types.rs
Normal file
2
src/datatypes/src/types.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod primitive_traits;
|
||||
pub mod primitive_type;
|
||||
28
src/datatypes/src/types/primitive_traits.rs
Normal file
28
src/datatypes/src/types/primitive_traits.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use arrow2::types::NativeType;
|
||||
|
||||
use crate::value::Value;
|
||||
|
||||
/// Primitive type.
|
||||
pub trait Primitive: PartialOrd + Default + Clone + Copy + Into<Value> + NativeType {
|
||||
/// Largest numeric type this primitive type can be cast to.
|
||||
type LargestType: Primitive;
|
||||
}
|
||||
|
||||
macro_rules! impl_primitive {
|
||||
($Type:ident, $LargestType: ident) => {
|
||||
impl Primitive for $Type {
|
||||
type LargestType = $LargestType;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_primitive!(u8, u64);
|
||||
impl_primitive!(u16, u64);
|
||||
impl_primitive!(u32, u64);
|
||||
impl_primitive!(u64, u64);
|
||||
impl_primitive!(i8, i64);
|
||||
impl_primitive!(i16, i64);
|
||||
impl_primitive!(i32, i64);
|
||||
impl_primitive!(i64, i64);
|
||||
impl_primitive!(f32, f64);
|
||||
impl_primitive!(f64, f64);
|
||||
73
src/datatypes/src/types/primitive_type.rs
Normal file
73
src/datatypes/src/types/primitive_type.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::data_type::{DataType, DataTypeRef};
|
||||
use crate::type_id::LogicalTypeId;
|
||||
use crate::types::primitive_traits::Primitive;
|
||||
use crate::value::Value;
|
||||
|
||||
pub struct PrimitiveType<T: Primitive> {
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Primitive> PrimitiveType<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new [DataTypeRef] from a primitive type.
|
||||
pub trait CreateDataType {
|
||||
fn create_data_type() -> DataTypeRef;
|
||||
}
|
||||
|
||||
macro_rules! impl_create_data_type {
|
||||
($Type:ident) => {
|
||||
paste::paste! {
|
||||
impl CreateDataType for $Type {
|
||||
fn create_data_type() -> DataTypeRef {
|
||||
Arc::new(PrimitiveType::<$Type>::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_numeric {
|
||||
($Type:ident, $TypeId:ident) => {
|
||||
impl DataType for PrimitiveType<$Type> {
|
||||
fn name(&self) -> &str {
|
||||
stringify!($TypeId)
|
||||
}
|
||||
|
||||
fn logical_type_id(&self) -> LogicalTypeId {
|
||||
LogicalTypeId::$TypeId
|
||||
}
|
||||
|
||||
fn default_value(&self) -> Value {
|
||||
$Type::default().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PrimitiveType<$Type> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{}", self.name())
|
||||
}
|
||||
}
|
||||
|
||||
impl_create_data_type!($Type);
|
||||
};
|
||||
}
|
||||
|
||||
impl_numeric!(u8, UInt8);
|
||||
impl_numeric!(u16, UInt16);
|
||||
impl_numeric!(u32, UInt32);
|
||||
impl_numeric!(u64, UInt64);
|
||||
impl_numeric!(i8, Int8);
|
||||
impl_numeric!(i16, Int16);
|
||||
impl_numeric!(i32, Int32);
|
||||
impl_numeric!(i64, Int64);
|
||||
impl_numeric!(f32, Float32);
|
||||
impl_numeric!(f64, Float64);
|
||||
59
src/datatypes/src/value.rs
Normal file
59
src/datatypes/src/value.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use common::{Bytes, StringBytes};
|
||||
|
||||
/// Value holds a single arbitrary value of any [DataType](crate::data_type::DataType).
|
||||
#[derive(Debug)]
|
||||
pub enum Value {
|
||||
Null,
|
||||
|
||||
// Numeric types:
|
||||
Boolean(bool),
|
||||
UInt8(u8),
|
||||
UInt16(u16),
|
||||
UInt32(u32),
|
||||
UInt64(u64),
|
||||
Int8(i8),
|
||||
Int16(i16),
|
||||
Int32(i32),
|
||||
Int64(i64),
|
||||
Float32(f32),
|
||||
Float64(f64),
|
||||
|
||||
// String types:
|
||||
String(StringBytes),
|
||||
Binary(Bytes),
|
||||
|
||||
// Date & Time types:
|
||||
Date(i32),
|
||||
DateTime(i64),
|
||||
}
|
||||
|
||||
macro_rules! impl_from {
|
||||
($Variant:ident, $Type:ident) => {
|
||||
impl From<$Type> for Value {
|
||||
fn from(value: $Type) -> Self {
|
||||
Value::$Variant(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<$Type>> for Value {
|
||||
fn from(value: Option<$Type>) -> Self {
|
||||
match value {
|
||||
Some(v) => Value::$Variant(v),
|
||||
None => Value::Null,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_from!(Boolean, bool);
|
||||
impl_from!(UInt8, u8);
|
||||
impl_from!(UInt16, u16);
|
||||
impl_from!(UInt32, u32);
|
||||
impl_from!(UInt64, u64);
|
||||
impl_from!(Int8, i8);
|
||||
impl_from!(Int16, i16);
|
||||
impl_from!(Int32, i32);
|
||||
impl_from!(Int64, i64);
|
||||
impl_from!(Float32, f32);
|
||||
impl_from!(Float64, f64);
|
||||
26
src/datatypes/src/vectors.rs
Normal file
26
src/datatypes/src/vectors.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
pub mod primitive;
|
||||
|
||||
use std::any::Any;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::data_type::DataTypeRef;
|
||||
|
||||
/// Vector of data values.
|
||||
pub trait Vector: Send + Sync {
|
||||
/// Returns the data type of the vector.
|
||||
fn data_type(&self) -> DataTypeRef;
|
||||
|
||||
/// Returns the vector as [Any](std::any::Any) so that it can be
|
||||
/// downcast to a specific implementation.
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
|
||||
/// Returns number of elements in the vector.
|
||||
fn len(&self) -> usize;
|
||||
|
||||
/// Returns whether the vector is empty.
|
||||
fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
}
|
||||
|
||||
pub type VectorRef = Arc<dyn Vector>;
|
||||
33
src/datatypes/src/vectors/primitive.rs
Normal file
33
src/datatypes/src/vectors/primitive.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
use std::any::Any;
|
||||
|
||||
use arrow2::array::PrimitiveArray;
|
||||
|
||||
use crate::data_type::DataTypeRef;
|
||||
use crate::types::primitive_traits::Primitive;
|
||||
use crate::types::primitive_type::CreateDataType;
|
||||
use crate::vectors::Vector;
|
||||
|
||||
/// Vector for primitive data types.
|
||||
pub struct PrimitiveVector<T: Primitive> {
|
||||
array: PrimitiveArray<T>,
|
||||
}
|
||||
|
||||
impl<T: Primitive> PrimitiveVector<T> {
|
||||
pub fn new(array: PrimitiveArray<T>) -> Self {
|
||||
Self { array }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Primitive + CreateDataType> Vector for PrimitiveVector<T> {
|
||||
fn data_type(&self) -> DataTypeRef {
|
||||
T::create_data_type()
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.array.len()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user