From 947327f3795816b5ae7338d4715bd22c63185b85 Mon Sep 17 00:00:00 2001 From: Sayan Date: Sat, 11 Sep 2021 19:24:54 +0530 Subject: [PATCH] Simplify response writing/handling (#222) * Use `BoolTable` to simplify resps * Fix inversion of table * Use BLUT and NLUT wherever possible --- server/src/actions/lists/mod.rs | 43 ++++---------- server/src/actions/mset.rs | 6 +- server/src/actions/mupdate.rs | 7 +-- server/src/actions/set.rs | 16 ++---- server/src/actions/update.rs | 14 ++--- server/src/corestore/booltable.rs | 95 +++++++++++++++++++++++++++++++ server/src/corestore/mod.rs | 1 + 7 files changed, 122 insertions(+), 60 deletions(-) create mode 100644 server/src/corestore/booltable.rs diff --git a/server/src/actions/lists/mod.rs b/server/src/actions/lists/mod.rs index f142db8c..f610ff1d 100644 --- a/server/src/actions/lists/mod.rs +++ b/server/src/actions/lists/mod.rs @@ -24,6 +24,8 @@ * */ +use crate::corestore::booltable::BoolTable; +use crate::corestore::booltable::NicheLUT; use crate::corestore::table::DataModel; use crate::corestore::Data; use crate::dbnet::connection::prelude::*; @@ -41,6 +43,10 @@ const REMOVE: &[u8] = "REMOVE".as_bytes(); const INSERT: &[u8] = "INSERT".as_bytes(); const POP: &[u8] = "POP".as_bytes(); +const OKAY_OVW_BLUT: BoolTable = BoolTable::new(groups::OKAY, groups::OVERWRITE_ERR); +const OKAY_BADIDX_NIL_NLUT: NicheLUT = + NicheLUT::new(groups::NIL, groups::OKAY, groups::LISTMAP_BAD_INDEX); + macro_rules! listmap { ($tbl:expr, $con:expr) => { match $tbl.get_model_ref() { @@ -78,11 +84,7 @@ action! { } else { false }; - if did { - conwrite!(con, groups::OKAY)?; - } else { - conwrite!(con, groups::OVERWRITE_ERR)?; - } + conwrite!(con, OKAY_OVW_BLUT[did])?; } else { conwrite!(con, groups::SERVER_ERR)?; } @@ -208,11 +210,7 @@ action! { } else { false }; - if okay { - conwrite!(con, groups::OKAY)?; - } else { - conwrite!(con, groups::SERVER_ERR)?; - } + conwrite!(con, OKAY_OVW_BLUT[okay])?; } PUSH => { err_if_len_is!(act, con, not 1); @@ -228,11 +226,7 @@ action! { false } }; - if okay { - conwrite!(con, groups::OKAY)?; - } else { - conwrite!(con, groups::SERVER_ERR)?; - } + conwrite!(con, OKAY_OVW_BLUT[okay])?; } REMOVE => { err_if_len_is!(act, con, not 1); @@ -247,18 +241,7 @@ action! { false } }); - match maybe_value { - Some(true) => { - // we removed the value - conwrite!(con, groups::OKAY)?; - } - Some(false) => { - conwrite!(con, groups::LISTMAP_BAD_INDEX)?; - } - None => { - conwrite!(con, groups::NIL)?; - } - } + conwrite!(con, OKAY_BADIDX_NIL_NLUT[maybe_value])?; } else { conwrite!(con, groups::SERVER_ERR)?; } @@ -278,11 +261,7 @@ action! { false } }); - match maybe_insert { - Some(true) => conwrite!(con, groups::OKAY)?, - Some(false) => conwrite!(con, groups::LISTMAP_BAD_INDEX)?, - None => conwrite!(con, groups::NIL)?, - } + conwrite!(con, OKAY_BADIDX_NIL_NLUT[maybe_insert])?; } else { conwrite!(con, groups::SERVER_ERR)?; } diff --git a/server/src/actions/mset.rs b/server/src/actions/mset.rs index 12809fa9..9b5af58b 100644 --- a/server/src/actions/mset.rs +++ b/server/src/actions/mset.rs @@ -53,9 +53,9 @@ action!( if registry::state_okay() { let mut didmany = 0; while let (Some(key), Some(val)) = (act.next(), act.next()) { - if kve.set_unchecked(Data::copy_from_slice(key), Data::copy_from_slice(val)) { - didmany += 1; - } + didmany += kve + .set_unchecked(Data::copy_from_slice(key), Data::copy_from_slice(val)) + as usize; } done_howmany = Some(didmany); } else { diff --git a/server/src/actions/mupdate.rs b/server/src/actions/mupdate.rs index 6673fd0d..f19308c8 100644 --- a/server/src/actions/mupdate.rs +++ b/server/src/actions/mupdate.rs @@ -53,10 +53,9 @@ action!( if registry::state_okay() { let mut didmany = 0; while let (Some(key), Some(val)) = (act.next(), act.next()) { - if kve.update_unchecked(Data::copy_from_slice(key), Data::copy_from_slice(val)) - { - didmany += 1; - } + didmany += kve + .update_unchecked(Data::copy_from_slice(key), Data::copy_from_slice(val)) + as usize; } done_howmany = Some(didmany); } else { diff --git a/server/src/actions/set.rs b/server/src/actions/set.rs index 3620cf7d..cbe55131 100644 --- a/server/src/actions/set.rs +++ b/server/src/actions/set.rs @@ -28,12 +28,14 @@ //! This module provides functions to work with `SET` queries use crate::corestore; +use crate::corestore::booltable::NicheLUT; use crate::dbnet::connection::prelude::*; -use crate::protocol::responses; use crate::queryengine::ActionIter; -use crate::util::compiler; use corestore::Data; +const SET_NLUT: NicheLUT = + NicheLUT::new(groups::ENCODING_ERROR, groups::OKAY, groups::OVERWRITE_ERR); + action!( /// Run a `SET` query fn set(handle: &crate::corestore::Corestore, con: &mut T, mut act: ActionIter<'a>) { @@ -54,15 +56,7 @@ action!( Err(()) => None, } }; - if let Some(did_we) = did_we { - if did_we { - con.write_response(responses::groups::OKAY).await?; - } else { - con.write_response(responses::groups::OVERWRITE_ERR).await?; - } - } else { - compiler::cold_err(con.write_response(responses::groups::ENCODING_ERROR)).await?; - } + conwrite!(con, SET_NLUT[did_we])?; } else { conwrite!(con, groups::SERVER_ERR)?; } diff --git a/server/src/actions/update.rs b/server/src/actions/update.rs index a934b556..1b8ca340 100644 --- a/server/src/actions/update.rs +++ b/server/src/actions/update.rs @@ -28,9 +28,11 @@ //! This module provides functions to work with `UPDATE` queries //! +use crate::corestore::booltable::NicheLUT; use crate::corestore::Data; use crate::dbnet::connection::prelude::*; -use crate::util::compiler; + +const UPDATE_NLUT: NicheLUT = NicheLUT::new(groups::ENCODING_ERROR, groups::OKAY, groups::NIL); action!( /// Run an `UPDATE` query @@ -52,15 +54,7 @@ action!( Err(()) => None, } }; - if let Some(did_we) = did_we { - if did_we { - con.write_response(responses::groups::OKAY).await?; - } else { - con.write_response(responses::groups::NIL).await?; - } - } else { - compiler::cold_err(con.write_response(responses::groups::ENCODING_ERROR)).await?; - } + conwrite!(con, UPDATE_NLUT[did_we])?; } else { conwrite!(con, groups::SERVER_ERR)?; } diff --git a/server/src/corestore/booltable.rs b/server/src/corestore/booltable.rs new file mode 100644 index 00000000..ee8aca5c --- /dev/null +++ b/server/src/corestore/booltable.rs @@ -0,0 +1,95 @@ +/* + * Created on Fri Sep 10 2021 + * + * This file is a part of Skytable + * Skytable (formerly known as TerrabaseDB or Skybase) is a free and open-source + * NoSQL database written by Sayan Nandan ("the Author") with the + * vision to provide flexibility in data modelling without compromising + * on performance, queryability or scalability. + * + * Copyright (c) 2021, Sayan Nandan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * +*/ + +use core::ops::Index; + +/// A two-value boolean LUT +pub struct BoolTable { + base: [&'static [u8]; 2], +} + +impl BoolTable { + /// Supply values in the order: `if_true` and `if_false` + pub const fn new(if_true: &'static [u8], if_false: &'static [u8]) -> Self { + Self { + base: [if_false, if_true], + } + } +} + +impl Index for BoolTable { + type Output = &'static [u8]; + fn index(&self, index: bool) -> &Self::Output { + unsafe { self.base.get_unchecked(index as usize) } + } +} + +/// A LUT based on niche values, especially built to support the `Option` optimized +/// structure +/// +/// **Warning:** This is a terrible opt and only works on the Rust ABI +pub struct NicheLUT { + base: [&'static [u8]; 3], +} + +impl NicheLUT { + /// Supply values in the following order: [`if_none`, `if_true`, `if_false`] + pub const fn new( + if_none: &'static [u8], + if_true: &'static [u8], + if_false: &'static [u8], + ) -> Self { + Self { + // 0 == S(F); 1 == S(T); 2 == NULL + base: [if_false, if_true, if_none], + } + } +} + +impl Index> for NicheLUT { + type Output = &'static [u8]; + fn index(&self, idx: Option) -> &Self::Output { + unsafe { + self.base + .get_unchecked(*(&idx as *const _ as *const u8) as usize) + } + } +} + +#[test] +fn niche_optim_sanity_test() { + let none: Option = None; + let some_t: Option = Some(true); + let some_f: Option = Some(false); + unsafe { + let r_some_f = &some_f as *const _ as *const u8; + let r_some_t = &some_t as *const _ as *const u8; + let r_none = &none as *const _ as *const u8; + assert_eq!(*r_some_f, 0); + assert_eq!(*r_some_t, 1); + assert_eq!(*r_none, 2); + } +} diff --git a/server/src/corestore/mod.rs b/server/src/corestore/mod.rs index 97133b95..c374ba89 100644 --- a/server/src/corestore/mod.rs +++ b/server/src/corestore/mod.rs @@ -47,6 +47,7 @@ use libsky::TResult; use std::sync::Arc; use tokio::io::{AsyncReadExt, AsyncWriteExt}; pub mod array; +pub mod booltable; pub mod buffers; pub mod htable; pub mod iarray;