Skip to content

Commit fed274e

Browse files
Jim Ciparfacebook-github-bot
authored andcommitted
Add itemValue to cachebench
Summary: This adds `itemValue`, a `uint64_t`, to the cache trace. This is used to store the user/intern flag. We gave it an intentionally vague name, because we were concerned with putting stuff about user/intern split into the open source code. Other users of this code can use itemValue for whatever they want. Differential Revision: D41134915 fbshipit-source-id: aa26ce715b70a4c95bb0678443832273522b4fa4
1 parent ad22457 commit fed274e

File tree

7 files changed

+50
-19
lines changed

7 files changed

+50
-19
lines changed

cachelib/cachebench/runner/CacheStressor.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,20 @@ class CacheStressor : public Stressor {
239239
}
240240

241241
// populate the input item handle according to the stress setup.
242-
void populateItem(WriteHandle& handle) {
242+
void populateItem(WriteHandle& handle, const std::string& itemValue = "") {
243243
if (!config_.populateItem) {
244244
return;
245245
}
246246
XDCHECK(handle);
247247
XDCHECK_LE(cache_->getSize(handle), 4ULL * 1024 * 1024);
248248
if (cache_->consistencyCheckEnabled()) {
249249
cache_->setUint64ToItem(handle, folly::Random::rand64(rng));
250+
}
251+
252+
if (!itemValue.empty()) {
253+
// Add the null character to ensure this is a proper c string.
254+
// TODO(T141356292): Clean this up to avoid allocating a new string
255+
cache_->setStringItem(handle, itemValue + "\0");
250256
} else {
251257
cache_->setStringItem(handle, hardcodedString_);
252258
}
@@ -323,7 +329,7 @@ class CacheStressor : public Stressor {
323329
}
324330
auto lock = chainedItemAcquireUniqueLock(*key);
325331
result = setKey(pid, stats, key, *(req.sizeBegin), req.ttlSecs,
326-
req.admFeatureMap);
332+
req.admFeatureMap, req.itemValue);
327333

328334
break;
329335
}
@@ -353,7 +359,7 @@ class CacheStressor : public Stressor {
353359
slock = {};
354360
xlock = chainedItemAcquireUniqueLock(*key);
355361
setKey(pid, stats, key, *(req.sizeBegin), req.ttlSecs,
356-
req.admFeatureMap);
362+
req.admFeatureMap, req.itemValue);
357363
}
358364
} else {
359365
result = OpResultType::kGetHit;
@@ -462,7 +468,8 @@ class CacheStressor : public Stressor {
462468
const std::string* key,
463469
size_t size,
464470
uint32_t ttlSecs,
465-
const std::unordered_map<std::string, std::string>& featureMap) {
471+
const std::unordered_map<std::string, std::string>& featureMap,
472+
const std::string& itemValue) {
466473
// check the admission policy first, and skip the set operation
467474
// if the policy returns false
468475
if (config_.admPolicy && !config_.admPolicy->accept(featureMap)) {
@@ -475,7 +482,7 @@ class CacheStressor : public Stressor {
475482
++stats.setFailure;
476483
return OpResultType::kSetFailure;
477484
} else {
478-
populateItem(it);
485+
populateItem(it, itemValue);
479486
cache_->insertOrReplace(it);
480487
return OpResultType::kSetSuccess;
481488
}
@@ -501,7 +508,8 @@ class CacheStressor : public Stressor {
501508
if (config_.checkConsistency && cache_->isInvalidKey(req.key)) {
502509
continue;
503510
}
504-
// TODO: allow callback on nvm eviction instead of checking it repeatedly.
511+
// TODO: allow callback on nvm eviction instead of checking it
512+
// repeatedly.
505513
if (config_.checkNvmCacheWarmUp &&
506514
folly::Random::oneIn(kNvmCacheWarmUpCheckRate)) {
507515
checkNvmCacheWarmedUp(req.timestamp);

cachelib/cachebench/util/Request.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,15 @@ struct Request {
7878
OpType o,
7979
uint32_t ttl,
8080
uint64_t reqId,
81-
const std::unordered_map<std::string, std::string>& admFeatureM)
81+
const std::unordered_map<std::string, std::string>& admFeatureM,
82+
const std::string& value)
8283
: key(k),
8384
sizeBegin(b),
8485
sizeEnd(e),
8586
ttlSecs(ttl),
8687
requestId(reqId),
8788
admFeatureMap(admFeatureM),
89+
itemValue(value),
8890
op(o) {}
8991

9092
static std::string getUniqueKey() {
@@ -123,6 +125,10 @@ struct Request {
123125
// May not have to be the same as wall clock
124126
uint64_t timestamp{0};
125127

128+
// Use case specific data that will be included in the request. This can be
129+
// used to track metadata that is specific to a particular application.
130+
std::string itemValue;
131+
126132
private:
127133
std::atomic<OpType> op{OpType::kGet};
128134
};

cachelib/cachebench/workload/PieceWiseCache.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ PieceWiseReqWrapper::PieceWiseReqWrapper(
340340
uint32_t ttl,
341341
std::vector<std::string>&& statsAggFieldV,
342342
std::unordered_map<std::string, std::string>&& admFeatureM,
343-
folly::Optional<bool> isHit)
343+
folly::Optional<bool> isHit,
344+
const std::string& itemValue = "")
344345
: baseKey(GenericPieces::escapeCacheKey(key.str())),
345346
pieceKey(baseKey),
346347
sizes(1),
@@ -350,7 +351,8 @@ PieceWiseReqWrapper::PieceWiseReqWrapper(
350351
opType,
351352
ttl,
352353
reqId,
353-
admFeatureM),
354+
admFeatureM,
355+
itemValue),
354356
requestRange(rangeStart, rangeEnd),
355357
headerSize(responseHeaderSize),
356358
fullObjectSize(fullContentSize),
@@ -389,7 +391,8 @@ PieceWiseReqWrapper::PieceWiseReqWrapper(const PieceWiseReqWrapper& other)
389391
other.req.getOp(),
390392
other.req.ttlSecs,
391393
other.req.requestId.value(),
392-
other.req.admFeatureMap),
394+
other.req.admFeatureMap,
395+
other.req.itemValue),
393396
requestRange(other.requestRange),
394397
isHeaderPiece(other.isHeaderPiece),
395398
headerSize(other.headerSize),

cachelib/cachebench/workload/PieceWiseCache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ struct PieceWiseReqWrapper {
282282
// @param ttl: ttl of the content for caching
283283
// @param statsAggFieldV: extra fields used for stats aggregation
284284
// @param admFeatureM: features map for admission policy
285+
// @param itemValue: client-specific data for the item
285286

286287
explicit PieceWiseReqWrapper(
287288
uint64_t cachePieceSize,
@@ -296,7 +297,8 @@ struct PieceWiseReqWrapper {
296297
uint32_t ttl,
297298
std::vector<std::string>&& statsAggFieldV,
298299
std::unordered_map<std::string, std::string>&& admFeatureM,
299-
folly::Optional<bool> isHit);
300+
folly::Optional<bool> isHit,
301+
const std::string& itemValue);
300302

301303
PieceWiseReqWrapper(const PieceWiseReqWrapper& other);
302304
};

cachelib/cachebench/workload/PieceWiseReplayGenerator.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ void PieceWiseReplayGenerator::getReqFromTrace() {
9191
try {
9292
std::vector<folly::StringPiece> fields;
9393
folly::split(",", line, fields);
94-
if (fields.size() != totalFieldCount &&
95-
// TODO: remove this after legacy data phased out.
96-
fields.size() + 1 != totalFieldCount) {
94+
95+
// TODO: remove this after legacy data phased out.
96+
if (fields.size() > totalFieldCount ||
97+
fields.size() < totalFieldCount - 2) {
9798
invalidSamples_.inc();
9899
continue;
99100
}
@@ -234,6 +235,11 @@ void PieceWiseReplayGenerator::getReqFromTrace() {
234235
}
235236
}
236237

238+
const std::string itemValue =
239+
fields.size() == totalFieldCount
240+
? folly::to<std::string>(fields[SampleFields::ITEM_VALUE])
241+
: "";
242+
237243
// Spin until the queue has room
238244
while (!activeReqQ_[shard]->write(config_.cachePieceSize,
239245
timestampSeconds,
@@ -248,7 +254,8 @@ void PieceWiseReplayGenerator::getReqFromTrace() {
248254
ttl,
249255
std::move(statsAggFields),
250256
std::move(admFeatureMap),
251-
cacheHit)) {
257+
cacheHit,
258+
itemValue)) {
252259
if (shouldShutdown()) {
253260
XLOG(INFO) << "Forced to stop, terminate reading trace file!";
254261
return;

cachelib/cachebench/workload/PieceWiseReplayGenerator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ class PieceWiseReplayGenerator : public ReplayGeneratorBase {
135135
TTL,
136136
SAMPLING_RATE,
137137
CACHE_HIT,
138-
TOTAL_DEFINED_FIELDS = 11
138+
ITEM_VALUE,
139+
TOTAL_DEFINED_FIELDS = 12
139140
};
140141

141142
TraceFileStream traceStream_;

cachelib/cachebench/workload/tests/PieceWiseCacheTest.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class PieceWiseCacheTest : public ::testing::Test {
3333
std::unordered_map<uint32_t, std::vector<std::string>> statsPerAggField;
3434
std::unordered_map<std::string, std::string> admFeatureMap1, admFeatureMap2,
3535
admFeatureMap3;
36+
std::string itemValue = "";
3637

3738
piecewiseCache =
3839
std::make_unique<PieceWiseCacheAdapter>(/*maxCachePiecesv=*/32000,
@@ -54,7 +55,8 @@ class PieceWiseCacheTest : public ::testing::Test {
5455
/*ttl=*/3600,
5556
/*extraField=*/std::move(extraFieldV1),
5657
/*admFeatureMap=*/std::move(admFeatureMap1),
57-
/*isHit=*/folly::none);
58+
/*isHit=*/folly::none,
59+
/*itemValue=*/itemValue);
5860

5961
// pieceReq2 is stored as multiple pieces, and the range contains a single
6062
// piece
@@ -71,7 +73,8 @@ class PieceWiseCacheTest : public ::testing::Test {
7173
/*ttl=*/3600,
7274
/*extraField=*/std::move(extraFieldV2),
7375
/*admFeatureMap=*/std::move(admFeatureMap2),
74-
/*isHit=*/folly::none);
76+
/*isHit=*/folly::none,
77+
/*itemValue=*/itemValue);
7578

7679
// nonPieceReq is stored as whole object
7780
nonPieceReq = std::make_unique<PieceWiseReqWrapper>(
@@ -87,7 +90,8 @@ class PieceWiseCacheTest : public ::testing::Test {
8790
/*ttl=*/3600,
8891
/*extraField=*/std::move(extraFieldV3),
8992
/*admFeatureMap=*/std::move(admFeatureMap3),
90-
/*isHit=*/folly::none);
93+
/*isHit=*/folly::none,
94+
/*itemValue=*/itemValue);
9195
}
9296

9397
std::unique_ptr<PieceWiseCacheAdapter> piecewiseCache;

0 commit comments

Comments
 (0)