forked from M-Labs/artiq
84 lines
2.2 KiB
Rust
84 lines
2.2 KiB
Rust
use alloc::{vec, vec::Vec, string::String, collections::btree_map::BTreeMap};
|
|
use cslice::{CSlice, AsCSlice};
|
|
use core::mem::transmute;
|
|
|
|
struct Entry {
|
|
data: Vec<i32>,
|
|
slice: CSlice<'static, i32>,
|
|
borrowed: bool
|
|
}
|
|
|
|
impl core::fmt::Debug for Entry {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
f.debug_struct("Entry")
|
|
.field("data", &self.data)
|
|
.field("borrowed", &self.borrowed)
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
pub struct Cache {
|
|
entries: BTreeMap<String, Entry>,
|
|
empty: CSlice<'static, i32>,
|
|
}
|
|
|
|
impl core::fmt::Debug for Cache {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
f.debug_struct("Cache")
|
|
.field("entries", &self.entries)
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl Cache {
|
|
pub fn new() -> Cache {
|
|
let empty_vec = vec![];
|
|
let empty = unsafe {
|
|
transmute::<CSlice<'_, i32>, CSlice<'static, i32>>(empty_vec.as_c_slice())
|
|
};
|
|
Cache { entries: BTreeMap::new(), empty }
|
|
}
|
|
|
|
pub fn get(&mut self, key: &str) -> *const CSlice<'static, i32> {
|
|
match self.entries.get_mut(key) {
|
|
None => &self.empty,
|
|
Some(ref mut entry) => {
|
|
entry.borrowed = true;
|
|
&entry.slice
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn put(&mut self, key: &str, data: &[i32]) -> Result<(), ()> {
|
|
match self.entries.get_mut(key) {
|
|
None => (),
|
|
Some(ref mut entry) => {
|
|
if entry.borrowed { return Err(()) }
|
|
entry.data = Vec::from(data);
|
|
unsafe {
|
|
entry.slice = transmute::<CSlice<'_, i32>, CSlice<'static, i32>>(
|
|
entry.data.as_c_slice());
|
|
}
|
|
return Ok(())
|
|
}
|
|
}
|
|
|
|
let data = Vec::from(data);
|
|
let slice = unsafe {
|
|
transmute::<CSlice<'_, i32>, CSlice<'static, i32>>(data.as_c_slice())
|
|
};
|
|
self.entries.insert(String::from(key), Entry {
|
|
data,
|
|
slice,
|
|
borrowed: false
|
|
});
|
|
Ok(())
|
|
}
|
|
|
|
pub unsafe fn unborrow(&mut self) {
|
|
for (_key, entry) in self.entries.iter_mut() {
|
|
entry.borrowed = false;
|
|
}
|
|
}
|
|
}
|