Simplify response writing/handling (#222)

* Use `BoolTable` to simplify resps

* Fix inversion of table

* Use BLUT and NLUT wherever possible
next
Sayan 3 years ago committed by GitHub
parent b6470c3585
commit 947327f379
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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)?;
}

@ -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 {

@ -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 {

@ -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)?;
}

@ -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)?;
}

@ -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 <ohsayan@outlook.com>
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
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<bool> 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<bool>` 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<Option<bool>> for NicheLUT {
type Output = &'static [u8];
fn index(&self, idx: Option<bool>) -> &Self::Output {
unsafe {
self.base
.get_unchecked(*(&idx as *const _ as *const u8) as usize)
}
}
}
#[test]
fn niche_optim_sanity_test() {
let none: Option<bool> = None;
let some_t: Option<bool> = Some(true);
let some_f: Option<bool> = 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);
}
}

@ -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;

Loading…
Cancel
Save