Skip to content

Commit

Permalink
optimize values
Browse files Browse the repository at this point in the history
  • Loading branch information
suharev7 committed Jul 31, 2019
1 parent d42d95c commit ee3a6e4
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 191 deletions.
7 changes: 4 additions & 3 deletions src/types/column/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
},
};
use chrono_tz::Tz;
use std::sync::Arc;

pub(crate) struct ArrayColumnData {
pub(crate) inner: Box<dyn ColumnData + Send + Sync>,
Expand Down Expand Up @@ -65,8 +66,8 @@ impl ColumnData for ArrayColumnData {
};

self.offsets.push((prev + vs.len()) as u64);
for v in vs {
self.inner.push(v);
for v in vs.iter() {
self.inner.push(v.clone());
}
} else {
panic!("value should be an array")
Expand All @@ -87,7 +88,7 @@ impl ColumnData for ArrayColumnData {
let v = self.inner.at(i);
vs.push(v);
}
ValueRef::Array(sql_type, vs)
ValueRef::Array(sql_type.into(), Arc::new(vs))
}
}

Expand Down
29 changes: 14 additions & 15 deletions src/types/column/date.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{convert, fmt, mem};
use std::{convert, fmt, sync::Arc};

use chrono::{prelude::*, Date};
use chrono_tz::Tz;
Expand All @@ -8,8 +8,8 @@ use crate::{
errors::Error,
types::{
column::{
array::ArrayColumnData, nullable::NullableColumnData, BoxColumnWrapper, ColumnWrapper,
Either,
array::ArrayColumnData, nullable::NullableColumnData, numeric::save_data,
BoxColumnWrapper, ColumnWrapper, Either,
},
DateConverter, Marshal, SqlType, StatBuffer, Unmarshal, Value, ValueRef,
},
Expand Down Expand Up @@ -97,10 +97,11 @@ impl ColumnFrom for Vec<Vec<Date<Tz>>> {
for vs in source {
let mut inner = Vec::with_capacity(vs.len());
for v in vs {
let value: Value = Value::Date(v);
let days = u16::get_days(v);
let value: Value = Value::Date(days, v.timezone());
inner.push(value);
}
data.push(Value::Array(sql_type, inner));
data.push(Value::Array(sql_type.into(), Arc::new(inner)));
}

W::wrap(data)
Expand All @@ -121,10 +122,10 @@ impl ColumnFrom for Vec<Vec<DateTime<Tz>>> {
for vs in source {
let mut inner = Vec::with_capacity(vs.len());
for v in vs {
let value: Value = Value::DateTime(v);
let value: Value = Value::DateTime(v.timestamp() as u32, v.timezone());
inner.push(value);
}
data.push(Value::Array(sql_type, inner));
data.push(Value::Array(sql_type.into(), Arc::new(inner)));
}

W::wrap(data)
Expand All @@ -143,9 +144,9 @@ impl ColumnFrom for Vec<Option<DateTime<Tz>>> {

for value in source {
match value {
None => data.push(Value::Nullable(Either::Left(SqlType::DateTime))),
None => data.push(Value::Nullable(Either::Left(SqlType::DateTime.into()))),
Some(d) => {
let value = Value::DateTime(d);
let value = Value::DateTime(d.timestamp() as u32, d.timezone());
data.push(Value::Nullable(Either::Right(Box::new(value))))
}
}
Expand All @@ -167,9 +168,10 @@ impl ColumnFrom for Vec<Option<Date<Tz>>> {

for value in source {
match value {
None => data.push(Value::Nullable(Either::Left(SqlType::Date))),
None => data.push(Value::Nullable(Either::Left(SqlType::Date.into()))),
Some(d) => {
let value = Value::Date(d);
let days = u16::get_days(d);
let value = Value::Date(days, d.timezone());
data.push(Value::Nullable(Either::Right(Box::new(value))))
}
}
Expand Down Expand Up @@ -199,10 +201,7 @@ where
}

fn save(&self, encoder: &mut Encoder, start: usize, end: usize) {
let start_index = start * mem::size_of::<T>();
let end_index = end * mem::size_of::<T>();
let data = self.data.as_ref();
encoder.write_bytes(&data[start_index..end_index]);
save_data::<T>(self.data.as_ref(), encoder, start, end);
}

fn len(&self) -> usize {
Expand Down
2 changes: 1 addition & 1 deletion src/types/column/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ impl ColumnData for NullableDecimalAdapter {
fn at(&self, index: usize) -> ValueRef {
let value: Option<Decimal> = Option::from_sql(self.column.at(index)).unwrap();
match value {
None => ValueRef::Nullable(Either::Left(self.sql_type())),
None => ValueRef::Nullable(Either::Left(self.sql_type().into())),
Some(mut v) => {
v = v.set_scale(self.scale);
v.precision = self.precision;
Expand Down
4 changes: 2 additions & 2 deletions src/types/column/fixed_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ impl ColumnData for FixedStringAdapter {
}
ValueRef::Array(SqlType::UInt8, vs) => {
let mut string_val: Vec<u8> = Vec::with_capacity(vs.len());
for v in vs {
let byte: u8 = v.into();
for v in vs.iter() {
let byte: u8 = v.clone().into();
string_val.push(byte);
}
let string_ref: &[u8] = string_val.as_ref();
Expand Down
4 changes: 2 additions & 2 deletions src/types/column/nullable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl ColumnData for NullableColumnData {
if let Value::Nullable(e) = value {
match e {
Either::Left(sql_type) => {
let default_value = Value::default(sql_type);
let default_value = Value::default(*sql_type);
self.inner.push(default_value);
self.nulls.push(true as u8);
}
Expand All @@ -69,7 +69,7 @@ impl ColumnData for NullableColumnData {
fn at(&self, index: usize) -> ValueRef {
if self.nulls[index] == 1 {
let sql_type = self.inner.sql_type();
ValueRef::Nullable(Either::Left(sql_type))
ValueRef::Nullable(Either::Left(sql_type.into()))
} else {
let inner_value = self.inner.at(index);
ValueRef::Nullable(Either::Right(Box::new(inner_value)))
Expand Down
15 changes: 9 additions & 6 deletions src/types/column/numeric.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{convert, mem};
use std::{convert, mem, sync::Arc};

use crate::{
binary::{Encoder, ReadEx},
Expand Down Expand Up @@ -132,7 +132,7 @@ where
let value: Value = v.into();
inner.push(value)
}
Value::Array(sql_type, inner)
Value::Array(sql_type.into(), Arc::new(inner))
}

impl<T> VectorColumnData<T>
Expand Down Expand Up @@ -183,10 +183,7 @@ where
}

fn save(&self, encoder: &mut Encoder, start: usize, end: usize) {
let start_index = start * mem::size_of::<T>();
let end_index = end * mem::size_of::<T>();
let data = self.data.as_ref();
encoder.write_bytes(&data[start_index..end_index]);
save_data::<T>(self.data.as_ref(), encoder, start, end);
}

fn len(&self) -> usize {
Expand Down Expand Up @@ -217,3 +214,9 @@ where
}
}
}

pub(crate) fn save_data<T>(data: &[u8], encoder: &mut Encoder, start: usize, end: usize) {
let start_index = start * mem::size_of::<T>();
let end_index = end * mem::size_of::<T>();
encoder.write_bytes(&data[start_index..end_index]);
}
138 changes: 68 additions & 70 deletions src/types/column/string.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::{io::Write, string::ToString};
use std::{io::Write, string::ToString, sync::Arc};

use crate::{
binary::{Encoder, ReadEx},
errors::Error,
types::{
column::{
array::ArrayColumnData, list::List, nullable::NullableColumnData, BoxColumnWrapper,
ColumnWrapper, StringPool,
ColumnWrapper, Either, StringPool,
},
Column, FromSql, SqlType, Value, ValueRef,
},
Expand Down Expand Up @@ -59,103 +59,101 @@ impl<'a> ColumnFrom for Vec<&'a [u8]> {
}
}

impl ColumnFrom for Vec<Option<String>> {
fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
let inner = Box::new(StringColumnData::with_capacity(source.len()));
trait StringSource {
fn to_value(self) -> Value;
}

let mut data = NullableColumnData {
inner,
nulls: Vec::with_capacity(source.len()),
};
impl StringSource for String {
fn to_value(self) -> Value {
self.into()
}
}

for value in source {
data.push(value.into());
}
impl StringSource for &str {
fn to_value(self) -> Value {
self.into()
}
}

W::wrap(data)
impl StringSource for Vec<u8> {
fn to_value(self) -> Value {
Value::String(Arc::new(self))
}
}

impl ColumnFrom for Vec<Vec<String>> {
fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
let fake: Vec<String> = Vec::with_capacity(source.len());
let inner = Vec::column_from::<BoxColumnWrapper>(fake);
let sql_type = inner.sql_type();

let mut data = ArrayColumnData {
inner,
offsets: List::with_capacity(source.len()),
};

for vs in source {
let mut inner = Vec::with_capacity(vs.len());
for v in vs {
let value: Value = v.into();
inner.push(value)
}
data.push(Value::Array(sql_type, inner));
}

W::wrap(data)
make_array_of_array::<W, String>(source)
}
}

impl ColumnFrom for Vec<Vec<&str>> {
fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
let fake: Vec<&str> = Vec::with_capacity(source.len());
let inner = Vec::column_from::<BoxColumnWrapper>(fake);
let sql_type = inner.sql_type();

let mut data = ArrayColumnData {
inner,
offsets: List::with_capacity(source.len()),
};
make_array_of_array::<W, &str>(source)
}
}

for vs in source {
let mut inner = Vec::with_capacity(vs.len());
for v in vs {
let value: Value = v.into();
inner.push(value)
}
data.push(Value::Array(sql_type, inner));
fn make_array_of_array<W: ColumnWrapper, S: StringSource>(
source: Vec<Vec<S>>,
) -> <W as ColumnWrapper>::Wrapper {
let fake: Vec<String> = Vec::with_capacity(source.len());
let inner = Vec::column_from::<BoxColumnWrapper>(fake);
let sql_type = inner.sql_type();

let mut data = ArrayColumnData {
inner,
offsets: List::with_capacity(source.len()),
};

for vs in source {
let mut inner = Vec::with_capacity(vs.len());
for v in vs {
let value: Value = v.to_value();
inner.push(value)
}

W::wrap(data)
data.push(Value::Array(sql_type.into(), Arc::new(inner)));
}

W::wrap(data)
}

impl ColumnFrom for Vec<Option<Vec<u8>>> {
fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
let inner = Box::new(StringColumnData::with_capacity(source.len()));

let mut data = NullableColumnData {
inner,
nulls: Vec::with_capacity(source.len()),
};

for value in source {
data.push(value.into());
}

W::wrap(data)
make_opt_column::<W, Vec<u8>>(source)
}
}

impl ColumnFrom for Vec<Option<&str>> {
fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
let inner = Box::new(StringColumnData::with_capacity(source.len()));
make_opt_column::<W, &str>(source)
}
}

impl ColumnFrom for Vec<Option<String>> {
fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
make_opt_column::<W, String>(source)
}
}

let mut data = NullableColumnData {
inner,
nulls: Vec::with_capacity(source.len()),
};
fn make_opt_column<W: ColumnWrapper, S: StringSource>(source: Vec<Option<S>>) -> W::Wrapper {
let inner = Box::new(StringColumnData::with_capacity(source.len()));

for value in source {
data.push(value.into());
}
let mut data = NullableColumnData {
inner,
nulls: Vec::with_capacity(source.len()),
};

W::wrap(data)
for value in source {
let item = if let Some(v) = value {
let inner = v.to_value();
Value::Nullable(Either::Right(Box::new(inner)))
} else {
Value::Nullable(Either::Left(SqlType::String.into()))
};
data.push(item);
}

W::wrap(data)
}

impl ColumnData for StringColumnData {
Expand Down
6 changes: 2 additions & 4 deletions src/types/date_converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ pub trait DateConverter {

impl DateConverter for u16 {
fn to_date(&self, tz: Tz) -> ValueRef<'static> {
let time = tz.timestamp(i64::from(*self) * 24 * 3600, 0);
ValueRef::Date(time.date())
ValueRef::Date(*self, tz)
}

fn get_stamp(source: Value) -> Self {
Expand All @@ -32,8 +31,7 @@ impl DateConverter for u16 {

impl DateConverter for u32 {
fn to_date(&self, tz: Tz) -> ValueRef<'static> {
let time = tz.timestamp(i64::from(*self), 0);
ValueRef::DateTime(time)
ValueRef::DateTime(*self, tz)
}

fn get_stamp(source: Value) -> Self {
Expand Down
Loading

0 comments on commit ee3a6e4

Please sign in to comment.