Skip to content

Commit 53ca174

Browse files
igchorvinser52
authored andcommitted
Extend cachbench with value validation
1 parent 4477fec commit 53ca174

File tree

5 files changed

+51
-1
lines changed

5 files changed

+51
-1
lines changed

cachelib/cachebench/cache/Cache-inl.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,22 @@ template <typename Allocator>
325325
void Cache<Allocator>::enableConsistencyCheck(
326326
const std::vector<std::string>& keys) {
327327
XDCHECK(valueTracker_ == nullptr);
328+
XDCHECK(!valueValidatingEnabled());
328329
valueTracker_ =
329330
std::make_unique<ValueTracker>(ValueTracker::wrapStrings(keys));
330331
for (const std::string& key : keys) {
331332
invalidKeys_[key] = false;
332333
}
333334
}
334335

336+
template <typename Allocator>
337+
void Cache<Allocator>::enableValueValidating(
338+
const std::string &expectedValue) {
339+
XDCHECK(!valueValidatingEnabled());
340+
XDCHECK(!consistencyCheckEnabled());
341+
this->expectedValue_ = expectedValue;
342+
}
343+
335344
template <typename Allocator>
336345
typename Cache<Allocator>::RemoveRes Cache<Allocator>::remove(Key key) {
337346
if (!consistencyCheckEnabled()) {
@@ -424,6 +433,20 @@ typename Cache<Allocator>::ItemHandle Cache<Allocator>::insertOrReplace(
424433
return rv;
425434
}
426435

436+
template <typename Allocator>
437+
void Cache<Allocator>::validateValue(const ItemHandle &it) const {
438+
XDCHECK(valueValidatingEnabled());
439+
440+
const auto &expected = expectedValue_.value();
441+
442+
auto ptr = reinterpret_cast<const uint8_t*>(getMemory(it));
443+
auto cmp = std::memcmp(ptr, expected.data(), std::min<size_t>(expected.size(),
444+
getSize(it)));
445+
if (cmp != 0) {
446+
throw std::runtime_error("Value does not match!");
447+
}
448+
}
449+
427450
template <typename Allocator>
428451
typename Cache<Allocator>::ItemHandle Cache<Allocator>::find(Key key,
429452
AccessMode mode) {
@@ -439,9 +462,15 @@ typename Cache<Allocator>::ItemHandle Cache<Allocator>::find(Key key,
439462
};
440463

441464
if (!consistencyCheckEnabled()) {
442-
return findFn();
465+
auto it = findFn();
466+
if (valueValidatingEnabled()) {
467+
validateValue(it);
468+
}
469+
return it;
443470
}
444471

472+
XDCHECK(!valueValidatingEnabled());
473+
445474
auto opId = valueTracker_->beginGet(key);
446475
auto it = findFn();
447476
if (checkGet(opId, it)) {

cachelib/cachebench/cache/Cache.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ class Cache {
168168
return getSize(item.get());
169169
}
170170

171+
// checks if values stored in it matches expectedValue_.
172+
void validateValue(const ItemHandle &it) const;
173+
171174
// returns the size of the item, taking into account ItemRecords could be
172175
// enabled.
173176
uint32_t getSize(const Item* item) const noexcept;
@@ -225,9 +228,15 @@ class Cache {
225228
// @param keys list of keys that the stressor uses for the workload.
226229
void enableConsistencyCheck(const std::vector<std::string>& keys);
227230

231+
// enables validating all values on find. Each value is compared to
232+
// expected Value.
233+
void enableValueValidating(const std::string &expectedValue);
234+
228235
// returns true if the consistency checking is enabled.
229236
bool consistencyCheckEnabled() const { return valueTracker_ != nullptr; }
230237

238+
bool valueValidatingEnabled() const { return expectedValue_.has_value(); }
239+
231240
// return true if the key was previously detected to be inconsistent. This
232241
// is useful only when consistency checking is enabled by calling
233242
// enableConsistencyCheck()
@@ -350,6 +359,9 @@ class Cache {
350359
// tracker for consistency monitoring.
351360
std::unique_ptr<ValueTracker> valueTracker_;
352361

362+
// exceptected value of all items in Cache.
363+
std::optional<std::string> expectedValue_;
364+
353365
// reading of the nand bytes written for the benchmark if enabled.
354366
const uint64_t nandBytesBegin_{0};
355367

cachelib/cachebench/runner/CacheStressor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ class CacheStressor : public Stressor {
110110
if (config_.checkConsistency) {
111111
cache_->enableConsistencyCheck(wg_->getAllKeys());
112112
}
113+
if (config_.validateValue) {
114+
cache_->enableValueValidating(hardcodedString_);
115+
}
113116
if (config_.opRatePerSec > 0) {
114117
rateLimiter_ = std::make_unique<folly::BasicTokenBucket<>>(
115118
config_.opRatePerSec, config_.opRatePerSec);

cachelib/cachebench/util/Config.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ StressorConfig::StressorConfig(const folly::dynamic& configJson) {
3434
JSONSetVal(configJson, samplingIntervalMs);
3535

3636
JSONSetVal(configJson, checkConsistency);
37+
JSONSetVal(configJson, validateValue);
3738

3839
JSONSetVal(configJson, numOps);
3940
JSONSetVal(configJson, numThreads);

cachelib/cachebench/util/Config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,13 @@ struct StressorConfig : public JSONConfig {
188188
uint64_t samplingIntervalMs{1000};
189189

190190
// If enabled, stressor will verify operations' results are consistent.
191+
// Mutually exclusive with validateValue
191192
bool checkConsistency{false};
192193

194+
// If enable, stressos will verify if value read is equal to value written.
195+
// Mutually exclusive with checkConsistency
196+
bool validateValue{false};
197+
193198
uint64_t numOps{0}; // operation per thread
194199
uint64_t numThreads{0}; // number of threads that will run
195200
uint64_t numKeys{0}; // number of keys that will be used

0 commit comments

Comments
 (0)