Skip to content

Commit 9d75ed1

Browse files
committed
infohash: add to_c_str(), improve toString() performance
1 parent fcca618 commit 9d75ed1

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

include/opendht/infohash.h

+2
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ class OPENDHT_PUBLIC InfoHash final : public std::array<uint8_t, HASH_LEN> {
278278
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const InfoHash& h);
279279
OPENDHT_PUBLIC friend std::istream& operator>> (std::istream& s, InfoHash& h);
280280

281+
const char* to_c_str() const;
282+
281283
std::string toString() const;
282284

283285
template <typename Packer>

src/infohash.cpp

+27-7
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,40 @@ InfoHash::getRandom()
7171
return h;
7272
}
7373

74+
struct HexMap : public std::array<std::array<char, 2>, 256> {
75+
HexMap() {
76+
for (size_t i=0; i<size(); i++) {
77+
auto& e = (*this)[i];
78+
e[0] = hex_digits[(i >> 4) & 0x0F];
79+
e[1] = hex_digits[i & 0x0F];
80+
}
81+
}
82+
private:
83+
static constexpr const char* hex_digits = "0123456789abcdef";
84+
};
85+
86+
const char*
87+
InfoHash::to_c_str() const
88+
{
89+
static const HexMap map;
90+
thread_local std::array<char, HASH_LEN*2+1> buf;
91+
for (size_t i=0; i<HASH_LEN; i++) {
92+
auto b = buf.data()+i*2;
93+
const auto& m = map[(*this)[i]];
94+
*((uint16_t*)b) = *((uint16_t*)&m);
95+
}
96+
return buf.data();
97+
}
98+
7499
std::string
75100
InfoHash::toString() const
76101
{
77-
std::stringstream ss;
78-
ss << *this;
79-
return ss.str();
102+
return std::string(to_c_str(), HASH_LEN*2);
80103
}
81104

82105
std::ostream& operator<< (std::ostream& s, const InfoHash& h)
83106
{
84-
s << std::hex;
85-
for (unsigned i=0; i<HASH_LEN; i++)
86-
s << std::setfill('0') << std::setw(2) << (unsigned)h[i];
87-
s << std::dec;
107+
s.write(h.to_c_str(), HASH_LEN*2);
88108
return s;
89109
}
90110

0 commit comments

Comments
 (0)