Stabilize "Except" response type impl

next
Sayan Nandan 4 years ago
parent 817eb92661
commit fc3e760c9a
No known key found for this signature in database
GPG Key ID: C31EFD7DDA12AEE0

@ -28,10 +28,10 @@ use crate::terrapipe::RespCodes;
use bytes::Bytes; use bytes::Bytes;
/// The size to skip through, dataframe bytes /// The size to skip through, dataframe bytes
type PRTuple = (usize, Vec<u8>); pub type PRTuple = (usize, Vec<u8>);
/// The bytes for the sizes (inclusive of the `#` character), the bytes for the df /// The bytes for the sizes (inclusive of the `#` character), the bytes for the df
type RGTuple = (Vec<u8>, Vec<u8>); pub type RGTuple = (Vec<u8>, Vec<u8>);
/// The metaline, metalayout and dataframe in order /// The metaline, metalayout and dataframe in order
pub type Response = (Vec<u8>, Vec<u8>, Vec<u8>); pub type Response = (Vec<u8>, Vec<u8>, Vec<u8>);

@ -23,9 +23,10 @@ use tokio::net::TcpListener;
mod coredb; mod coredb;
mod dbnet; mod dbnet;
mod diskstore; mod diskstore;
mod protocol;
mod kvengine; mod kvengine;
mod protocol;
mod queryengine; mod queryengine;
mod resputil;
use coredb::CoreDB; use coredb::CoreDB;
use dbnet::run; use dbnet::run;
use tokio::signal; use tokio::signal;

@ -20,7 +20,7 @@
*/ */
mod deserializer; mod deserializer;
use crate::queryengine::queryutil::Writable; use crate::resputil::Writable;
use bytes::{Buf, BytesMut}; use bytes::{Buf, BytesMut};
use corelib::builders::response::IntoResponse; use corelib::builders::response::IntoResponse;
use corelib::builders::response::Response; use corelib::builders::response::Response;

