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;
/// 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
type RGTuple = (Vec<u8>, Vec<u8>);
pub type RGTuple = (Vec<u8>, Vec<u8>);
/// The metaline, metalayout and dataframe in order
pub type Response = (Vec<u8>, Vec<u8>, Vec<u8>);

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

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

@ -22,12 +22,10 @@
//! # The Query Engine
use crate::coredb::CoreDB;
use crate::kvengine;
use corelib::builders::response::*;
use corelib::de::DataGroup;
use corelib::terrapipe::responses;
pub mod queryutil;
use crate::kvengine;
use std::mem;
mod tags {
//! This module is a collection of tags/strings used for evaluating queries
//! 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::future::Future;
use std::mem;
use std::pin::Pin;
use tokio::io::AsyncWriteExt;
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
/// which existed, it would not provide any information on what existed and what didn't which might be
/// 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 {
/// Create a new `ExceptFor` instance
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 add(&mut self, idx: usize) {
self.0.push(idx);
pub fn with_space_for(howmany: usize) -> Self {
let mut df_ext = vec![b'^'];
df_ext.reserve(howmany);
ExceptFor { df_ext }
}
/// Drop the object returning the inner-vector
pub fn finish_into_vec(self) -> Vec<usize> {
self.0
/// This will essentially add 'idx,' to the `df_ext` field as bytes
pub fn add(&mut self, idx: usize) {
self.df_ext.extend(idx.to_string().into_bytes());
self.df_ext.push(b',');
}
}
impl IntoRespGroup for ExceptFor {
fn into_resp_group(self) -> (Vec<u8>, Vec<u8>) {
let mut except_for_line = Vec::with_capacity((self.0.len() * 2) + 2);
except_for_line.push(b'^');
let mut it = self.0.into_iter().peekable();
while let Some(item) = it.next() {
except_for_line.extend(item.to_string().into_bytes());
if it.peek().is_some() {
except_for_line.push(b',');
} else {
except_for_line.push(b'\n');
}
fn into_resp_group(self) -> RGTuple {
// self_len is the length of the exceptfor line in bytes
let self_len = self.df_ext.len().to_string().into_bytes();
// The size_of(self_len) + size_of('#1#<bytes>')
let mut metalayout = Vec::with_capacity(self_len.len() + 4);
let mut dataframe = Vec::with_capacity(self.df_ext.len() + 3);
metalayout.extend(&[b'#', b'2', b'#']);
metalayout.extend(self_len);
// Preallocate capacity for the dataframe: df_ext.len() + len("&1\n")
dataframe.extend(&[b'&', b'1', b'\n']);
unsafe {
// Add a newline
let self_ptr = &self as *const _;
let self_mut_ptr = self_ptr as *mut ExceptFor;
let mut_ref = &mut (*self_mut_ptr);
let _ = mem::replace(&mut mut_ref.df_ext[(*self_mut_ptr).df_ext.len() - 1], b'\n');
}
let mut metalayout_ext = Vec::with_capacity(EXCEPTFOR_CAP);
metalayout_ext.push(b'#');
metalayout_ext.push(b'1');
metalayout_ext.push(b'#');
metalayout_ext.extend(except_for_line.len().to_string().into_bytes());
let dataframe_ext = [vec![b'&', b'1', b'\n'], except_for_line].concat();
(metalayout_ext, dataframe_ext)
dataframe.extend(self.df_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 {
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');
let df_len_bytes = df_ext.len().to_string().into_bytes();
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());
let mut metaline = Vec::with_capacity(builders::MLINE_BUF);
metaline.extend(&[b'*', b'!']);
metaline.extend(df_len_bytes);
metaline.extend(dataframe.len().to_string().into_bytes());
metaline.push(b'!');
metaline.extend(ml_len_bytes);
metaline.extend(metalayout_ext.len().to_string().into_bytes());
metaline.push(b'\n');
(metaline, metalayout_ext, df_ext)
(metaline, metalayout_ext, dataframe)
}
}
#[cfg(test)]
#[test]
fn test_exceptfor() {
let mut exfor = ExceptFor::new();
exfor.add(1);
exfor.add(2);
let (r1, r2, r3) = exfor.into_response();
fn test_intoresponse_trait_impl_exceptfor() {
let mut exceptfor = ExceptFor::new();
exceptfor.add(1);
exceptfor.add(3);
let (r1, r2, r3) = exceptfor.into_response();
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
Loading…
Cancel
Save