TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
lazy_codes.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// Lattice-indexed obstacle codes that start "not computed" (INT32_MIN) and are allocated in chunks on first write.
4// The router's per-class caches cover the whole board lattice on every layer, but a run touches only the cells its
5// windows reach: a full array per class was 1.6 GB per router on KiCad-Library_Teensy_test_layout, and filling it
6// with INT32_MIN 3-5 % of the run. Reading an unallocated chunk gives INT32_MIN, as the full array did.
7#include <climits>
8#include <cstddef>
9#include <cstdint>
10#include <memory>
11#include <vector>
12
13namespace tmk::route {
14
15class LazyCodes {
16 public:
17 static constexpr std::int32_t kUnknown = INT32_MIN;
18
19 // n entries, all unknown; drops any earlier contents.
20 void init(std::size_t n) {
21 n_ = n;
22 chunks_.clear();
23 chunks_.resize((n + kChunk - 1) / kChunk);
24 }
25 bool empty() const { return n_ == 0; }
26 std::size_t size() const { return n_; }
27
28 // The entry, allocating its chunk (all unknown) if needed.
29 std::int32_t& operator[](std::size_t i) {
30 auto& c = chunks_[i >> kShift];
31 if (!c) {
32 c = std::make_unique<std::int32_t[]>(kChunk);
33 for (std::size_t k = 0; k < kChunk; ++k) c[k] = kUnknown;
34 }
35 return c[i & (kChunk - 1)];
36 }
37 // The entry without allocating: unknown where nothing was written.
38 std::int32_t get(std::size_t i) const {
39 const auto& c = chunks_[i >> kShift];
40 return c ? c[i & (kChunk - 1)] : kUnknown;
41 }
42 // Bytes held by allocated chunks (diagnostics, test).
43 std::size_t bytes() const {
44 std::size_t b = 0;
45 for (const auto& c : chunks_) b += c ? kChunk * sizeof(std::int32_t) : 0;
46 return b;
47 }
48
49 private:
50 static constexpr std::size_t kShift = 12; // 4,096 entries (16 KB): a few lattice rows of a window
51 static constexpr std::size_t kChunk = std::size_t{1} << kShift;
52 std::size_t n_ = 0;
53 std::vector<std::unique_ptr<std::int32_t[]>> chunks_;
54};
55
56} // namespace tmk::route
std::int32_t get(std::size_t i) const
The entry without allocating: unknown where nothing was written.
static constexpr std::int32_t kUnknown
std::int32_t & operator[](std::size_t i)
The entry, allocating its chunk (all unknown) if needed.
std::size_t size() const
void init(std::size_t n)
n entries, all unknown; drops any earlier contents.
std::size_t bytes() const
Bytes held by allocated chunks (diagnostics, test).