@ -22,12 +22,10 @@
//! # The Query Engine //! # The Query Engine
use crate::coredb::CoreDB; use crate::coredb::CoreDB;
use crate::kvengine;
use corelib::builders::response::*; use corelib::builders::response::*;
use corelib::de::DataGroup; use corelib::de::DataGroup;
use corelib::terrapipe::responses; use corelib::terrapipe::responses;
pub mod queryutil;
use crate::kvengine;
use std::mem;
mod tags { mod tags {
//! This module is a collection of tags/strings used for evaluating queries //! This module is a collection of tags/strings used for evaluating queries
//! and responses //! and responses

@ -19,12 +19,13 @@
* *
*/ */
//! Utilities for handling queries //! Utilities for generating responses, which are only used by the `server`
//! //!
use corelib::builders::response::*; use corelib::builders::{self, response::*};
use std::error::Error; use std::error::Error;
use std::future::Future; use std::future::Future;
use std::mem;
use std::pin::Pin; use std::pin::Pin;
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use tokio::io::BufWriter; use tokio::io::BufWriter;
@ -52,72 +53,87 @@ use tokio::net::TcpStream;
/// this, the `ExceptFor` type exists. Though we could've returned the count of the number of elements /// this, the `ExceptFor` type exists. Though we could've returned the count of the number of elements
/// which existed, it would not provide any information on what existed and what didn't which might be /// which existed, it would not provide any information on what existed and what didn't which might be
/// needed at times. /// needed at times.
pub struct ExceptFor(Vec<usize>); pub struct ExceptFor {
df_ext: Vec<u8>,
}
const EXCEPTFOR_CAP: usize = 10; const EXFOR_CAP: usize = 2 * 10;
impl ExceptFor { impl ExceptFor {
/// Create a new `ExceptFor` instance
pub fn new() -> Self { pub fn new() -> Self {
ExceptFor(Vec::with_capacity(EXCEPTFOR_CAP)) let mut df_ext = Vec::with_capacity(EXFOR_CAP + 2);
df_ext.push(b'^');
ExceptFor { df_ext }
} }
/// Add an index to `ExceptFor` pub fn with_space_for(howmany: usize) -> Self {
pub fn add(&mut self, idx: usize) { let mut df_ext = vec![b'^'];
self.0.push(idx); df_ext.reserve(howmany);
ExceptFor { df_ext }
} }
/// Drop the object returning the inner-vector /// This will essentially add 'idx,' to the `df_ext` field as bytes
pub fn finish_into_vec(self) -> Vec<usize> { pub fn add(&mut self, idx: usize) {
self.0 self.df_ext.extend(idx.to_string().into_bytes());
self.df_ext.push(b',');
} }
} }
impl IntoRespGroup for ExceptFor { impl IntoRespGroup for ExceptFor {
fn into_resp_group(self) -> (Vec<u8>, Vec<u8>) { fn into_resp_group(self) -> RGTuple {
let mut except_for_line = Vec::with_capacity((self.0.len() * 2) + 2); // self_len is the length of the exceptfor line in bytes
except_for_line.push(b'^'); let self_len = self.df_ext.len().to_string().into_bytes();
let mut it = self.0.into_iter().peekable(); // The size_of(self_len) + size_of('#1#<bytes>')
while let Some(item) = it.next() { let mut metalayout = Vec::with_capacity(self_len.len() + 4);
except_for_line.extend(item.to_string().into_bytes()); let mut dataframe = Vec::with_capacity(self.df_ext.len() + 3);
if it.peek().is_some() { metalayout.extend(&[b'#', b'2', b'#']);
except_for_line.push(b','); metalayout.extend(self_len);
} else { // Preallocate capacity for the dataframe: df_ext.len() + len("&1\n")
except_for_line.push(b'\n'); dataframe.extend(&[b'&', b'1', b'\n']);
} unsafe {
} // Add a newline
let mut metalayout_ext = Vec::with_capacity(EXCEPTFOR_CAP); let self_ptr = &self as *const _;
metalayout_ext.push(b'#'); let self_mut_ptr = self_ptr as *mut ExceptFor;
metalayout_ext.push(b'1'); let mut_ref = &mut (*self_mut_ptr);
metalayout_ext.push(b'#'); let _ = mem::replace(&mut mut_ref.df_ext[(*self_mut_ptr).df_ext.len() - 1], b'\n');
metalayout_ext.extend(except_for_line.len().to_string().into_bytes()); }
let dataframe_ext = [vec![b'&', b'1', b'\n'], except_for_line].concat(); dataframe.extend(self.df_ext);
(metalayout_ext, dataframe_ext) (metalayout, dataframe)
} }
} }
#[cfg(test)]
#[test]
fn test_intorespgroup_trait_impl_exceptfor() {
let mut exceptfor = ExceptFor::new();
exceptfor.add(1);
exceptfor.add(2);
let (ml, df) = exceptfor.into_resp_group();
assert_eq!("#2#5".as_bytes().to_owned(), ml);
assert_eq!("&1\n^1,2\n".as_bytes().to_owned(), df);
}
impl IntoResponse for ExceptFor { impl IntoResponse for ExceptFor {
fn into_response(self) -> Response { fn into_response(self) -> Response {
let (mut metalayout_ext, df_ext) = self.into_resp_group(); let (mut metalayout_ext, dataframe) = self.into_resp_group();
metalayout_ext.push(b'\n'); metalayout_ext.push(b'\n');
let df_len_bytes = df_ext.len().to_string().into_bytes(); let mut metaline = Vec::with_capacity(builders::MLINE_BUF);
let ml_len_bytes = metalayout_ext.len().to_string().into_bytes();
let mut metaline = Vec::with_capacity(4 + df_len_bytes.len() + ml_len_bytes.len());
metaline.extend(&[b'*', b'!']); metaline.extend(&[b'*', b'!']);
metaline.extend(df_len_bytes); metaline.extend(dataframe.len().to_string().into_bytes());
metaline.push(b'!'); metaline.push(b'!');
metaline.extend(ml_len_bytes); metaline.extend(metalayout_ext.len().to_string().into_bytes());
metaline.push(b'\n'); metaline.push(b'\n');
(metaline, metalayout_ext, df_ext) (metaline, metalayout_ext, dataframe)
} }
} }
#[cfg(test)]
#[test] #[test]
fn test_exceptfor() { fn test_intoresponse_trait_impl_exceptfor() {
let mut exfor = ExceptFor::new(); let mut exceptfor = ExceptFor::new();
exfor.add(1); exceptfor.add(1);
exfor.add(2); exceptfor.add(3);
let (r1, r2, r3) = exfor.into_response(); let (r1, r2, r3) = exceptfor.into_response();
let r = [r1, r2, r3].concat(); let r = [r1, r2, r3].concat();
assert_eq!("*!8!5\n#1#5\n&1\n^1,2\n".as_bytes().to_owned(), r); assert_eq!("*!8!5\n#2#5\n&1\n^1,3\n".as_bytes().to_owned(), r);
} }
/// # The `Writable` trait /// # The `Writable` trait
Loading…
Cancel
Save