GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
49 / 50
98.0%
Branches:
36 / 44
81.8%
Functions:
8 / 8
100.0%

scene/extent_cache.cpp
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file extent_cache.cpp
3 /// @brief Replaying row changes into the extent boxes and recomputing stale runs.
4 #include "ernie/scene/extent_cache.h"
5
6 #include <algorithm>
7
8 namespace ernie {
9
10 715 void ExtentCache::Track(BucketId bucket, ExtentFunction compute) {
11
1/2
✓ Branch 0 taken 715 times.
✗ Branch 1 not taken.
1430 buckets_.resize(std::max<std::size_t>(buckets_.size(), bucket + 1));
12 715 buckets_[bucket].compute = compute;
13 715 }
14
15 62 void ExtentCache::Update(const PrimStore& store) {
16 62 const ChangeSet changes = store.ChangesSince(cursor_);
17
2/2
✓ Branch 0 taken 1344 times.
✓ Branch 1 taken 62 times.
1406 for (const ChangeSet::Rows& rows : changes.rows) {
18
2/2
✓ Branch 0 taken 1295 times.
✓ Branch 1 taken 49 times.
1344 if (Tracked(rows.bucket)) {
19
1/2
✓ Branch 1 taken 1295 times.
✗ Branch 2 not taken.
1295 Replay(buckets_[rows.bucket], rows.change);
20 }
21 }
22
2/2
✓ Branch 0 taken 633 times.
✓ Branch 1 taken 62 times.
695 for (const ChangeSet::Values& values : changes.values) {
23
2/2
✓ Branch 0 taken 596 times.
✓ Branch 1 taken 37 times.
633 if (Tracked(values.bucket)) {
24
2/2
✓ Branch 0 taken 865 times.
✓ Branch 1 taken 596 times.
1461 for (const RowRange range : values.rows) {
25 865 buckets_[values.bucket].stale.SetRange(range.begin, range.end);
26 }
27 }
28 }
29
2/2
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 62 times.
217 for (BucketId bucket = 0; bucket < buckets_.size(); ++bucket) {
30
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 2 times.
155 if (Tracked(bucket) && store.GetBucket(bucket).version > cursor_) {
31
1/2
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
66 Refresh(buckets_[bucket], store, bucket);
32 }
33 }
34 62 cursor_ = changes.version;
35 62 }
36
37 13601 std::optional<Box> ExtentCache::Find(const PrimStore& store, BucketId bucket,
38 std::uint32_t row) const {
39
5/6
✓ Branch 0 taken 13585 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 13434 times.
✓ Branch 3 taken 151 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13434 times.
13601 if (!Tracked(bucket) || store.GetBucket(bucket).version > cursor_ ||
40
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13434 times.
13434 row >= buckets_[bucket].boxes.size()) {
41 167 return std::nullopt;
42 }
43 13434 return buckets_[bucket].boxes[row];
44 }
45
46 15733 bool ExtentCache::Tracked(BucketId bucket) const {
47
3/4
✓ Branch 0 taken 15733 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 189 times.
✓ Branch 3 taken 15544 times.
15733 return bucket < buckets_.size() && buckets_[bucket].compute != nullptr;
48 }
49
50 1295 void ExtentCache::Replay(Entry& entry, const StructuralChange& change) {
51 1295 using Kind = StructuralChange::Kind;
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1295 times.
1295 if (change.kind == Kind::Reset) {
53 ✗ Resize(entry, 0);
54 }
55
2/2
✓ Branch 0 taken 819 times.
✓ Branch 1 taken 476 times.
1295 if (change.kind == Kind::Added || change.kind == Kind::Reset) {
56 819 Resize(entry, change.row + change.count);
57 819 entry.stale.SetRange(change.row, change.row + change.count);
58
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 239 times.
476 } else if (change.kind == Kind::Moved) {
59 // Recomputed, not copied: the moved row's own value edits are reported at its old place.
60 237 entry.stale.Set(change.row);
61 237 Resize(entry, change.from);
62
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 237 times.
239 } else if (change.row + 1 == entry.boxes.size()) {
63 // Removing the last row moves nothing; otherwise the Moved that follows shrinks it.
64 2 Resize(entry, change.row);
65 }
66 1295 }
67
68 1058 void ExtentCache::Resize(Entry& entry, std::uint32_t rows) {
69 1058 entry.boxes.resize(rows);
70 1058 entry.stale.Resize(rows);
71 1058 }
72
73 66 void ExtentCache::Refresh(Entry& entry, const PrimStore& store, BucketId bucket) {
74 66 const ExtentRows columns{store, bucket};
75 66 entry.stale.ForEachRun([&](std::size_t begin, std::size_t end) {
76 75 entry.compute(columns, {static_cast<std::uint32_t>(begin), static_cast<std::uint32_t>(end)},
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
75 std::span(entry.boxes).subspan(begin, end - begin));
78 75 });
79 66 entry.stale.Clear();
80 66 }
81
82 } // namespace ernie
83