Switch to using `next_unchecked`

next
Sayan Nandan 3 years ago
parent 831d84d65e
commit 1dfaa0e4a0

@ -37,7 +37,7 @@ action!(
get_tbl!(handle, con).truncate_table(); get_tbl!(handle, con).truncate_table();
} else { } else {
// flush the entity // flush the entity
let raw_entity = unsafe { act.next().unsafe_unwrap() }; let raw_entity = unsafe { act.next_unchecked() };
let entity = handle_entity!(con, raw_entity); let entity = handle_entity!(con, raw_entity);
get_tbl!(entity, handle, con).truncate_table(); get_tbl!(entity, handle, con).truncate_table();
} }

@ -39,7 +39,7 @@ action!(
(get_tbl!(handle, con), DEFAULT_COUNT) (get_tbl!(handle, con), DEFAULT_COUNT)
} else if act.len() == 1 { } else if act.len() == 1 {
// two args, could either be count or an entity // two args, could either be count or an entity
let nextret = unsafe { act.next().unsafe_unwrap() }; let nextret = unsafe { act.next_unchecked() };
if unsafe { nextret.get_unchecked(0) }.is_ascii_digit() { if unsafe { nextret.get_unchecked(0) }.is_ascii_digit() {
// noice, this is a number; let's try to parse it // noice, this is a number; let's try to parse it
let count = if let Ok(cnt) = String::from_utf8_lossy(nextret).parse::<usize>() { let count = if let Ok(cnt) = String::from_utf8_lossy(nextret).parse::<usize>() {

@ -43,8 +43,8 @@ action!(
// UNSAFE(@ohsayan): This is completely safe as we've already checked // UNSAFE(@ohsayan): This is completely safe as we've already checked
// that there are exactly 2 arguments // that there are exactly 2 arguments
writer.update( writer.update(
Data::copy_from_slice(act.next().unsafe_unwrap()), Data::copy_from_slice(act.next_unchecked()),
Data::copy_from_slice(act.next().unsafe_unwrap()), Data::copy_from_slice(act.next_unchecked()),
) )
} { } {
Ok(true) => Some(true), Ok(true) => Some(true),

@ -34,10 +34,16 @@ use core::ops::Deref;
use core::slice::ChunksExact; use core::slice::ChunksExact;
use core::slice::Iter; use core::slice::Iter;
/// An iterator over an [`AnyArray`] (an [`UnsafeSlice`]). The validity of the iterator is
/// left to the caller who has to guarantee:
/// - Source pointers for the unsafe slice are valid
/// - Source pointers exist as long as this iterator is used
pub struct AnyArrayIter<'a> { pub struct AnyArrayIter<'a> {
iter: Iter<'a, UnsafeSlice>, iter: Iter<'a, UnsafeSlice>,
} }
/// Same as [`AnyArrayIter`] with the exception that it directly dereferences to the actual
/// slice iterator
pub struct BorrowedAnyArrayIter<'a> { pub struct BorrowedAnyArrayIter<'a> {
iter: Iter<'a, UnsafeSlice>, iter: Iter<'a, UnsafeSlice>,
} }
@ -50,29 +56,40 @@ impl<'a> Deref for BorrowedAnyArrayIter<'a> {
} }
impl<'a> AnyArrayIter<'a> { impl<'a> AnyArrayIter<'a> {
/// Create a new `AnyArrayIter`.
///
/// ## Safety
/// - Valid source pointers
/// - Source pointers exist as long as the iterator is used
pub const unsafe fn new(iter: Iter<'a, UnsafeSlice>) -> AnyArrayIter<'a> { pub const unsafe fn new(iter: Iter<'a, UnsafeSlice>) -> AnyArrayIter<'a> {
Self { iter } Self { iter }
} }
/// Returns a [`ChunksExact`] (similar to [`ChunksExact` provided by core::slice](core::slice::ChunksExact))
pub fn chunks_exact(&'a self, chunks_exact: usize) -> ChunksExact<'a, UnsafeSlice> { pub fn chunks_exact(&'a self, chunks_exact: usize) -> ChunksExact<'a, UnsafeSlice> {
self.iter.as_ref().chunks_exact(chunks_exact) self.iter.as_ref().chunks_exact(chunks_exact)
} }
/// Returns a borrowed iterator => simply put, advancing the returned iterator does not
/// affect the base iterator owned by this object
pub fn as_ref(&'a self) -> BorrowedAnyArrayIter<'a> { pub fn as_ref(&'a self) -> BorrowedAnyArrayIter<'a> {
BorrowedAnyArrayIter { BorrowedAnyArrayIter {
iter: self.iter.as_ref().iter(), iter: self.iter.as_ref().iter(),
} }
} }
/// Returns the next value in uppercase
pub fn next_uppercase(&mut self) -> Option<Box<[u8]>> { pub fn next_uppercase(&mut self) -> Option<Box<[u8]>> {
self.iter.next().map(|v| unsafe { self.iter.next().map(|v| unsafe {
// SAFETY: Only construction is unsafe, forwarding is not // SAFETY: Only construction is unsafe, forwarding is not
v.as_slice().to_ascii_uppercase().into_boxed_slice() v.as_slice().to_ascii_uppercase().into_boxed_slice()
}) })
} }
/// Returns the next value without any checks
pub unsafe fn next_unchecked(&mut self) -> &'a [u8] { pub unsafe fn next_unchecked(&mut self) -> &'a [u8] {
match self.next() { match self.next() {
Some(s) => s, Some(s) => s,
None => unreachable_unchecked(), None => unreachable_unchecked(),
} }
} }
/// Returns the next value without any checks as an owned copy of [`Bytes`]
pub unsafe fn next_unchecked_bytes(&mut self) -> Bytes { pub unsafe fn next_unchecked_bytes(&mut self) -> Bytes {
Bytes::copy_from_slice(self.next_unchecked()) Bytes::copy_from_slice(self.next_unchecked())
} }

@ -33,7 +33,6 @@ use crate::protocol::element::UnsafeElement;
use crate::protocol::iter::AnyArrayIter; use crate::protocol::iter::AnyArrayIter;
use crate::protocol::responses; use crate::protocol::responses;
use crate::protocol::SimpleQuery; use crate::protocol::SimpleQuery;
use crate::protocol::UnsafeSlice;
use crate::{actions, admin}; use crate::{actions, admin};
use core::hint::unreachable_unchecked; use core::hint::unreachable_unchecked;
mod ddl; mod ddl;
@ -53,11 +52,10 @@ macro_rules! gen_constants_and_matches {
pub const $action: &[u8] = stringify!($action).as_bytes(); pub const $action: &[u8] = stringify!($action).as_bytes();
)* )*
} }
let mut first = match $buf.next_uppercase() { let first = match $buf.next_uppercase() {
Some(frst) => frst, Some(frst) => frst,
None => return $con.write_response(responses::groups::PACKET_ERR).await, None => return $con.write_response(responses::groups::PACKET_ERR).await,
}; };
first.make_ascii_uppercase();
match first.as_ref() { match first.as_ref() {
$( $(
tags::$action => $fns($db, $con, $buf).await?, tags::$action => $fns($db, $con, $buf).await?,
@ -105,7 +103,7 @@ where
if !buf.is_any_array() { if !buf.is_any_array() {
return con.write_response(responses::groups::WRONGTYPE_ERR).await; return con.write_response(responses::groups::WRONGTYPE_ERR).await;
} }
let bufref: Box<[UnsafeSlice]>; let bufref;
let _rawiter; let _rawiter;
let mut iter; let mut iter;
unsafe { unsafe {
@ -165,7 +163,7 @@ action! {
err_if_len_is!(act, con, not 1); err_if_len_is!(act, con, not 1);
let entity = unsafe { let entity = unsafe {
// SAFETY: Already checked len // SAFETY: Already checked len
act.next().unsafe_unwrap() act.next_unchecked()
}; };
swap_entity!(con, handle, entity); swap_entity!(con, handle, entity);
Ok(()) Ok(())

Loading…
Cancel
Save