Skip to content

Commit 151f398

Browse files
zakalibitAlex Revetchi
andauthored
Row values decoding performance optimisation (#510)
* - optimise row decoding, just update decoder for every column * - fix null rows decoding * - a bit of code cleanup * - remove semicolon * - apply formatting * - reduce branching * - fix typo * - address review comment, handle tuple & udt cases * - fix typos * - add new line to trigger CI Co-authored-by: Alex Revetchi <alex.revetchi@synchronoss.com>
1 parent 1802d9b commit 151f398

7 files changed

Lines changed: 62 additions & 29 deletions

File tree

src/decoder.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,21 @@ Value Decoder::decode_value(const DataType::ConstPtr& data_type) {
158158
return Value(data_type);
159159
}
160160

161+
bool Decoder::update_value(Value& value) {
162+
int32_t size = 0;
163+
if (decode_int32(size)) {
164+
if (size >= 0) {
165+
Decoder decoder(input_, size, protocol_version_);
166+
input_ += size;
167+
remaining_ -= size;
168+
return value.update(decoder);
169+
}
170+
Decoder decoder;
171+
return value.update(decoder);
172+
}
173+
return false;
174+
}
175+
161176
void Decoder::notify_error(const char* detail, size_t bytes) const {
162177
if (strlen(type_) == 0) {
163178
LOG_ERROR("Expected at least %u byte%s to decode %s value", static_cast<unsigned int>(bytes),

src/decoder.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,9 @@ class Decoder {
559559
bool decode_warnings(WarningVec& output);
560560

561561
Value decode_value(const DataType::ConstPtr& data_type);
562+
bool update_value(Value& value);
563+
564+
bool is_null() const { return input_ == NULL; }
562565

563566
protected:
564567
// Testing only

src/result_iterator.hpp

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,17 @@ class ResultIterator : public Iterator {
3131
, index_(-1)
3232
, row_(result) {
3333
decoder_ = (const_cast<ResultResponse*>(result))->row_decoder();
34-
row_.values.reserve(result->column_count());
34+
row_.values = result_->first_row().values;
3535
}
3636

3737
virtual bool next() {
38-
if (index_ + 1 >= result_->row_count()) {
39-
return false;
40-
}
41-
42-
++index_;
43-
44-
if (index_ > 0) {
45-
return decode_row(decoder_, result_, row_.values);
46-
}
47-
48-
return true;
38+
return (index_ + 1 < result_->row_count()) &&
39+
(++index_ < 1 || decode_next_row(decoder_, row_.values));
4940
}
5041

5142
const Row* row() const {
5243
assert(index_ >= 0 && index_ < result_->row_count());
53-
if (index_ > 0) {
54-
return &row_;
55-
} else {
56-
return &result_->first_row();
57-
}
44+
return &row_;
5845
}
5946

6047
private:

src/row.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,21 @@ namespace datastax { namespace internal { namespace core {
5151

5252
bool decode_row(Decoder& decoder, const ResultResponse* result, OutputValueVec& output) {
5353
output.clear();
54-
const int column_count = result->column_count();
55-
if (column_count > 0) {
56-
output.reserve(column_count);
57-
const SharedRefPtr<ResultMetadata>& metadata = result->metadata();
58-
for (int i = 0; i < column_count; ++i) {
59-
const ColumnDefinition& def = metadata->get_column_definition(i);
60-
Value value = decoder.decode_value(def.data_type);
61-
if (value.is_valid()) {
62-
output.push_back(value);
63-
} else
64-
return false;
65-
}
54+
for (int i = 0; i < result->column_count(); ++i) {
55+
const ColumnDefinition& def = result->metadata()->get_column_definition(i);
56+
Value value = decoder.decode_value(def.data_type);
57+
if (value.is_valid()) {
58+
output.push_back(value);
59+
} else
60+
return false;
61+
}
62+
return true;
63+
}
64+
65+
bool decode_next_row(Decoder& decoder, OutputValueVec& output) {
66+
const size_t column_count = output.size();
67+
for (size_t i = 0; i < column_count; ++i) {
68+
if (!decoder.update_value(output[i])) return false;
6669
}
6770
return true;
6871
}

src/row.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class Row {
5151
};
5252

5353
bool decode_row(Decoder& decoder, const ResultResponse* result, OutputValueVec& output);
54+
bool decode_next_row(Decoder& decoder, OutputValueVec& output);
5455

5556
}}} // namespace datastax::internal::core
5657

src/value.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,26 @@ Value::Value(const DataType::ConstPtr& data_type, Decoder decoder)
209209
}
210210
}
211211

212+
bool Value::update(const Decoder& decoder) {
213+
decoder_ = decoder;
214+
if (!decoder_.is_null()) {
215+
if (data_type_->is_collection()) {
216+
return decoder_.decode_int32(count_);
217+
} else if (data_type_->is_tuple()) {
218+
const CompositeType& composite_type = static_cast<const CompositeType&>(*data_type_);
219+
count_ = composite_type.types().size();
220+
} else if (data_type_->is_user_type()) {
221+
const UserType& user_type = static_cast<const UserType&>(*data_type_);
222+
count_ = user_type.fields().size();
223+
}
224+
} else {
225+
count_ = 0;
226+
is_null_ = true;
227+
}
228+
229+
return true;
230+
}
231+
212232
bool Value::as_bool() const {
213233
assert(!is_null() && value_type() == CASS_VALUE_TYPE_BOOLEAN);
214234
bool value = false;

src/value.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ class Value {
136136
CassUuid as_uuid() const;
137137
StringVec as_stringlist() const;
138138

139+
private:
140+
friend class Decoder;
141+
bool update(const Decoder& decoder);
142+
139143
private:
140144
DataType::ConstPtr data_type_;
141145
int32_t count_;

0 commit comments

Comments
 (0)