MXS-1538: Remove unnecessary copying of schema information

The schema related information was copied for each row. A shared pointer
to the data can be used to remove the repeated copying of the values.
This commit is contained in:
Markus Mäkelä
2018-01-18 22:05:17 +02:00
parent 070df73d99
commit f204650bbb
3 changed files with 45 additions and 42 deletions

View File

@ -156,6 +156,7 @@ template <> void Closer<struct addrinfo*>::close(struct addrinfo* ai)
{ {
freeaddrinfo(ai); freeaddrinfo(ai);
} }
template <> void Closer<int>::close(int fd) template <> void Closer<int>::close(int fd)
{ {
close(fd); close(fd);
@ -307,8 +308,8 @@ static inline bool is_schema(json_t* json)
void Connection::process_schema(json_t* json) void Connection::process_schema(json_t* json)
{ {
ValueList keys; SValueVector keys(std::make_shared<ValueVector>());
ValueList types; SValueVector types(std::make_shared<ValueVector>());
json_t* arr = json_object_get(json, "fields"); json_t* arr = json_object_get(json, "fields");
size_t i; size_t i;
@ -338,22 +339,22 @@ void Connection::process_schema(json_t* json)
} }
} }
keys.push_back(nameval); keys->push_back(nameval);
types.push_back(typeval); types->push_back(typeval);
} }
m_keys.swap(keys); m_keys = keys;
m_types.swap(types); m_types = types;
} }
Row Connection::process_row(json_t* js) SRow Connection::process_row(json_t* js)
{ {
ValueList values; ValueVector values;
values.reserve(m_keys.size()); values.reserve(m_keys->size());
m_error.clear(); m_error.clear();
for (ValueList::iterator it = m_keys.begin(); for (ValueVector::iterator it = m_keys->begin();
it != m_keys.end(); it++) it != m_keys->end(); it++)
{ {
json_t* v = json_object_get(js, it->c_str()); json_t* v = json_object_get(js, it->c_str());
@ -369,20 +370,20 @@ Row Connection::process_row(json_t* js)
} }
} }
Row rval; SRow rval;
if (m_error.empty()) if (m_error.empty())
{ {
rval = Row(new InternalRow(m_keys, m_types, values)); rval = SRow(new Row(m_keys, m_types, values));
} }
return rval; return rval;
} }
Row Connection::read() SRow Connection::read()
{ {
m_error.clear(); m_error.clear();
Row rval; SRow rval;
std::string row; std::string row;
if (m_first_row) if (m_first_row)

View File

@ -1,3 +1,4 @@
#pragma once
/* Copyright (c) 2017, MariaDB Corporation. All rights reserved. /* Copyright (c) 2017, MariaDB Corporation. All rights reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -32,10 +33,11 @@ namespace CDC
const char* TIMEOUT = "Request timed out"; const char* TIMEOUT = "Request timed out";
// The typedef for the Row type // The typedef for the Row type
class InternalRow; class Row;
typedef std::shared_ptr<InternalRow> Row; typedef std::shared_ptr<Row> SRow;
typedef std::vector<std::string> ValueList; typedef std::vector<std::string> ValueVector;
typedef std::shared_ptr<ValueVector> SValueVector;
typedef std::map<std::string, std::string> ValueMap; typedef std::map<std::string, std::string> ValueMap;
// A class that represents a CDC connection // A class that represents a CDC connection
@ -78,7 +80,7 @@ public:
* *
* @see InternalRow * @see InternalRow
*/ */
Row read(); SRow read();
/** /**
* Explicitly close the connection * Explicitly close the connection
@ -116,9 +118,9 @@ public:
{ {
ValueMap fields; ValueMap fields;
for (size_t i = 0; i < m_keys.size(); i++) for (size_t i = 0; i < m_keys->size(); i++)
{ {
fields[m_keys[i]] = m_types[i]; fields[(*m_keys)[i]] = (*m_types)[i];
} }
return fields; return fields;
@ -132,19 +134,19 @@ private:
std::string m_password; std::string m_password;
std::string m_error; std::string m_error;
std::string m_schema; std::string m_schema;
ValueList m_keys; SValueVector m_keys;
ValueList m_types; SValueVector m_types;
int m_timeout; int m_timeout;
std::vector<char> m_buffer; std::vector<char> m_buffer;
std::vector<char>::iterator m_buf_ptr; std::vector<char>::iterator m_buf_ptr;
Row m_first_row; SRow m_first_row;
bool m_connected; bool m_connected;
bool do_auth(); bool do_auth();
bool do_registration(); bool do_registration();
bool read_row(std::string& dest); bool read_row(std::string& dest);
void process_schema(json_t* json); void process_schema(json_t* json);
Row process_row(json_t*); SRow process_row(json_t*);
bool is_error(const char* str); bool is_error(const char* str);
// Lower-level functions // Lower-level functions
@ -154,11 +156,11 @@ private:
}; };
// Internal representation of a row, used via the Row type // Internal representation of a row, used via the Row type
class InternalRow class Row
{ {
InternalRow(const InternalRow&) = delete; Row(const Row&) = delete;
InternalRow& operator=(const InternalRow&) = delete; Row& operator=(const Row&) = delete;
InternalRow() = delete; Row() = delete;
public: public:
/** /**
@ -180,7 +182,7 @@ public:
*/ */
const std::string& value(size_t i) const const std::string& value(size_t i) const
{ {
return m_values[i]; return m_values.at(i);
} }
/** /**
@ -192,8 +194,8 @@ public:
*/ */
const std::string& value(const std::string& str) const const std::string& value(const std::string& str) const
{ {
ValueList::const_iterator it = std::find(m_keys.begin(), m_keys.end(), str); ValueVector::const_iterator it = std::find(m_keys->begin(), m_keys->end(), str);
return m_values[it - m_keys.begin()]; return m_values.at(it - m_keys->begin());
} }
/** /**
@ -219,7 +221,7 @@ public:
*/ */
const std::string& key(size_t i) const const std::string& key(size_t i) const
{ {
return m_keys[i]; return m_keys->at(i);
} }
/** /**
@ -229,24 +231,24 @@ public:
*/ */
const std::string& type(size_t i) const const std::string& type(size_t i) const
{ {
return m_types[i]; return m_types->at(i);
} }
~InternalRow() ~Row()
{ {
} }
private: private:
ValueList m_keys; SValueVector m_keys;
ValueList m_types; SValueVector m_types;
ValueList m_values; ValueVector m_values;
// Only a Connection should construct an InternalRow // Only a Connection should construct an InternalRow
friend class Connection; friend class Connection;
InternalRow(const ValueList& keys, Row(SValueVector& keys,
const ValueList& types, SValueVector& types,
ValueList& values): ValueVector& values):
m_keys(keys), m_keys(keys),
m_types(types) m_types(types)
{ {

View File

@ -182,7 +182,7 @@ bool run_test(TestConnections& test)
{ {
for (int j = 0; test_set[x].values[j]; j++) for (int j = 0; test_set[x].values[j]; j++)
{ {
CDC::Row row; CDC::SRow row;
if ((row = conn.read())) if ((row = conn.read()))
{ {