Skip to content

Commit

Permalink
Share fetch array buffer when <Row as RowValue>::get() is called inst…
Browse files Browse the repository at this point in the history
…ead of deep copy.

This will improve performance pointed by #44.
  • Loading branch information
kubo committed Jun 15, 2024
1 parent 887efee commit 1b5051a
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ impl RowValue for Row {
let num_cols = row.column_values.len();
let mut column_values = Vec::with_capacity(num_cols);
for val in &row.column_values {
column_values.push(val.dup_by_handle()?);
column_values.push(val.clone_except_fetch_array_buffer()?);
}
Ok(Row {
column_info: row.column_info.clone(),
Expand Down
45 changes: 28 additions & 17 deletions src/sql_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use std::convert::TryInto;
use std::fmt;
use std::os::raw::c_char;
use std::ptr;
use std::rc::Rc;
use std::str;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
Expand Down Expand Up @@ -128,7 +129,7 @@ pub enum BufferRowIndex {

enum DpiData<'a> {
Data(&'a mut dpiData),
Var(DpiVar),
Var(Rc<DpiVar>), // Rc is incremented only when <Row as RowValue>::get() is called.
Null,
}

Expand Down Expand Up @@ -298,7 +299,7 @@ impl SqlValue<'_> {
&mut data,
)
);
self.data = DpiData::Var(DpiVar::new(handle, data));
self.data = DpiData::Var(Rc::new(DpiVar::new(handle, data)));
self.native_type = native_type;
self.oratype = Some(oratype.clone());
if native_type_num == DPI_NATIVE_TYPE_STMT {
Expand All @@ -322,7 +323,7 @@ impl SqlValue<'_> {
);
if num != 0 {
self.array_size = num;
self.data = DpiData::Var(DpiVar::with_add_ref(handle, data));
self.data = DpiData::Var(Rc::new(DpiVar::with_add_ref(handle, data)));
}
Ok(())
}
Expand Down Expand Up @@ -849,21 +850,31 @@ impl SqlValue<'_> {
Ok(())
}

pub(crate) fn dup_by_handle(&self) -> Result<SqlValue<'static>> {
let mut val = SqlValue::new(
self.conn.clone(),
self.lob_bind_type,
self.query_params.clone(),
1,
);
if let Some(ref oratype) = self.oratype {
val.init_handle(oratype)?;
chkerr!(
self.ctxt(),
dpiVar_copyData(val.handle()?, 0, self.handle()?, self.buffer_row_index())
);
pub(crate) fn clone_except_fetch_array_buffer(&self) -> Result<SqlValue<'static>> {
if let DpiData::Var(ref var) = self.data {
Ok(SqlValue {
conn: self.conn.clone(),
data: DpiData::Var(var.clone()),
native_type: self.native_type.clone(),
oratype: self.oratype.clone(),
array_size: self.array_size,
buffer_row_index: BufferRowIndex::Owned(self.buffer_row_index()),
keep_bytes: Vec::new(),
keep_dpiobj: DpiObject::null(),
lob_bind_type: self.lob_bind_type,
query_params: self.query_params.clone(),
})
} else {
Err(Error::internal_error("dpVar handle isn't initialized"))
}
}

pub(crate) fn fetch_array_buffer_shared_count(&self) -> Result<usize> {
if let DpiData::Var(ref var) = self.data {
Ok(Rc::strong_count(var))
} else {
Err(Error::internal_error("dpData isn't initialized"))
}
Ok(val)
}

//
Expand Down
20 changes: 19 additions & 1 deletion src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,13 +444,31 @@ impl Stmt {
}

pub fn fetch_rows(&mut self) -> Result<bool> {
let handle = self.handle();
let row = self.row.as_mut().unwrap();
for i in 0..(row.column_info.len()) {
// If fetch array buffer is referenced only by self, it is reusable.
// Otherwise, a new SqlValue must be created to allocate a new buffer
// because dpiStmt_fetchRows() overwrites the buffer.
if row.column_values[i].fetch_array_buffer_shared_count()? > 1 {
let oratype = row.column_info[i].oracle_type();
row.column_values[i] = SqlValue::for_column(
self.conn.clone(),
self.query_params.clone(),
self.shared_buffer_row_index.clone(),
oratype,
handle,
(i + 1) as u32,
)?;
}
}
let mut new_index = 0;
let mut num_rows = 0;
let mut more_rows = 0;
chkerr!(
self.ctxt(),
dpiStmt_fetchRows(
self.handle(),
handle,
self.query_params.fetch_array_size,
&mut new_index,
&mut num_rows,
Expand Down

0 comments on commit 1b5051a

Please sign in to comment.