Skip to content

Commit

Permalink
Avoid extra copy of the data in oracle::read_from_lob()
Browse files Browse the repository at this point in the history
Read directly into the provided string instead of reading into a
temporary buffer and then copying into the string.
  • Loading branch information
vadz committed Nov 20, 2024
1 parent ba202d0 commit 0db5797
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/backends/oracle/standard-into-type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,16 +253,18 @@ void oracle::read_from_lob(oracle_session_backend& session,
return;

// Read the LOB in chunks into the buffer while anything remains to be read.
std::vector<char> buf(len);
for (bool done = false; !done; )
{
auto const prevSize = value.size();
value.resize(prevSize + len);

// By setting the input length to 0, we tell Oracle to read as many
// bytes as possible (so called "streaming" mode).
ub4 lenChunk = 0;
res = OCILobRead(session.svchp_, session.errhp_, lobp,
&lenChunk,
1, // Only used for the first chunk, ignored later.
&buf[0], len,
const_cast<char*>(value.data()) + prevSize, len,
0, 0, 0, 0);

switch (res)
Expand All @@ -279,8 +281,12 @@ void oracle::read_from_lob(oracle_session_backend& session,
throw_oracle_soci_error(res, session.errhp_);
}

value.append(buf.begin(), buf.begin() + lenChunk);
value.resize(prevSize + lenChunk);
}

// We may have over-allocated the string, especially when a big chunk size
// is used, so release the unused memory.
value.shrink_to_fit();
}

void oracle_standard_into_type_backend::post_fetch(
Expand Down

0 comments on commit 0db5797

Please sign in to comment.