Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

Commit

Permalink
quic: make QuicCID more efficient
Browse files Browse the repository at this point in the history
Much of the time, QuicCID is wrapping a `const ngtcp2_cid*`, when that
is the case, avoid copying it's value and use the pointer directly.
Otherwise, allocate an internal buffer.
  • Loading branch information
jasnell committed Jan 15, 2020
1 parent 26ca170 commit f9ea38a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 31 deletions.
5 changes: 3 additions & 2 deletions src/quic/node_quic_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1465,7 +1465,6 @@ void QuicSession::AckedStreamDataOffset(
// be associated with the new QuicSocket.
void QuicSession::AddToSocket(QuicSocket* socket) {
socket->AddSession(scid_, BaseObjectPtr<QuicSession>(this));

switch (crypto_context_->side()) {
case NGTCP2_CRYPTO_SIDE_SERVER: {
socket->AssociateCID(rcid_, scid_);
Expand All @@ -1475,8 +1474,9 @@ void QuicSession::AddToSocket(QuicSocket* socket) {
case NGTCP2_CRYPTO_SIDE_CLIENT: {
std::vector<ngtcp2_cid> cids(ngtcp2_conn_get_num_scid(connection()));
ngtcp2_conn_get_scid(connection(), cids.data());
for (const ngtcp2_cid& cid : cids)
for (const ngtcp2_cid& cid : cids) {
socket->AssociateCID(QuicCID(&cid), scid_);
}
break;
}
default:
Expand Down Expand Up @@ -2748,6 +2748,7 @@ BaseObjectPtr<QuicSession> QuicSession::CreateClient(
qlog);

session->AddToSocket(socket);

return session;
}

Expand Down
19 changes: 8 additions & 11 deletions src/quic/node_quic_util-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,26 @@ QuicPath::QuicPath(

size_t QuicCID::Hash::operator()(const QuicCID& token) const {
size_t hash = 0;
for (size_t n = 0; n < token.cid_.datalen; n++)
hash ^= std::hash<uint8_t>{}(token.cid_.data[n]) + 0x9e3779b9 +
for (size_t n = 0; n < token->datalen; n++) {
hash ^= std::hash<uint8_t>{}(token->data[n]) + 0x9e3779b9 +
(hash << 6) + (hash >> 2);
}
return hash;
}

bool QuicCID::Compare::operator()(
const QuicCID& lcid,
const QuicCID& rcid) const {
if (lcid.cid_.datalen != rcid.cid_.datalen)
return false;
return memcmp(
lcid.cid_.data,
rcid.cid_.data,
lcid.cid_.datalen) == 0;
return lcid->datalen != rcid->datalen ?
false : memcmp(lcid->data, rcid->data, lcid->datalen) == 0;
}

std::string QuicCID::ToHex() const {
std::vector<char> dest(cid_.datalen * 2 + 1);
std::vector<char> dest(ptr_->datalen * 2 + 1);
dest[dest.size() - 1] = '\0';
size_t written = StringBytes::hex_encode(
reinterpret_cast<const char*>(cid_.data),
cid_.datalen,
reinterpret_cast<const char*>(ptr_->data),
ptr_->datalen,
dest.data(),
dest.size());
return std::string(dest.data(), written);
Expand Down
58 changes: 40 additions & 18 deletions src/quic/node_quic_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,22 @@ struct QuicPathStorage : public ngtcp2_path_storage {
// Simple wrapper for ngtcp2_cid that handles hex encoding
class QuicCID : public MemoryRetainer {
public:
QuicCID() {}
QuicCID(const QuicCID& cid) : cid_(cid.cid_) {}
explicit QuicCID(const ngtcp2_cid* cid) : cid_(*cid) {}
explicit QuicCID(const ngtcp2_cid& cid) : cid_(cid) {}
QuicCID(const uint8_t* cid, size_t len) {
ngtcp2_cid_init(&cid_, cid, len);
// Empty constructor
QuicCID() : ptr_(&cid_) {}

// Copy constructor
QuicCID(const QuicCID& cid) : QuicCID(cid->data, cid->datalen) {}

// Copy constructor
explicit QuicCID(const ngtcp2_cid& cid) : QuicCID(cid.data, cid.datalen) {}

// Wrap constructor
explicit QuicCID(const ngtcp2_cid* cid) : ptr_(cid) {}

QuicCID(const uint8_t* cid, size_t len) : QuicCID() {
ngtcp2_cid* ptr = this->cid();
ngtcp2_cid_init(ptr, cid, len);
ptr_ = ptr;
}

struct Hash {
Expand All @@ -216,28 +226,40 @@ class QuicCID : public MemoryRetainer {

inline std::string ToHex() const;

// Copy assignment
QuicCID& operator=(const QuicCID& cid) {
cid_ = cid.cid_;
return *this;
if (this == &cid) return *this;
this->~QuicCID();
return *new(this) QuicCID(std::move(cid));
}
const ngtcp2_cid& operator*() const { return cid_; }
const ngtcp2_cid* operator->() const { return &cid_; }
const ngtcp2_cid* cid() const { return &cid_; }
ngtcp2_cid* cid() { return &cid_; }
operator bool() const { return cid_.datalen > 0; }

const uint8_t* data() const { return cid_.data; }
size_t length() const { return cid_.datalen; }
const ngtcp2_cid& operator*() const { return *ptr_; }
const ngtcp2_cid* operator->() const { return ptr_; }
const ngtcp2_cid* cid() const { return ptr_; }
const uint8_t* data() const { return ptr_->data; }
operator bool() const { return ptr_->datalen > 0; }
size_t length() const { return ptr_->datalen; }

unsigned char* data() { return reinterpret_cast<unsigned char*>(cid_.data); }
void set_length(size_t length) { cid_.datalen = length; }
ngtcp2_cid* cid() {
CHECK_EQ(ptr_, &cid_);
return &cid_;
}

unsigned char* data() {
return reinterpret_cast<unsigned char*>(cid()->data);
}

void set_length(size_t length) {
cid()->datalen = length;
}

SET_NO_MEMORY_INFO()
SET_MEMORY_INFO_NAME(QuicCID)
SET_SELF_SIZE(QuicCID)

private:
ngtcp2_cid cid_;
ngtcp2_cid cid_{};
const ngtcp2_cid* ptr_;
};

// Simple timer wrapper that is used to implement the internals
Expand Down

0 comments on commit f9ea38a

Please sign in to comment.