Skip to content

Commit

Permalink
cas: fix metric accounting for duplicate keys
Browse files Browse the repository at this point in the history
Summary: If multiple `(path, node)` keys map to the same CAS digest, we were recording the number of digests as "fetch" (i.e. attempt) count, but the number of keys as the "hit" count. This could lead to hit count greater than fetch count. Fix by recording the number of keys as "fetch" count.

Reviewed By: liubov-dmitrieva

Differential Revision: D65067201

fbshipit-source-id: 7db173e8de7d41787f78beb5e9342d90e6331adc
  • Loading branch information
muirdm authored and facebook-github-bot committed Oct 29, 2024
1 parent 5315a47 commit e33e64f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 13 deletions.
16 changes: 9 additions & 7 deletions eden/scm/lib/revisionstore/src/scmstore/file/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,9 @@ impl FetchState {
.collect();

// Include the duplicates in the count.
span.record("keys", digest_with_keys.len());
let keys_fetch_count = digest_with_keys.len();

span.record("keys", keys_fetch_count);

let mut digest_to_key: HashMap<CasDigest, Vec<Key>> = HashMap::default();

Expand All @@ -778,7 +780,7 @@ impl FetchState {

let digests: Vec<CasDigest> = digest_to_key.keys().cloned().collect();

let mut found = 0;
let mut keys_found_count = 0;
let mut error = 0;
let mut reqs = 0;

Expand All @@ -800,7 +802,7 @@ impl FetchState {
tracing::error!("got CAS result for unrequested digest {:?}", digest);
continue;
};
found += keys.len();
keys_found_count += keys.len();
tracing::trace!(target: "cas", ?keys, ?digest, "file(s) prefetched in cas");
for key in keys {
self.found_attributes(
Expand Down Expand Up @@ -848,7 +850,7 @@ impl FetchState {
// miss
}
Ok(Some(data)) => {
found += keys.len();
keys_found_count += keys.len();
tracing::trace!(target: "cas", ?keys, ?digest, "file(s) found in cas");
if !keys.is_empty() {
let last = keys.pop().unwrap();
Expand Down Expand Up @@ -888,14 +890,14 @@ impl FetchState {
});
}

span.record("hits", found);
span.record("hits", keys_found_count);
span.record("requests", reqs);
span.record("time", start_time.elapsed().as_millis() as u64);

let _ = self.metrics.cas.time_from_duration(start_time.elapsed());
self.metrics.cas.fetch(digests.len());
self.metrics.cas.fetch(keys_fetch_count);
self.metrics.cas.err(error);
self.metrics.cas.hit(found);
self.metrics.cas.hit(keys_found_count);
self.metrics
.cas_backend
.zdb_bytes(total_stats.total_bytes_zdb);
Expand Down
14 changes: 8 additions & 6 deletions eden/scm/lib/revisionstore/src/scmstore/tree/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ impl FetchState {
.collect();

// Include the duplicates in the count.
span.record("keys", digest_with_keys.len());
let keys_fetch_count = digest_with_keys.len();

span.record("keys", keys_fetch_count);

let mut digest_to_key: HashMap<CasDigest, Vec<Key>> = HashMap::default();

Expand All @@ -220,7 +222,7 @@ impl FetchState {

let digests: Vec<CasDigest> = digest_to_key.keys().cloned().collect();

let mut found = 0;
let mut keys_found_count = 0;
let mut error = 0;
let mut reqs = 0;

Expand Down Expand Up @@ -251,7 +253,7 @@ impl FetchState {
}
Ok(Some(data)) => match AugmentedTree::try_deserialize(&*data) {
Ok(tree) => {
found += keys.len();
keys_found_count += keys.len();
tracing::trace!(target: "cas", ?keys, ?digest, "tree found in cas");

let lazy_tree = LazyTree::Cas(AugmentedTreeWithDigest {
Expand Down Expand Up @@ -311,14 +313,14 @@ impl FetchState {
}).await;
});

span.record("hits", found);
span.record("hits", keys_found_count);
span.record("requests", reqs);
span.record("time", start_time.elapsed().as_millis() as u64);

let _ = self.metrics.cas.time_from_duration(start_time.elapsed());
self.metrics.cas.fetch(digests.len());
self.metrics.cas.fetch(keys_fetch_count);
self.metrics.cas.err(error);
self.metrics.cas.hit(found);
self.metrics.cas.hit(keys_found_count);
self.metrics
.cas_backend
.zdb_bytes(total_stats.total_bytes_zdb);
Expand Down
7 changes: 7 additions & 0 deletions eden/scm/tests/test-scmstore-cas.t
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,10 @@ And sanity check the counter we are looking for exists:
scmstore.tree.fetch.indexedlog.cache.keys: 1
$ hg debugscmstore -r $A --mode file "dir/file" --config devel.print-metrics=scmstore.file.fetch.indexedlog.cache.keys --config scmstore.fetch-from-cas=false >/dev/null
scmstore.file.fetch.indexedlog.cache.keys: 1

Count duplicate key fetches properly:
$ hg dbsh -c "n = repo['$A']['dir/file'].filenode(); repo.fileslog.filestore.prefetch([('foo', n), ('bar', n)])" --config devel.print-metrics=scmstore.file.fetch.cas >/dev/null
scmstore.file.fetch.cas.hits: 2
scmstore.file.fetch.cas.keys: 2
scmstore.file.fetch.cas.requests: 1
scmstore.file.fetch.cas.time: * (glob)

0 comments on commit e33e64f

Please sign in to comment.