163 const int node = GetLeafFromEvent(event);
169template <
typename IntegerType>
171 DCHECK(!leaf_nodes_have_delayed_operations_);
172 return tree_[1].envelope;
174template <
typename IntegerType>
176 DCHECK(!leaf_nodes_have_delayed_operations_);
177 return tree_[1].envelope_opt;
180template <
typename IntegerType>
182 IntegerType target_envelope)
const {
183 DCHECK(!leaf_nodes_have_delayed_operations_);
184 DCHECK_LT(target_envelope, tree_[1].envelope);
186 return GetEventFromLeaf(
187 GetMaxLeafWithEnvelopeGreaterThan(1, target_envelope, &unused));
190template <
typename IntegerType>
192 IntegerType target_envelope,
int* critical_event,
int* optional_event,
193 IntegerType* available_energy)
const {
194 DCHECK(!leaf_nodes_have_delayed_operations_);
197 GetLeavesWithOptionalEnvelopeGreaterThan(target_envelope, &critical_leaf,
198 &optional_leaf, available_energy);
199 *critical_event = GetEventFromLeaf(critical_leaf);
200 *optional_event = GetEventFromLeaf(optional_leaf);
203template <
typename IntegerType>
205 DCHECK(!leaf_nodes_have_delayed_operations_);
206 const int leaf = GetLeafFromEvent(event);
207 IntegerType envelope = tree_[leaf].envelope;
208 for (
int node = leaf; node > 1; node >>= 1) {
209 const int right = node | 1;
210 if (node != right) envelope += tree_[right].sum_of_energy_min;
215template <
typename IntegerType>
217 TreeNode* tree = tree_.data();
219 const int right = node | 1;
220 const int left = right ^ 1;
222 tree[node] = ComposeTreeNodes(tree[left], tree[right]);
226template <
typename IntegerType>
227int ThetaLambdaTree<IntegerType>::GetMaxLeafWithEnvelopeGreaterThan(
228 int node, IntegerType target_envelope, IntegerType* extra)
const {
229 DCHECK(!leaf_nodes_have_delayed_operations_);
230 DCHECK_LT(target_envelope, tree_[node].envelope);
231 while (node < num_leaves_) {
232 const int left = node << 1;
233 const int right = left | 1;
234 DCHECK_LT(right, tree_.size());
236 if (target_envelope < tree_[right].envelope) {
239 target_envelope -= tree_[right].sum_of_energy_min;
243 *extra = tree_[node].envelope - target_envelope;
247template <
typename IntegerType>
248int ThetaLambdaTree<IntegerType>::GetLeafWithMaxEnergyDelta(
int node)
const {
249 DCHECK(!leaf_nodes_have_delayed_operations_);
250 const IntegerType delta_node = tree_[node].max_of_energy_delta;
251 while (node < num_leaves_) {
252 const int left = node << 1;
253 const int right = left | 1;
254 DCHECK_LT(right, tree_.size());
255 if (tree_[right].max_of_energy_delta == delta_node) {
258 DCHECK_EQ(tree_[left].max_of_energy_delta, delta_node);
265template <
typename IntegerType>
266void ThetaLambdaTree<IntegerType>::GetLeavesWithOptionalEnvelopeGreaterThan(
267 IntegerType target_envelope,
int* critical_leaf,
int* optional_leaf,
268 IntegerType* available_energy)
const {
269 DCHECK(!leaf_nodes_have_delayed_operations_);
270 DCHECK_LT(target_envelope, tree_[1].envelope_opt);
272 while (node < num_leaves_) {
273 const int left = node << 1;
274 const int right = left | 1;
275 DCHECK_LT(right, tree_.size());
277 if (target_envelope < tree_[right].envelope_opt) {
280 const IntegerType opt_energy_right =
281 tree_[right].sum_of_energy_min + tree_[right].max_of_energy_delta;
282 if (target_envelope < tree_[left].envelope + opt_energy_right) {
283 *optional_leaf = GetLeafWithMaxEnergyDelta(right);
285 *critical_leaf = GetMaxLeafWithEnvelopeGreaterThan(
286 left, target_envelope - opt_energy_right, &extra);
287 *available_energy = tree_[*optional_leaf].sum_of_energy_min +
288 tree_[*optional_leaf].max_of_energy_delta - extra;
291 target_envelope -= tree_[right].sum_of_energy_min;
296 *critical_leaf = node;
297 *optional_leaf = node;
298 *available_energy = target_envelope - (tree_[node].envelope_opt -
299 tree_[node].sum_of_energy_min -
300 tree_[node].max_of_energy_delta);
303template class ThetaLambdaTree<IntegerValue>;
304template class ThetaLambdaTree<int64_t>;