move more operations to the operations/ folder

This commit is contained in:
Nikita Sivukhin
2025-10-09 16:18:53 +04:00
parent 7e9e102f20
commit a2f4376bd2
6 changed files with 144 additions and 152 deletions

View File

View File

@@ -1,4 +1,7 @@
pub mod concat;
pub mod deserialize;
pub mod distance_cos;
pub mod distance_l2;
pub mod serialize;
pub mod slice;
pub mod text;

View File

@@ -0,0 +1,22 @@
use crate::{
vector::vector_types::{Vector, VectorType},
Value,
};
pub fn vector_serialize(x: Vector) -> Value {
match x.vector_type {
VectorType::Float32Dense => vector_f32_serialize(x),
VectorType::Float64Dense => vector_f64_serialize(x),
}
}
fn vector_f64_serialize(x: Vector) -> Value {
let mut blob = Vec::with_capacity(x.dims * 8 + 1);
blob.extend_from_slice(&x.data);
blob.push(2);
Value::from_blob(blob)
}
fn vector_f32_serialize(x: Vector) -> Value {
Value::from_blob(x.data)
}

View File

@@ -0,0 +1,96 @@
use crate::{
vector::vector_types::{Vector, VectorType},
LimboError, Result,
};
pub fn vector_to_text(vector: &Vector) -> String {
let mut text = String::new();
text.push('[');
match vector.vector_type {
VectorType::Float32Dense => {
let data = vector.as_f32_slice();
for (i, value) in data.iter().enumerate().take(vector.dims) {
text.push_str(&value.to_string());
if i < vector.dims - 1 {
text.push(',');
}
}
}
VectorType::Float64Dense => {
let data = vector.as_f64_slice();
for (i, value) in data.iter().enumerate().take(vector.dims) {
text.push_str(&value.to_string());
if i < vector.dims - 1 {
text.push(',');
}
}
}
}
text.push(']');
text
}
/// Parse a vector in text representation into a Vector.
///
/// The format of a vector in text representation looks as follows:
///
/// ```console
/// [1.0, 2.0, 3.0]
/// ```
pub fn vector_from_text(vector_type: VectorType, text: &str) -> Result<Vector> {
let text = text.trim();
let mut chars = text.chars();
if chars.next() != Some('[') || chars.last() != Some(']') {
return Err(LimboError::ConversionError(
"Invalid vector value".to_string(),
));
}
let mut data: Vec<u8> = Vec::new();
let text = &text[1..text.len() - 1];
if text.trim().is_empty() {
return Ok(Vector {
vector_type,
dims: 0,
data,
});
}
let xs = text.split(',');
for x in xs {
let x = x.trim();
if x.is_empty() {
return Err(LimboError::ConversionError(
"Invalid vector value".to_string(),
));
}
match vector_type {
VectorType::Float32Dense => {
let x = x
.parse::<f32>()
.map_err(|_| LimboError::ConversionError("Invalid vector value".to_string()))?;
if !x.is_finite() {
return Err(LimboError::ConversionError(
"Invalid vector value".to_string(),
));
}
data.extend_from_slice(&x.to_le_bytes());
}
VectorType::Float64Dense => {
let x = x
.parse::<f64>()
.map_err(|_| LimboError::ConversionError("Invalid vector value".to_string()))?;
if !x.is_finite() {
return Err(LimboError::ConversionError(
"Invalid vector value".to_string(),
));
}
data.extend_from_slice(&x.to_le_bytes());
}
};
}
let dims = vector_type.size_to_dims(data.len());
Ok(Vector {
vector_type,
dims,
data,
})
}