Add branch hints to parser

next
Sayan Nandan 3 years ago
parent 6eaf580ac8
commit 2f7a2d546b

@ -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, fn() -> Regex> =
Lazy::new(|| Regex::new("^[a-zA-Z_$][a-zA-Z_$0-9]*$").unwrap());
#[cold]
#[inline(never)]
fn cold_err<T>(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
return cold_err({
let all_nonzero = model_args.into_iter().all(|v| !v.is_empty());
if all_nonzero {
// arg fun
return Err(responses::groups::TOO_MANY_ARGUMENTS);
Err(responses::groups::TOO_MANY_ARGUMENTS)
} else {
// comma fun
return Err(responses::groups::BAD_EXPRESSION);
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))
}
}
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<EntityGroup<'a>,
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<EntityGroup<'a>,
// 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))
}
}
}

Loading…
Cancel
Save