Anchors
C++ library for Incremental Computing
engine.h
1// engine.h
2#ifndef ANCHORS_ENGINE_H
3#define ANCHORS_ENGINE_H
4
5#include "anchor.h"
6#include "anchorutil.h"
7
8#include <memory>
9#include <queue>
10#include <unordered_set>
11
12namespace anchors {
13
19class Engine {
20 public:
25
40 template <typename T>
41 T get(const AnchorPtr<T>& anchor);
42
53 template <typename T>
54 void set(AnchorPtr<T>& anchor, T val);
55
63 template <typename T>
64 void observe(AnchorPtr<T>& anchor);
65
72 template <typename T>
73 void observe(std::vector<AnchorPtr<T>>& anchors);
74
80 template <typename T>
81 void unobserve(AnchorPtr<T>& anchor);
82
83 private:
84 // PRIVATE TYPES
85 template <class T>
86 using min_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
87
88 // PRIVATE MANIPULATORS
89 void stabilize();
90 // Brings all observed Anchors up-to-date.
91
92 void observeNode(std::shared_ptr<AnchorBase>& current,
93 std::unordered_set<std::shared_ptr<AnchorBase>>&);
94 // Marks all the dependencies of the given Anchor as necessary and adds
95 // stale Anchors to the recompute heap;
96
97 void unobserveNode(std::shared_ptr<AnchorBase>& current);
98 // Removes `current` from the set of observed Anchors.
99 // Also decrements the 'necessary' count and removes `current` as a
100 // dependant of each of its dependencies.
101
102 // PRIVATE DATA
103 int d_stabilizationNumber;
104 // Current stabilization number of the engine. We use this number to
105 // represent when an Anchor value was recomputed and/or changed.
106
107 std::unordered_set<std::shared_ptr<AnchorBase>> d_observedNodes;
108 // Set of observed Anchors.
109
110 min_heap<std::shared_ptr<AnchorBase>> d_recomputeHeap;
111 // Priority queue containing Anchors that need to be recomputed, in
112 // increasing order of their heights.
113
114 std::unordered_set<std::shared_ptr<AnchorBase>> d_recomputeSet;
115 // Set of Anchors present in the recompute queue.
116
117 // std::priority_queue<std::shared_ptr<AnchorBase>> d_adjustHeightsHeap;
118 // // Update the adjust-heights heap when setUpdater is called. Will use
119 // later.
120};
121
122template <typename T>
123T Engine::get(const AnchorPtr<T>& anchor) {
124 if (d_observedNodes.contains(anchor)) {
125 stabilize();
126 }
127
128 return anchor->get();
129}
130
131template <typename T>
132void Engine::set(AnchorPtr<T>& anchor, T val) {
133 T oldVal = anchor->get();
134
135 if (oldVal == val) return;
136 d_stabilizationNumber++;
137
138 anchor->setChangeId(d_stabilizationNumber);
139 anchor->set(val);
140
141 if (anchor->isNecessary()) {
142 for (const auto& dependant : anchor->getDependants()) {
143 if (dependant->isNecessary() &&
144 !d_recomputeSet.contains(dependant)) {
145 d_recomputeHeap.push(dependant);
146 d_recomputeSet.insert(dependant);
147 }
148 }
149 }
150}
151
152template <typename T>
154 if (d_observedNodes.contains(anchor)) {
155 return;
156 }
157
158 d_observedNodes.insert(anchor);
159
160 std::unordered_set<std::shared_ptr<AnchorBase>> visited;
161 std::shared_ptr<AnchorBase> anchorBase = anchor;
162 observeNode(anchorBase, visited);
163}
164
165template <typename T>
167 for (auto& anchor : anchors) {
168 observe(anchor);
169 }
170}
171
172template <typename T>
174 if (!d_observedNodes.contains(anchor)) {
175 return;
176 }
177
178 d_observedNodes.erase(anchor);
179
180 std::shared_ptr<AnchorBase> anchorBase = anchor;
181 unobserveNode(anchorBase);
182}
183
184} // namespace anchors
185#endif
Engine is the brain of Anchors, containing the necessary functions and data to retrieve the value of ...
Definition: engine.h:19
Engine()
Creates an instance of the Engine class.
void set(AnchorPtr< T > &anchor, T val)
Sets the value of the given Anchor.
Definition: engine.h:132
void observe(AnchorPtr< T > &anchor)
Marks an Anchor as observed.
Definition: engine.h:153
T get(const AnchorPtr< T > &anchor)
Returns the value of the given Anchor.
Definition: engine.h:123
void unobserve(AnchorPtr< T > &anchor)
Marks an Anchor as unobserved.
Definition: engine.h:173
Main library namespace.
Definition: anchor.h:32
std::shared_ptr< AnchorWrap< T > > AnchorPtr
Alias representing a shared pointer to an Anchor of output type T.
Definition: anchorutil.h:15