Container Types¶
Container types hold multiple values. RayforceDB provides both homogeneous (vectors) and heterogeneous (lists) containers.
RayVector¶
Homogeneous arrays where all elements have the same type. Vectors are the most efficient container for columnar operations.
Creating Vectors¶
use rayforce::{RayVector, RaySymbol};
// From iterator
let prices: RayVector<i64> = RayVector::from_iter([100, 200, 300, 400]);
let ratios: RayVector<f64> = RayVector::from_iter([1.5, 2.0, 3.5]);
// From symbols
let symbols: RayVector<RaySymbol> = RayVector::from_iter([
RaySymbol::new("AAPL"),
RaySymbol::new("GOOGL"),
RaySymbol::new("MSFT"),
]);
Vector Operations¶
use rayforce::RayVector;
let v: RayVector<i64> = RayVector::from_iter([10, 20, 30]);
// Length
println!("Length: {}", v.len()); // → 3
// Check if empty
if v.is_empty() {
println!("Vector is empty");
}
// Display
println!("{}", v); // → [10 20 30]
Supported Element Types¶
| Element Type | Description |
|---|---|
i64 |
64-bit integers |
f64 |
64-bit floats |
RaySymbol |
Interned symbols |
RayList¶
Heterogeneous lists that can hold any RayforceDB type. Lists are more flexible but less efficient than vectors.
Creating Lists¶
use rayforce::{RayList, RayObj};
// Empty list
let mut list = RayList::new();
// Add elements
list.push(RayObj::from(42_i64));
list.push(RayObj::from("hello"));
list.push(RayObj::from(3.14_f64));
List Operations¶
use rayforce::{RayList, RayObj};
let mut list = RayList::new();
list.push(RayObj::from(1_i64));
list.push(RayObj::from(2_i64));
list.push(RayObj::from(3_i64));
// Length
println!("Length: {}", list.len()); // → 3
// Access by index
if let Some(item) = list.get(0) {
println!("First: {}", item);
}
// Set by index
list.set(1, RayObj::from(100_i64));
// Iterate
for item in list.iter() {
println!("{}", item);
}
List from Iterator¶
use rayforce::{RayList, RayObj};
let list = RayList::from_iter([
RayObj::from(1_i64),
RayObj::from("two"),
RayObj::from(3.0_f64),
]);
RayString¶
Character strings, implemented as a vector of characters.
Creating Strings¶
use rayforce::RayString;
// From &str
let s = RayString::from("Hello, World!");
// From String
let owned = String::from("Rust");
let s = RayString::from(owned.as_str());
String Operations¶
use rayforce::RayString;
let s = RayString::from("Hello");
// Length (character count)
println!("Length: {}", s.len()); // → 5
// Convert to Rust String
let rust_string: String = s.to_string();
// Display
println!("{}", s); // → "Hello"
RayDict¶
Key-value dictionaries mapping symbols to values.
Creating Dictionaries¶
use rayforce::{RayDict, RaySymbol, RayObj};
// From pairs
let dict = RayDict::from_pairs([
(RaySymbol::new("name"), RayObj::from("Alice")),
(RaySymbol::new("age"), RayObj::from(30_i64)),
(RaySymbol::new("active"), RayObj::from(true)),
]);
Dictionary Operations¶
use rayforce::{RayDict, RaySymbol, RayObj};
let dict = RayDict::from_pairs([
(RaySymbol::new("a"), RayObj::from(1_i64)),
(RaySymbol::new("b"), RayObj::from(2_i64)),
]);
// Length
println!("Size: {}", dict.len()); // → 2
// Check if empty
if dict.is_empty() {
println!("Dict is empty");
}
// Get keys
let keys = dict.keys();
// Get values
let values = dict.values();
// Clone
let dict2 = dict.clone();
Accessing Values¶
use rayforce::{RayDict, RaySymbol, RayObj};
let dict = RayDict::from_pairs([
(RaySymbol::new("price"), RayObj::from(100_i64)),
]);
// Get by key (returns Option)
if let Some(value) = dict.get(&RaySymbol::new("price")) {
println!("Price: {}", value);
}
Type Reference Table¶
| Type | Description | Homogeneous | Mutable |
|---|---|---|---|
RayVector<T> |
Typed array | Yes | No |
RayList |
Mixed list | No | Yes |
RayString |
Character string | Yes | No |
RayDict |
Key-value map | No | No |
Performance Considerations¶
Vectors vs Lists¶
Use Vectors when: - All elements have the same type - Performing columnar operations - Memory efficiency is important - Operating on large datasets
Use Lists when: - Elements have different types - Building heterogeneous records - Flexibility is more important than performance
Memory Layout¶
Vector<i64>: [i64, i64, i64, i64] ← Contiguous memory
List: [ptr, ptr, ptr, ptr] ← Pointers to objects
Vectors store values contiguously, enabling SIMD operations and better cache performance.
Common Patterns¶
Building Data Structures¶
use rayforce::{RayList, RayVector, RayObj, RaySymbol};
// Table-like structure as list of vectors
let columns = RayList::from_iter([
RayObj::from(RayVector::<i64>::from_iter([1, 2, 3]).ptr()),
RayObj::from(RayVector::<f64>::from_iter([1.1, 2.2, 3.3]).ptr()),
]);
// Record as dict
let record = RayDict::from_pairs([
(RaySymbol::new("id"), RayObj::from(1_i64)),
(RaySymbol::new("name"), RayObj::from("Alice")),
(RaySymbol::new("score"), RayObj::from(95.5_f64)),
]);
Nested Structures¶
use rayforce::{RayList, RayObj};
// List of lists
let matrix = RayList::from_iter([
RayObj::from(RayList::from_iter([
RayObj::from(1_i64),
RayObj::from(2_i64),
]).ptr()),
RayObj::from(RayList::from_iter([
RayObj::from(3_i64),
RayObj::from(4_i64),
]).ptr()),
]);