From f4fbdcae16340a134240be554e679d14c7f29675 Mon Sep 17 00:00:00 2001 From: Sayan Nandan Date: Sat, 11 Sep 2021 08:03:40 -0700 Subject: [PATCH] Fix encoding check correctness in actions --- server/src/actions/del.rs | 9 ++------- server/src/actions/exists.rs | 9 ++------- server/src/actions/lists/mod.rs | 10 +++++----- server/src/actions/mget.rs | 8 ++------ server/src/actions/mpop.rs | 8 ++------ server/src/actions/set.rs | 6 +++--- server/src/actions/update.rs | 5 +++-- server/src/corestore/booltable.rs | 31 +++++++++++++++---------------- server/src/kvengine/encoding.rs | 14 ++++++++++++++ 9 files changed, 48 insertions(+), 52 deletions(-) diff --git a/server/src/actions/del.rs b/server/src/actions/del.rs index b33f16f8..63f781b3 100644 --- a/server/src/actions/del.rs +++ b/server/src/actions/del.rs @@ -29,7 +29,7 @@ use crate::corestore::table::DataModel; use crate::dbnet::connection::prelude::*; -use crate::kvengine::KVTable; +use crate::kvengine::{encoding::ENCODING_LUT_ITER, KVTable}; use crate::util::compiler; action!( @@ -42,12 +42,7 @@ action!( let table = get_tbl!(handle, con); macro_rules! remove { ($engine:expr) => {{ - let encoding_is_okay = if $engine.kve_key_encoded() { - let encoder = $engine.kve_get_key_encoder(); - act.as_ref().all(|k| encoder.is_ok(k)) - } else { - true - }; + let encoding_is_okay = ENCODING_LUT_ITER[$engine.kve_key_encoded()](act.as_ref()); if compiler::likely(encoding_is_okay) { let done_howmany: Option; { diff --git a/server/src/actions/exists.rs b/server/src/actions/exists.rs index f51413a5..8dbbd7cd 100644 --- a/server/src/actions/exists.rs +++ b/server/src/actions/exists.rs @@ -29,7 +29,7 @@ use crate::corestore::table::DataModel; use crate::dbnet::connection::prelude::*; -use crate::kvengine::KVTable; +use crate::kvengine::{encoding::ENCODING_LUT_ITER, KVTable}; use crate::queryengine::ActionIter; use crate::util::compiler; @@ -40,12 +40,7 @@ action!( let mut how_many_of_them_exist = 0usize; macro_rules! exists { ($engine:expr) => {{ - let encoding_is_okay = if $engine.kve_key_encoded() { - let encoder = $engine.kve_get_key_encoder(); - act.as_ref().all(|k| encoder.is_ok(k)) - } else { - true - }; + let encoding_is_okay = ENCODING_LUT_ITER[$engine.kve_key_encoded()](act.as_ref()); if compiler::likely(encoding_is_okay) { act.for_each(|key| { if $engine.kve_exists(key) { diff --git a/server/src/actions/lists/mod.rs b/server/src/actions/lists/mod.rs index f610ff1d..f5882aca 100644 --- a/server/src/actions/lists/mod.rs +++ b/server/src/actions/lists/mod.rs @@ -24,8 +24,8 @@ * */ -use crate::corestore::booltable::BoolTable; -use crate::corestore::booltable::NicheLUT; +use crate::corestore::booltable::BytesBoolTable; +use crate::corestore::booltable::BytesNicheLUT; use crate::corestore::table::DataModel; use crate::corestore::Data; use crate::dbnet::connection::prelude::*; @@ -43,9 +43,9 @@ 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); +const OKAY_OVW_BLUT: BytesBoolTable = BytesBoolTable::new(groups::OKAY, groups::OVERWRITE_ERR); +const OKAY_BADIDX_NIL_NLUT: BytesNicheLUT = + BytesNicheLUT::new(groups::NIL, groups::OKAY, groups::LISTMAP_BAD_INDEX); macro_rules! listmap { ($tbl:expr, $con:expr) => { diff --git a/server/src/actions/mget.rs b/server/src/actions/mget.rs index c9519552..eaca73da 100644 --- a/server/src/actions/mget.rs +++ b/server/src/actions/mget.rs @@ -25,6 +25,7 @@ */ use crate::dbnet::connection::prelude::*; +use crate::kvengine::{encoding::ENCODING_LUT_ITER, KVTable}; use crate::queryengine::ActionIter; use crate::resp::writer::TypedArrayWriter; use crate::util::compiler; @@ -35,12 +36,7 @@ action!( fn mget(handle: &crate::corestore::Corestore, con: &mut T, act: ActionIter<'a>) { crate::err_if_len_is!(act, con, eq 0); let kve = kve!(con, handle); - let encoding_is_okay = if kve.needs_key_encoding() { - true - } else { - let encoder = kve.get_key_encoder(); - act.as_ref().all(|k| encoder.is_ok(k)) - }; + let encoding_is_okay = ENCODING_LUT_ITER[kve.kve_key_encoded()](act.as_ref()); if compiler::likely(encoding_is_okay) { let mut writer = unsafe { // SAFETY: We are getting the value type ourselves diff --git a/server/src/actions/mpop.rs b/server/src/actions/mpop.rs index 7ee38d2b..fbfb9591 100644 --- a/server/src/actions/mpop.rs +++ b/server/src/actions/mpop.rs @@ -26,6 +26,7 @@ use crate::corestore; use crate::dbnet::connection::prelude::*; +use crate::kvengine::encoding::ENCODING_LUT_ITER; use crate::protocol::responses; use crate::queryengine::ActionIter; use crate::resp::writer::TypedArrayWriter; @@ -37,12 +38,7 @@ action!( err_if_len_is!(act, con, eq 0); if registry::state_okay() { let kve = kve!(con, handle); - let encoding_is_okay = if kve.needs_key_encoding() { - true - } else { - let encoder = kve.get_key_encoder(); - act.as_ref().all(|k| encoder.is_ok(k)) - }; + let encoding_is_okay = ENCODING_LUT_ITER[kve.needs_key_encoding()](act.as_ref()); if compiler::likely(encoding_is_okay) { let mut writer = unsafe { // SAFETY: We have verified the tsymbol ourselves diff --git a/server/src/actions/set.rs b/server/src/actions/set.rs index cbe55131..5b09e6bc 100644 --- a/server/src/actions/set.rs +++ b/server/src/actions/set.rs @@ -28,13 +28,13 @@ //! This module provides functions to work with `SET` queries use crate::corestore; -use crate::corestore::booltable::NicheLUT; +use crate::corestore::booltable::BytesNicheLUT; use crate::dbnet::connection::prelude::*; use crate::queryengine::ActionIter; use corestore::Data; -const SET_NLUT: NicheLUT = - NicheLUT::new(groups::ENCODING_ERROR, groups::OKAY, groups::OVERWRITE_ERR); +const SET_NLUT: BytesNicheLUT = + BytesNicheLUT::new(groups::ENCODING_ERROR, groups::OKAY, groups::OVERWRITE_ERR); action!( /// Run a `SET` query diff --git a/server/src/actions/update.rs b/server/src/actions/update.rs index 1b8ca340..ba5d8ac3 100644 --- a/server/src/actions/update.rs +++ b/server/src/actions/update.rs @@ -28,11 +28,12 @@ //! This module provides functions to work with `UPDATE` queries //! -use crate::corestore::booltable::NicheLUT; +use crate::corestore::booltable::BytesNicheLUT; use crate::corestore::Data; use crate::dbnet::connection::prelude::*; -const UPDATE_NLUT: NicheLUT = NicheLUT::new(groups::ENCODING_ERROR, groups::OKAY, groups::NIL); +const UPDATE_NLUT: BytesNicheLUT = + BytesNicheLUT::new(groups::ENCODING_ERROR, groups::OKAY, groups::NIL); action!( /// Run an `UPDATE` query diff --git a/server/src/corestore/booltable.rs b/server/src/corestore/booltable.rs index 4221b253..91c81dc5 100644 --- a/server/src/corestore/booltable.rs +++ b/server/src/corestore/booltable.rs @@ -26,22 +26,25 @@ use core::ops::Index; +pub type BytesBoolTable = BoolTable<&'static [u8]>; +pub type BytesNicheLUT = NicheLUT<&'static [u8]>; + /// A two-value boolean LUT -pub struct BoolTable { - base: [&'static [u8]; 2], +pub struct BoolTable { + base: [T; 2], } -impl BoolTable { +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 { + pub const fn new(if_true: T, if_false: T) -> Self { Self { base: [if_false, if_true], } } } -impl Index for BoolTable { - type Output = &'static [u8]; +impl Index for BoolTable { + type Output = T; fn index(&self, index: bool) -> &Self::Output { unsafe { &*self.base.as_ptr().add(index as usize) } } @@ -51,17 +54,13 @@ impl Index for BoolTable { /// structure /// /// **Warning:** This is a terrible opt and only works on the Rust ABI -pub struct NicheLUT { - base: [&'static [u8]; 3], +pub struct NicheLUT { + base: [T; 3], } -impl NicheLUT { +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 { + pub const fn new(if_none: T, if_true: T, if_false: T) -> Self { Self { // 0 == S(F); 1 == S(T); 2 == NULL base: [if_false, if_true, if_none], @@ -69,8 +68,8 @@ impl NicheLUT { } } -impl Index> for NicheLUT { - type Output = &'static [u8]; +impl Index> for NicheLUT { + type Output = T; fn index(&self, idx: Option) -> &Self::Output { unsafe { &*self diff --git a/server/src/kvengine/encoding.rs b/server/src/kvengine/encoding.rs index 1b74b826..70a84799 100644 --- a/server/src/kvengine/encoding.rs +++ b/server/src/kvengine/encoding.rs @@ -54,6 +54,12 @@ * - Sayan N. (July, 2021) */ +use crate::corestore::booltable::BoolTable; +use crate::protocol::iter::BorrowedAnyArrayIter; + +pub const ENCODING_LUT_ITER: BoolTable bool> = + BoolTable::new(is_okay_encoded_iter, is_okay_no_encoding_iter); + /// This table maps bytes to character classes that helps us reduce the size of the /// transition table and generate bitmasks const UTF8_MAP_BYTE_TO_CHAR_CLASS: [u8; 256] = [ @@ -78,6 +84,14 @@ const UTF8_TRANSITION_MAP: [u8; 108] = [ 12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, ]; +pub fn is_okay_encoded_iter(mut inp: BorrowedAnyArrayIter<'_>) -> bool { + inp.all(|v| self::is_okay_encoded(v)) +} + +pub const fn is_okay_no_encoding_iter(_inp: BorrowedAnyArrayIter<'_>) -> bool { + true +} + pub fn is_okay_encoded(inp: &[u8]) -> bool { self::is_utf8(inp) }