Skip to content

Commit cd219f0

Browse files
committed
reduce number of hash table lookups in the resource library
commit_hash:7252be1dc97d6361957aa6f9071247cf1a2b8afe
1 parent a275f7a commit cd219f0

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

library/cpp/resource/registry.cpp

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,33 @@ namespace {
2121

2222
typedef std::pair<TStringBuf, TStringBuf> TDescriptor;
2323

24+
[[noreturn]]
25+
void ReportRedefinitionError(const TStringBuf key, const TStringBuf data, const ui64 kk, const TDescriptor& prev) noexcept {
26+
const auto& [prevKey, value] = prev;
27+
Y_ABORT_UNLESS(key == prevKey, "Internal hash collision:"
28+
" old key: %s,"
29+
" new key: %s,"
30+
" hash: %" PRIx64 ".",
31+
TString{prevKey}.Quote().c_str(),
32+
TString{key}.Quote().c_str(),
33+
kk);
34+
size_t vsize = GetCodec()->DecompressedLength(value);
35+
size_t dsize = GetCodec()->DecompressedLength(data);
36+
if (vsize + dsize < 1000) {
37+
Y_ABORT_UNLESS(false, "Redefinition of key %s:\n"
38+
" old value: %s,\n"
39+
" new value: %s.",
40+
TString{key}.Quote().c_str(),
41+
Decompress(value).Quote().c_str(),
42+
Decompress(data).Quote().c_str());
43+
} else {
44+
Y_ABORT_UNLESS(false, "Redefinition of key %s,"
45+
" old size: %zu,"
46+
" new size: %zu.",
47+
TString{key}.Quote().c_str(), vsize, dsize);
48+
}
49+
}
50+
2451
struct TStore final: public IStore, public absl::flat_hash_map<ui64, TDescriptor*> {
2552
static inline ui64 ToK(TStringBuf k) {
2653
return NHashPrivate::ComputeStringHash(k.data(), k.size());
@@ -29,28 +56,16 @@ namespace {
2956
void Store(const TStringBuf key, const TStringBuf data) override {
3057
auto kk = ToK(key);
3158

32-
if (contains(kk)) {
33-
const TStringBuf value = (*this)[kk]->second;
59+
const auto [it, unique] = try_emplace(kk, nullptr);
60+
if (!unique) {
61+
const auto& [_, value] = *it->second;
3462
if (value != data) {
35-
size_t vsize = GetCodec()->DecompressedLength(value);
36-
size_t dsize = GetCodec()->DecompressedLength(data);
37-
if (vsize + dsize < 1000) {
38-
Y_ABORT_UNLESS(false, "Redefinition of key %s:\n"
39-
" old value: %s,\n"
40-
" new value: %s.",
41-
TString{key}.Quote().c_str(),
42-
Decompress(value).Quote().c_str(),
43-
Decompress(data).Quote().c_str());
44-
} else {
45-
Y_ABORT_UNLESS(false, "Redefinition of key %s,"
46-
" old size: %zu,"
47-
" new size: %zu.",
48-
TString{key}.Quote().c_str(), vsize, dsize);
49-
}
63+
ReportRedefinitionError(key, data, kk, *it->second);
64+
Y_UNREACHABLE();
5065
}
5166
} else {
5267
D_.push_back(TDescriptor(key, data));
53-
(*this)[kk] = &D_.back();
68+
it->second = &D_.back();
5469
}
5570

5671
Y_ABORT_UNLESS(size() == Count(), "size mismatch");

0 commit comments

Comments
 (0)