Project
Loading...
Searching...
No Matches
SegmentTree.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#ifndef O2_MCH_CONTOUR_SEGMENTTREE_H
16#define O2_MCH_CONTOUR_SEGMENTTREE_H
17
18#include <vector>
19#include <ostream>
20#include <algorithm>
21#include "Interval.h"
22
23namespace o2
24{
25namespace mch
26{
27namespace contour
28{
29namespace impl
30{
31
32template <typename T>
33class Node
34{
35 public:
36 Node() = delete;
37
38 explicit Node(Interval<T> i, T midpoint);
39
41
42 Node* left() const { return mLeftChild; }
43
44 Node* right() const { return mRightChild; }
45
46 int cardinality() const { return mCardinality; }
47
48 // for testing
49 void setCardinality(int c) { mCardinality = c; }
50
51 void increaseCardinality() { ++mCardinality; }
52
53 void decreaseCardinality() { --mCardinality; }
54
55 bool goLeft(const Interval<T>& i) const
56 {
58 return isStrictlyBelow(i.begin(), midpoint());
59 }
60
61 bool goRight(const Interval<T>& i) const
62 {
64 return isStrictlyBelow(midpoint(), i.end());
65 }
66
67 bool isPotent() const { return mIsPotent; }
68
69 Node& potent(bool v)
70 {
71 mIsPotent = v;
72 return *this;
73 }
74
75 T midpoint() const { return mMidpoint; }
76
77 Interval<T> interval() const { return mInterval; }
78
80
82
84 {
85 mLeftChild = left;
86 return *this;
87 }
88
90 {
91 mRightChild = right;
92 return *this;
93 }
94
96
97 void update();
98
99 void promote();
100
101 void demote();
102
103 bool isLeaf() const { return left() == nullptr && right() == nullptr; }
104
105 std::vector<const Node*> getNodeList() const;
106
107 private:
108 Node* mLeftChild;
109 Node* mRightChild;
110
111 Interval<T> mInterval;
112 T mMidpoint; // midpoint (not necessarily exactly half)
113 int mCardinality; // cardinality
114 bool mIsPotent; // potent state
115};
116
117template <typename T>
118Node<T>* buildNode(const std::vector<T>& values, int b, int e)
119{
121 int mid((b + e) / 2);
122 Node<T>* node = new Node<T>(i, values[mid]);
123 if (e - b == 1) {
124 return node;
125 }
126 node->setLeft(buildNode<T>(values, b, mid)).setRight(buildNode<T>(values, mid, e));
127 return node;
128}
129
130template <typename T>
131bool isActive(const Node<T>& node)
132{
133 return node.cardinality() > 0 || node.isPotent();
134}
135
136template <typename T>
138{
139 if (values.size() < 2) {
140 throw std::invalid_argument("must get at least two values");
141 }
142
143 std::sort(values.begin(), values.end());
144
145 return buildNode(values, 0, values.size() - 1);
146}
147
148template <typename T>
150 : mInterval(i), mMidpoint(m), mCardinality(0), mIsPotent(false), mLeftChild(nullptr), mRightChild(nullptr)
151{
152}
153
154template <typename T>
156{
157 delete mLeftChild;
158 delete mRightChild;
159}
160
161template <typename T>
163{
165 if (cardinality()) {
166 return;
167 }
168 if (interval().isFullyContainedIn(i) && !isPotent()) {
169 if (edgeStack.empty()) {
170 edgeStack.push_back(interval());
171 } else {
172 auto& back = edgeStack.back();
173 if (!back.extend(interval())) {
174 // add a new segment if it can not be merged with current one
175 edgeStack.push_back(interval());
176 }
177 }
178 } else {
179 if (goLeft(i)) {
180 left()->contribution(i, edgeStack);
181 }
182 if (goRight(i)) {
183 right()->contribution(i, edgeStack);
184 }
185 }
186}
187
188template <typename T>
189void dump(const char* msg, const Node<T>& node, const Interval<T>& i)
190{
191 std::cout << msg << "(" << i << ") into mInterval=" << node.interval() << " midpoint=" << node.midpoint();
192 std::cout << " isFullyContained=" << node.interval().isFullyContainedIn(i) << " cardinality=" << node.cardinality()
193 << (node.goLeft(i) ? " -L- " : " -R- ");
194
195 if (areEqual(i.begin(), node.midpoint())) {
196 std::cout << " WARNING BEGIN=MID";
197 }
198 if (areEqual(i.end(), node.midpoint())) {
199 std::cout << " WARNING END=MID";
200 }
201}
202
203template <typename T>
205{
206 if (interval().isFullyContainedIn(i)) {
207 increaseCardinality();
208 } else {
209 if (goLeft(i)) {
210 left()->insertInterval(i);
211 }
212 if (goRight(i)) {
213 right()->insertInterval(i);
214 }
215 }
216 update();
217}
218
219template <typename T>
221{
222 if (interval().isFullyContainedIn(i)) {
223 decreaseCardinality();
224 } else {
225 if (cardinality() > 0) {
226 demote();
227 }
228 if (goLeft(i)) {
229 left()->deleteInterval(i);
230 }
231 if (goRight(i)) {
232 right()->deleteInterval(i);
233 }
234 }
235 update();
236}
237
238template <typename T>
240{
241 if (left() == nullptr) {
242 potent(false);
243 } else {
244 if (left()->cardinality() > 0 && right()->cardinality() > 0) {
245 promote();
246 }
247 potent(!(!isActive(*left()) && !isActive(*right())));
248 }
249}
250
251template <typename T>
253{
255 right()->decreaseCardinality();
256 increaseCardinality();
257}
258
259template <typename T>
261{
263 right()->increaseCardinality();
264 decreaseCardinality();
265 potent(true);
266}
267
268template <typename T>
269std::vector<const Node<T>*> Node<T>::getNodeList() const
270{
271 if (isLeaf()) {
272 return {this};
273 }
274 auto l = left()->getNodeList();
275 auto r = right()->getNodeList();
276 l.insert(l.end(), r.begin(), r.end());
277 return l;
278}
279
280template <typename T>
281int numberOfLeaves(const Node<T>& rootNode)
282{
283 auto v = rootNode.getNodeList();
284 return std::count_if(v.begin(), v.end(), [](const Node<T>* node) { return node->isLeaf(); });
285}
286
287template <typename T>
288std::ostream& operator<<(std::ostream& os, const Node<T>& node)
289{
290 auto w = os.width();
291 os << node.interval();
292 if (node.cardinality()) {
293 os << " C=" << node.cardinality();
294 }
295 if (node.isPotent()) {
296 os << " potent";
297 }
298 os << '\n';
299 os.width(w + 6);
300 if (!node.isLeaf()) {
301 os << (*node.left());
302 os << (*node.right());
303 }
304 os.width(w);
305 return os;
306}
307
308} // namespace impl
309} // namespace contour
310} // namespace mch
311} // namespace o2
312
313#endif
int32_t i
uint32_t c
Definition RawData.h:2
void insertInterval(Interval< T > i)
bool goLeft(const Interval< T > &i) const
Definition SegmentTree.h:55
std::vector< const Node * > getNodeList() const
void deleteInterval(Interval< T > i)
Node & setLeft(Node *left)
Definition SegmentTree.h:83
Node & setRight(Node *right)
Definition SegmentTree.h:89
void contribution(Interval< T > i, std::vector< o2::mch::contour::impl::Interval< T > > &edgeStack)
bool goRight(const Interval< T > &i) const
Definition SegmentTree.h:61
Node(Interval< T > i, T midpoint)
Interval< T > interval() const
Definition SegmentTree.h:77
const GLfloat * m
Definition glcorearb.h:4066
const GLdouble * v
Definition glcorearb.h:832
GLdouble GLdouble right
Definition glcorearb.h:4077
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint left
Definition glcorearb.h:1979
GLenum GLsizei GLsizei GLint * values
Definition glcorearb.h:1576
GLboolean r
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
bool isActive(const Node< T > &node)
void dump(const char *msg, const Node< T > &node, const Interval< T > &i)
Interval< T > interval(const VerticalEdge< T > &edge)
Node< T > * buildNode(const std::vector< T > &values, int b, int e)
bool isStrictlyBelow(double a, double b)
Definition Helper.h:48
bool areEqual(double a, double b)
Definition Helper.h:41
int numberOfLeaves(const Node< T > &rootNode)
std::ostream & operator<<(std::ostream &os, const ManhattanEdge< T > &edge)
Definition Edge.h:150
Node< T > * createSegmentTree(std::vector< T > values)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint64_t const void const *restrict const msg
Definition x9.h:153