Skip to content
API Documentation
BastionGuard™
bad_block_map.cpp
Go to the documentation of this file.
1#include "bad_block_map.hpp"
2
3#include <algorithm>
4
5void BadBlockMap::mark_readable(uint64_t offset, uint64_t length) {
6 mark(offset, length, RangeState::Readable);
7}
8
9void BadBlockMap::mark_bad(uint64_t offset, uint64_t length) {
10 mark(offset, length, RangeState::Bad);
11}
12
13void BadBlockMap::mark_slow(uint64_t offset, uint64_t length) {
14 mark(offset, length, RangeState::Slow);
15}
16
17std::vector<BlockRange> BadBlockMap::readable_ranges() const {
19}
20
21std::vector<BlockRange> BadBlockMap::bad_ranges() const {
23}
24
25std::vector<BlockRange> BadBlockMap::slow_ranges() const {
27}
28
29bool BadBlockMap::is_known_bad(uint64_t offset, uint64_t length) const {
30 const uint64_t end = offset + length;
31 for (const auto& range : ranges_) {
32 if (range.state != RangeState::Bad) continue;
33 const uint64_t range_end = range.offset + range.length;
34 if (offset < range_end && end > range.offset) {
35 return true;
36 }
37 }
38 return false;
39}
40
42 if (ranges_.empty()) return;
43
44 std::sort(ranges_.begin(), ranges_.end(), [](const BlockRange& a, const BlockRange& b) {
45 if (a.state != b.state) return static_cast<int>(a.state) < static_cast<int>(b.state);
46 return a.offset < b.offset;
47 });
48
49 std::vector<BlockRange> merged;
50 merged.reserve(ranges_.size());
51 merged.push_back(ranges_.front());
52
53 for (size_t i = 1; i < ranges_.size(); ++i) {
54 auto& last = merged.back();
55 const auto& current = ranges_[i];
56 const uint64_t last_end = last.offset + last.length;
57
58 if (last.state == current.state && current.offset <= last_end) {
59 const uint64_t new_end = std::max<uint64_t>(last_end, current.offset + current.length);
60 last.length = new_end - last.offset;
61 } else {
62 merged.push_back(current);
63 }
64 }
65
66 std::sort(merged.begin(), merged.end(), [](const BlockRange& a, const BlockRange& b) {
67 return a.offset < b.offset;
68 });
69
70 ranges_.swap(merged);
71}
72
73void BadBlockMap::mark(uint64_t offset, uint64_t length, RangeState state) {
74 if (length == 0) return;
75 ranges_.push_back(BlockRange{offset, length, state});
77}
78
79std::vector<BlockRange> BadBlockMap::filtered(RangeState state) const {
80 std::vector<BlockRange> out;
81 for (const auto& range : ranges_) {
82 if (range.state == state) out.push_back(range);
83 }
84 return out;
85}
RangeState
bool is_known_bad(uint64_t offset, uint64_t length) const
std::vector< BlockRange > readable_ranges() const
std::vector< BlockRange > bad_ranges() const
void mark(uint64_t offset, uint64_t length, RangeState state)
std::vector< BlockRange > ranges_
void merge_adjacent()
std::vector< BlockRange > slow_ranges() const
std::vector< BlockRange > filtered(RangeState state) const
void mark_readable(uint64_t offset, uint64_t length)
void mark_slow(uint64_t offset, uint64_t length)
void mark_bad(uint64_t offset, uint64_t length)