From 2f7a2d546bf5dd7edec94a31a0c444750bf4c447 Mon Sep 17 00:00:00 2001 From: Sayan Nandan Date: Tue, 27 Jul 2021 12:42:50 +0530 Subject: [PATCH] Add branch hints to parser --- server/src/queryengine/parser.rs | 57 +++++++++++++++++++------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/server/src/queryengine/parser.rs b/server/src/queryengine/parser.rs index dc67d9cc..25146039 100644 --- a/server/src/queryengine/parser.rs +++ b/server/src/queryengine/parser.rs @@ -29,6 +29,7 @@ use crate::corestore::memstore::ObjectID; use crate::kvengine::encoding; use crate::protocol::responses; use crate::queryengine::ActionIter; +use crate::util::compiler; use crate::util::Unwrappable; use bytes::Bytes; use core::str; @@ -41,19 +42,25 @@ const STR: &[u8] = "str".as_bytes(); pub(super) static VALID_CONTAINER_NAME: Lazy Regex> = Lazy::new(|| Regex::new("^[a-zA-Z_$][a-zA-Z_$0-9]*$").unwrap()); +#[cold] +#[inline(never)] +fn cold_err(v: T) -> T { + v +} + pub(super) fn parse_table_args(mut act: ActionIter) -> Result<(ObjectID, u8), &'static [u8]> { let table_name = unsafe { act.next().unsafe_unwrap() }; let model_name = unsafe { act.next().unsafe_unwrap() }; - if !encoding::is_utf8(&table_name) || !encoding::is_utf8(&model_name) { + if compiler::unlikely(!encoding::is_utf8(&table_name) || !encoding::is_utf8(&model_name)) { return Err(responses::groups::ENCODING_ERROR); } let table_name_str = unsafe { str::from_utf8_unchecked(&table_name) }; let model_name_str = unsafe { str::from_utf8_unchecked(&model_name) }; - if !VALID_CONTAINER_NAME.is_match(table_name_str) { + if compiler::unlikely(!VALID_CONTAINER_NAME.is_match(table_name_str)) { return Err(responses::groups::BAD_EXPRESSION); } let splits: Vec<&str> = model_name_str.split('(').collect(); - if splits.len() != 2 { + if compiler::unlikely(splits.len() != 2) { return Err(responses::groups::BAD_EXPRESSION); } let model_name_split = unsafe { splits.get_unchecked(0) }; @@ -61,7 +68,7 @@ pub(super) fn parse_table_args(mut act: ActionIter) -> Result<(ObjectID, u8), &' // model name has to have at least one char while model args should have // atleast `)` 1 chars (for example if the model takes no arguments: `smh()`) - if model_name_split.is_empty() || model_args_split.is_empty() { + if compiler::unlikely(model_name_split.is_empty() || model_args_split.is_empty()) { return Err(responses::groups::BAD_EXPRESSION); } @@ -77,7 +84,7 @@ pub(super) fn parse_table_args(mut act: ActionIter) -> Result<(ObjectID, u8), &' != b')' }; - if non_bracketed_end { + if compiler::unlikely(non_bracketed_end) { return Err(responses::groups::BAD_EXPRESSION); } @@ -86,21 +93,25 @@ pub(super) fn parse_table_args(mut act: ActionIter) -> Result<(ObjectID, u8), &' .split(',') .map(|v| v.trim()) .collect(); - if model_args.len() != 2 { + if compiler::unlikely(model_args.len() != 2) { // nope, someone had fun with commas or they added more args // let's check if it was comma fun or if it was arg fun - let all_nonzero = model_args.into_iter().all(|v| !v.is_empty()); - if all_nonzero { - // arg fun - return Err(responses::groups::TOO_MANY_ARGUMENTS); - } else { - // comma fun - return Err(responses::groups::BAD_EXPRESSION); - } + return cold_err({ + let all_nonzero = model_args.into_iter().all(|v| !v.is_empty()); + if all_nonzero { + // arg fun + Err(responses::groups::TOO_MANY_ARGUMENTS) + } else { + // comma fun + Err(responses::groups::BAD_EXPRESSION) + } + }); } let key_ty = unsafe { model_args.get_unchecked(0) }; let val_ty = unsafe { model_args.get_unchecked(1) }; - if !VALID_CONTAINER_NAME.is_match(key_ty) || !VALID_CONTAINER_NAME.is_match(val_ty) { + if compiler::unlikely( + !VALID_CONTAINER_NAME.is_match(key_ty) || !VALID_CONTAINER_NAME.is_match(val_ty), + ) { return Err(responses::groups::BAD_EXPRESSION); } let key_ty = key_ty.as_bytes(); @@ -113,11 +124,11 @@ pub(super) fn parse_table_args(mut act: ActionIter) -> Result<(ObjectID, u8), &' _ => return Err(responses::groups::UNKNOWN_DATA_TYPE), }; - if table_name_str.len() > 64 { - return Err(responses::groups::CONTAINER_NAME_TOO_LONG); + if compiler::unlikely(table_name_str.len() > 64) { + Err(responses::groups::CONTAINER_NAME_TOO_LONG) + } else { + Ok((unsafe { ObjectID::from_slice(table_name_str) }, model_code)) } - - Ok((unsafe { ObjectID::from_slice(table_name_str) }, model_code)) } pub type EntityGroup<'a> = (Option<&'a [u8]>, Option<&'a [u8]>); @@ -128,7 +139,7 @@ pub(super) fn get_query_entity<'a>(input: &'a Bytes) -> Result, if y.len() == 1 { // just tbl let tblret = y.get_unchecked(0); - if tblret.len() > 64 || tblret.is_empty() { + if compiler::unlikely(tblret.len() > 64 || tblret.is_empty()) { Err(responses::groups::BAD_CONTAINER_NAME) } else { Ok((None, Some(tblret))) @@ -137,16 +148,16 @@ pub(super) fn get_query_entity<'a>(input: &'a Bytes) -> Result, // tbl + ns let ksret = y.get_unchecked(0); let tblret = y.get_unchecked(1); - if ksret.len() > 64 || tblret.len() > 64 { + if compiler::unlikely(ksret.len() > 64 || tblret.len() > 64) { Err(responses::groups::BAD_CONTAINER_NAME) - } else if tblret.is_empty() || ksret.is_empty() { + } else if compiler::unlikely(tblret.is_empty() || ksret.is_empty()) { Err(responses::groups::BAD_EXPRESSION) } else { Ok((Some(ksret), Some(tblret))) } } else { // something wrong - Err(responses::groups::BAD_EXPRESSION) + cold_err(Err(responses::groups::BAD_EXPRESSION)) } } }