Expand description
NOTICE: THE LIBRARY IS STILL EXPERIMENTAL AND VERY BUGGY. API IS INCOMPLETE AND SUBJECTED TO CHANGE. PLEASE PROCEED WITH CAUTION
This crate is an implementation of ObjectSpace - a natural progression on the idea of TupleSpace proposed by Gelernter in 1985. ObjectSpace is a data structure with the capability of holding any structure (e.g: a string, an int, and a complex struct could all lives under one ObjectSpace). It also allows retrieving a struct based on the value of a field.
This crate also provides a fully thread-safe implementation of ObjectSpace, which allows simple concurrent and distributed programming.
§API
An ObjectSpace could perform the following tasks:
write
an object to the space. E.g:space.write(test_struct)
try_read
(non-blocking),read
(blocking), andread_all
structs of a type. E.g:space.try_read::<TestStruct>()
try_take
,take
, andtake_all
to remove and returns struct of a type. E.g:space.try_take::<TestStruct>()
Notice that an ObjectSpace could hold data from any types, which means that an i64, a String, and a complex struct could all live under one space (which leads to the somewhat wordy API for retrieving items).
Additionally, by implementing ValueLookupObjectSpace
and RangeLookupObjectSpace
, an ObjectSpace could retrieve item based on the value of a field. Notice that the field must be a “basic” field: the type of the field must be either an int, a string, or a bool.
E.g: Given a TestStruct:
struct Prop {
touched: bool
}
struct TestStruct {
index: i32,
property: Prop,
}
space.try_take_by_value::<TestStruct>("property.touched", true)
will return a TestStruct
with the value true
for property.touched
. space.try_take_by_range::<TestStruct>("index", 2..10)
will return a TestStruct
with the value of index
between in the range 2..10
For further information, please read the documentation of ObjectSpace
, RangeLookupObjectSpace
, and ValueLookupObjectSpace
§TreeObjectSpace
TreeSpaceObject
is a referenced implementation of ObjectSpace
trait. It is, in essence, a concurrent HashMap of TypeId
and corresponding Entry
for each type. Each Entry
stores objects by serializing & flattening their structure, then put the values of basic fields in a BTreeMap
for efficient lookup. TreeSpaceObject
is thread-safe, which allows it to be used in concurrent and distributed settings.
§Example
Here is a program to calculate all primes up to a limit using ObjectSpace
extern crate object_space;
extern crate serde;
#[macro_use]
extern crate serde_derive;
use std::thread;
use std::env;
use std::sync::Arc;
use object_space::{ObjectSpace, ValueLookupObjectSpace, RangeLookupObjectSpace, TreeObjectSpace};
fn main() {
let mut args = env::args();
let upper_lim = 1000000;
let thread_count = 4;
// setup. add 2 & 3 just because we can
let mut n = 4;
let space = Arc::new(TreeObjectSpace::new());
space.write::<i64>(2);
space.write::<i64>(3);
// create 4 worker threads
for _ in 0..thread_count {
let space_clone = space.clone();
thread::spawn(move || {
check_numbers(space_clone);
});
}
// continue until we hit limit
while n < upper_lim {
let max = if n * n < upper_lim { n * n } else { upper_lim };
for i in 0..thread_count {
// divide work evenly between threads
let start =
n + (((max - n) as f64) / (thread_count as f64) * (i as f64)).round() as i64;
let end =
n + (((max - n) as f64) / (thread_count as f64) * ((i + 1) as f64)).round() as i64;
let clone = space.clone();
clone.write(Task {
finished: false,
start: start,
end: end,
});
}
// "joining" threads
for _ in 0..thread_count {
let clone = space.clone();
clone.take_by_value::<Task>("finished", &true);
}
n = max;
}
}
fn check_numbers(space: Arc<TreeObjectSpace>) {
loop {
let task = space.take_by_value::<Task>("finished", &false);
let max = task.end;
let min = task.start;
let primes: Vec<i64> = space.read_all::<i64>().filter(|i| i * i < max).collect();
for i in min..max {
if primes.iter().all(|prime| i % prime != 0) {
space.write(i);
}
}
space.write(Task {
finished: true,
start: min,
end: max,
});
}
}
#[derive(Serialize, Deserialize)]
struct Task {
finished: bool,
start: i64,
end: i64,
}
Structs§
- Tree
Object Space - A thread-safe reference
ObjectSpace
implementation
Traits§
- Object
Space - Basic interface of an ObjectSpace.
- Range
Lookup Object Space - An extension of
ObjectSpace
supporting retrieving structs by range of a field. - Value
Lookup Object Space - An extension of
ObjectSpace
supporting retrieving structs by value of a field.