Simplify ctx handling

Also added some misc documentation changes.
next
Sayan Nandan 9 months ago
parent c2cfbd71cc
commit d89495ab83
No known key found for this signature in database
GPG Key ID: 0EBD769024B24F0A

@ -1,5 +1,5 @@
<br/><p align="center">
<img width="150" src="assets/logo.jpg">
<a href="https://skytable.io"><img width="150" src="assets/logo.jpg"></a>
</p>
<h2 align = "center">
Skytable — A modern database for building powerful experiences

@ -1034,42 +1034,45 @@ pub(super) fn apply_and_validate<CS: ConfigurationSource>(
*/
#[cfg(test)]
thread_local! {
static CLI_SRC: std::cell::RefCell<Option<Vec<String>>> = std::cell::RefCell::new(None);
static ENV_SRC: std::cell::RefCell<Option<HashMap<String, String>>> = std::cell::RefCell::new(None);
static FILE_SRC: std::cell::RefCell<Option<String>> = std::cell::RefCell::new(None);
local! {
static CLI_SRC: Option<Vec<String>> = None;
static ENV_SRC: Option<HashMap<String, String>> = None;
static FILE_SRC: Option<String> = None;
}
#[cfg(test)]
pub(super) fn set_cli_src(cli: Vec<String>) {
CLI_SRC.with(|args| *args.borrow_mut() = Some(cli))
local_mut!(CLI_SRC, |args| *args = Some(cli))
}
#[cfg(test)]
pub(super) fn set_env_src(variables: Vec<String>) {
ENV_SRC.with(|env| {
let variables = variables
.into_iter()
.map(|var| {
var.split("=")
.map(ToString::to_string)
.collect::<Vec<String>>()
})
.map(|mut vars| (vars.remove(0), vars.remove(0)))
.collect();
*env.borrow_mut() = Some(variables);
})
local_mut!(ENV_SRC, |env| {
*env = Some(
variables
.into_iter()
.map(|var| {
var.split("=")
.map(ToString::to_string)
.collect::<Vec<String>>()
})
.map(|mut vars| (vars.remove(0), vars.remove(0)))
.collect(),
);
});
}
#[cfg(test)]
pub(super) fn set_file_src(src: &str) {
FILE_SRC.with(|s| {
s.borrow_mut().replace(src.to_string());
})
pub(super) fn set_file_src(new_src: &str) {
local_mut!(FILE_SRC, |src| *src = Some(new_src.to_string()))
}
fn get_file_from_store(filename: &str) -> RuntimeResult<String> {
let _f = filename;
let f;
#[cfg(test)]
{
f = Ok(FILE_SRC.with(|f| f.borrow().clone().unwrap()));
f = Ok(local_ref!(FILE_SRC, |f| f.clone().unwrap()));
}
#[cfg(not(test))]
{
@ -1082,17 +1085,14 @@ fn get_var_from_store(name: &str) -> Result<String, std::env::VarError> {
let var;
#[cfg(test)]
{
var = ENV_SRC.with(|venv| {
let ret = {
match venv.borrow_mut().as_mut() {
None => return Err(std::env::VarError::NotPresent),
Some(env_store) => match env_store.remove(name) {
Some(var) => Ok(var),
None => Err(std::env::VarError::NotPresent),
},
}
};
ret
var = local_mut!(ENV_SRC, |venv| {
match venv.as_mut() {
None => return Err(std::env::VarError::NotPresent),
Some(env_store) => match env_store.remove(name) {
Some(var) => Ok(var),
None => Err(std::env::VarError::NotPresent),
},
}
});
}
#[cfg(not(test))]
@ -1105,9 +1105,7 @@ fn get_cli_from_store() -> Vec<String> {
let src;
#[cfg(test)]
{
src = CLI_SRC
.with(|args| args.borrow_mut().take())
.unwrap_or(vec![]);
src = local_mut!(CLI_SRC, |args| args.take()).unwrap_or_default();
}
#[cfg(not(test))]
{

@ -24,9 +24,6 @@
*
*/
#[cfg(test)]
use std::cell::RefCell;
use {
crate::{
engine::{
@ -237,23 +234,22 @@ const fn opc(opr: TagClass, ope: AssignmentOperator) -> usize {
}
#[cfg(test)]
thread_local! {
pub(super) static ROUTE_TRACE: RefCell<Vec<&'static str>> = RefCell::new(Vec::new());
local! {
pub(super) static ROUTE_TRACE: Vec<&'static str> = Vec::new();
}
#[inline(always)]
fn input_trace(v: &'static str) {
#[cfg(test)]
{
ROUTE_TRACE.with(|rcv| rcv.borrow_mut().push(v))
local_mut!(ROUTE_TRACE, |rtrace| rtrace.push(v))
}
let _ = v;
}
#[cfg(test)]
pub fn collect_trace_path() -> Vec<&'static str> {
ROUTE_TRACE.with(|v| v.borrow().iter().cloned().collect())
local_ref!(ROUTE_TRACE, |rtrace| rtrace.iter().cloned().collect())
}
pub fn update_resp(
global: &impl GlobalInstanceLike,
update: UpdateStatement,

@ -27,9 +27,6 @@
pub(super) mod alt;
pub(in crate::engine) mod delta;
#[cfg(test)]
use std::cell::RefCell;
use {
super::index::PrimaryIndex,
crate::engine::{
@ -696,26 +693,22 @@ impl Layer {
}
#[cfg(test)]
thread_local! {
static LAYER_TRACE: RefCell<Vec<Box<str>>> = RefCell::new(Vec::new());
local! {
static LAYER_TRACE: Vec<Box<str>> = Vec::new();
}
#[inline(always)]
fn layertrace(_layer: impl ToString) {
#[cfg(test)]
{
LAYER_TRACE.with(|v| v.borrow_mut().push(_layer.to_string().into()));
local_mut!(LAYER_TRACE, |ltrace| ltrace.push(_layer.to_string().into()))
}
}
#[cfg(test)]
/// Obtain a layer trace and clear older traces
pub(super) fn layer_traces() -> Box<[Box<str>]> {
LAYER_TRACE.with(|x| {
let ret = x.borrow().iter().cloned().collect();
x.borrow_mut().clear();
ret
})
local_mut!(LAYER_TRACE, |ltrace| ltrace.drain(..).collect())
}
static VTFN: [unsafe fn(Layer, &mut Datacell) -> bool; 8] = [

@ -24,10 +24,9 @@
*
*/
#![allow(unused)]
#![allow(dead_code)]
use core::fmt;
use std::cell::RefCell;
/// The current engine context
#[derive(Debug, PartialEq, Clone, Copy)]
@ -191,7 +190,7 @@ impl LocalContext {
Self::_new(None, None)
}
fn _ctx<T>(f: impl FnOnce(&mut Self) -> T) -> T {
thread_local! { static CTX: RefCell<LocalContext> = RefCell::new(LocalContext::null()) }
CTX.with(|lctx| f(&mut lctx.borrow_mut()))
local! { static CTX: LocalContext = LocalContext::null(); }
local_mut!(CTX, f)
}
}

@ -55,11 +55,6 @@ use {
},
};
/*
HACK(@ohsayan): Until https://github.com/rust-lang/rust/issues/76560 is stabilized which is likely to take a while,
we need to settle for trait objects.
*/
#[cfg(debug_assertions)]
struct CHTMetricsData {
split: AtomicUsize,
@ -114,6 +109,36 @@ impl Drop for CHTRuntimeLog {
}
}
/*
concurrent index impl
---
This implementation borrows ideas from the research by Phil Bagwell on hash trees and concurrency[1][2]. This implementation
simplifies some of the features as described in the original paper, with some implementation ideas from contrie[3] but makes
several other custom changes for maintenance, performance and custom features tuned to the use-case for Skytable.
## Warning: High memory overhead (explanation)
This implementation unfortunately is quite bad in terms of memory efficiency because it uses full-sized nodes
instead of differentiating the nodes, for performance (reducing indirection). The original paper recommends using
differently sized nodes.
Noting this, expect signficant memory blowup. We'll also remove this implementation down the line.
This is why, I do NOT recommend its use as a daily data structure.
---
References:
[1]: Aleksandar Prokopec, Nathan Grasso Bronson, Phil Bagwell, and Martin Odersky. 2012.
Concurrent tries with efficient non-blocking snapshots. SIGPLAN Not. 47, 8 (August 2012),
151160. https://doi.org/10.1145/2370036.2145836
[2]: https://lampwww.epfl.ch/papers/idealhashtrees.pdf
[3]: https://github.com/vorner/contrie (distributed under the MIT or Apache-2.0 license)
-- Sayan (@ohsayan)
---
HACK(@ohsayan): Until https://github.com/rust-lang/rust/issues/76560 is stabilized which is likely to take a while,
we need to settle for trait objects.
*/
pub struct Node<C: Config> {
branch: [Atomic<Self>; <DefConfig as Config>::BRANCH_MX],
}

@ -55,6 +55,11 @@ use {
Second note, I'm not a big fan of the DLL and will most likely try a different approach in the future; this one
is the most convenient option for now.
This work uses some ideas from the archived linked hash map crate which is now unmaintained[1]
---
[1]: https://github.com/contain-rs/linked-hash-map (distributed under the MIT or Apache-2.0 License)
-- Sayan (@ohsayan) // Jan. 16 '23
*/

@ -395,3 +395,28 @@ macro_rules! sizeof {
::core::mem::size_of::<$ty>() * $by
};
}
macro_rules! local {
($($vis:vis static$ident:ident:$ty:ty=$expr:expr;)*)=> {::std::thread_local!{$($vis static $ident: ::std::cell::RefCell::<$ty> = ::std::cell::RefCell::new($expr);)*}};
}
macro_rules! local_mut {
($ident:ident, $call:expr) => {{
#[inline(always)]
fn _f<T, U>(v: &::std::cell::RefCell<T>, f: impl FnOnce(&mut T) -> U) -> U {
f(&mut *v.borrow_mut())
}
::std::thread::LocalKey::with(&$ident, |v| _f(v, $call))
}};
}
#[cfg(test)]
macro_rules! local_ref {
($ident:ident, $call:expr) => {{
#[inline(always)]
fn _f<T, U>(v: &::std::cell::RefCell<T>, f: impl FnOnce(&T) -> U) -> U {
f(&v.borrow())
}
::std::thread::LocalKey::with(&$ident, |v| _f(v, $call))
}};
}

Loading…
Cancel
Save