Gaia
descriptortree.h
1 /*
2  * Copyright (C) 2006-2013 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Gaia
5  *
6  * Gaia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef GAIA_DESCRIPTORTREE_H
21 #define GAIA_DESCRIPTORTREE_H
22 
23 #include <QList>
24 #include <QStringList>
25 #include "region.h"
26 #include "gaia.h"
27 
28 // OMFG is there no other way to do this?
29 #define NOCONST_CALL(f) const_cast<DescriptorTree*>(const_cast<const DescriptorTree*>(this)->f)
30 
31 namespace gaia2 {
32 
38 
39  public:
40  // constructors
42  DescriptorTree(const QString& name, DescriptorType type,
43  DescriptorLengthType ltype = VariableLength, int size = 1);
44 
45  // destructor
46  ~DescriptorTree();
47 
48  // copy-constructor, assignment operator and equality comparison
49  protected:
50  DescriptorTree(const DescriptorTree& rhs);
51  DescriptorTree& operator=(const DescriptorTree& rhs);
52 
53  public:
54  bool operator==(const DescriptorTree& rhs) const;
55 
60  bool subtreeOf(const DescriptorTree* other) const;
61 
68  DescriptorTree* copy() const;
69 
74  void clear();
75 
79  QString name() const { return _segment.name; }
80 
88  QString fullName(bool recurseDown = true) const;
89 
94  DescriptorType type() const;
95 
101 
102  const DescriptorTree* parent() const { return _parent; }
103  DescriptorTree* parent() { return _parent; }
104 
108  bool isLeaf() const { return _children.empty(); }
109 
113  const DescriptorTree* root() const;
114 
118  DescriptorTree* root() { return NOCONST_CALL(root()); }
119 
124  void addChild(DescriptorTree* t);
125 
132  bool addChild(const QString& name, DescriptorType type,
133  DescriptorLengthType ltype = VariableLength, int size = 1);
134 
139  void removeChild(DescriptorTree* child);
140 
147  void removeNode(const QString& name, bool recurse = true);
148 
155  void removeNodes(const QStringList& names, bool recurse = true);
156 
157 
158 
164  void fixLength(int length);
165 
171  void enumerate();
172 
176  QString descriptorName(DescriptorType type, DescriptorLengthType ltype, int index) const;
177 
182  QStringList descriptorNames() const;
183 
184 
189  Region correspondingRegion() const;
190 
191 
197  void updateLayout();
198 
202  DescriptorTree* findSimple(const QString& name);
203 
208  const DescriptorTree* find(const QString& name) const;
209  DescriptorTree* find(const QString& name) { return NOCONST_CALL(find(name)); }
210 
216  const DescriptorTree* findFromRoot(const QString& name) const;
217  DescriptorTree* findFromRoot(const QString& name) { return NOCONST_CALL(findFromRoot(name)); }
218 
219 
223  const DescriptorTree* findLeaf(const QString& name) const;
224  DescriptorTree* findLeaf(const QString& name) { return NOCONST_CALL(findLeaf(name)); }
225 
226  int regionSize(DescriptorType type, DescriptorLengthType ltype) const;
227 
228  // intended for debug only
229  void printLeafSegments() const;
230 
236  QString toYaml(int spaces = 0) const;
237 
238  // this checks if the regiontree is in a consistent state. This includes the
239  // following criteria up to now:
240  // - the segment in each leaf node has to be of size 1;
241  // - all leaf nodes should have a type which is not Undefined
242  void checkConsistency() const;
243 
248  void modify();
249 
250 
251  protected:
252  Segment _segment; // should always be of size 1
253  // that is not necessarily true anymore, now that we have fixed length descriptors in the game, or is it?
254  DescriptorTree* _parent;
255  QList<DescriptorTree*> _children;
256 
257 
258  bool _modified;
259  bool _hashModified;
260 
261  struct CachedValues {
262  uint hash;
263  QList<DescriptorTree*> dfs;
264  QList<const DescriptorTree*> dfsConst;
265  QList<DescriptorTree*> leaves;
266  QList<const DescriptorTree*> leavesConst;
267  int realSize, stringSize, enumSize;
268  int realSizeFixed, stringSizeFixed, enumSizeFixed;
269  };
270 
271  mutable struct CachedValues _cache;
272 
277  QList<DescriptorTree*> nodes();
278  QList<DescriptorTree*> leaves();
279 
280  QList<const DescriptorTree*> nodes() const;
281  QList<const DescriptorTree*> leaves() const;
282 
283  QList<const DescriptorTree*> dfsNoCache() const;
284 
285  int regionSizeNoCache(DescriptorType type, DescriptorLengthType ltype) const;
286 
287  void reorder() const;
288  void recomputeCaches() const;
289  void recomputeHash() const;
290 
295  uint hash() const;
296 
300  void detach();
301 
306  void updateSegments(const QList<DescriptorTree*>& lrt) const;
307 
308  // find the given branch within this tree, starting at its root. Returns 0 if not found.
309  // if onlyLeaves is set to true, only returns those branches that end in a leaf
310  const DescriptorTree* find(const QStringList& nodeList, bool onlyLeaves, int i=0) const;
311 
312  friend QDataStream& operator<<(QDataStream& out, const DescriptorTree& tree);
313  friend QDataStream& operator>>(QDataStream& in, DescriptorTree& tree);
314 };
315 
316 
317 } // namespace gaia2
318 
319 
320 #endif // GAIA_DESCRIPTORTREE_H
DescriptorLengthType lengthType() const
Returns the length type of this node.
Definition: descriptortree.cpp:93
void modify()
Function to be called by each non const function as soon as it modifies the tree, so as to know when ...
Definition: descriptortree.cpp:133
QString toYaml(int spaces=0) const
Returns a yaml string representing the hierachy of descriptors that this tree represents.
Definition: descriptortree.cpp:636
A region is a physical location in the point layout which consists in a list of segments.
Definition: region.h:125
Region correspondingRegion() const
Returns a Region formed by the merged segments of all the children of this node.
Definition: descriptortree.cpp:280
DescriptorTree * copy() const
Make a deep-copy of this region-tree.
Definition: descriptortree.cpp:66
void updateSegments(const QList< DescriptorTree * > &lrt) const
Updates the segments&#39; begin and end indices so that all segments are contiguous and sorted alphabetic...
Definition: descriptortree.cpp:518
void removeChild(DescriptorTree *child)
Removes given DescriptorTree from this node&#39;s children.
Definition: descriptortree.cpp:170
void clear()
Resets this tree to a single root node.
Definition: descriptortree.cpp:114
void removeNode(const QString &name, bool recurse=true)
Remove the node with the given fully-qualified name.
Definition: descriptortree.cpp:180
const DescriptorTree * find(const QString &name) const
Find the node with given name (be it a leaf or not).
Definition: descriptortree.cpp:358
void removeNodes(const QStringList &names, bool recurse=true)
Remove the list of nodes with the given fully-qualified name.
Definition: descriptortree.cpp:188
void enumerate()
Sets this descriptor to be an enumeration.
Definition: descriptortree.cpp:231
Definition: descriptortree.h:37
A segment is a physical contiguous location of descriptors of the same type in the point layout...
Definition: region.h:75
void updateLayout()
This function takes all the segments of the current DescriptorTree, orders them by type and by alphab...
Definition: descriptortree.cpp:545
const DescriptorTree * findFromRoot(const QString &name) const
Find the node with the given name (be it a leaf or not).
Definition: descriptortree.cpp:374
DescriptorLengthType
Either fixed-length or variable-length.
Definition: region.h:46
QList< DescriptorTree * > nodes()
Returns all the nodes of this tree in a list, corresponding to a DFS search.
Definition: descriptortree.cpp:481
Main Gaia namespace, which contains all the library functions.
Definition: addfield.cpp:22
void detach()
detach this tree from its (possible) current parent.
Definition: descriptortree.cpp:151
void addChild(DescriptorTree *t)
Add the given DescriptorTree to this node&#39;s children.
Definition: descriptortree.cpp:159
QStringList descriptorNames() const
Returns a list of all the descriptor names contained in this layout.
Definition: descriptortree.cpp:262
QString fullName(bool recurseDown=true) const
Returns the fully-qualified name of this node, eg: using the names of the nodes from the root down to...
Definition: descriptortree.cpp:75
Definition: descriptortree.h:261
DescriptorTree * findSimple(const QString &name)
Find the node in this tree that has the given (short) name.
Definition: descriptortree.cpp:304
void fixLength(int length)
Sets this descriptor to be of the specified fixed length.
Definition: descriptortree.cpp:219
DescriptorType
The possible types of descriptors accepted.
Definition: region.h:36
const DescriptorTree * findLeaf(const QString &name) const
Find the leaf with given name.
Definition: descriptortree.cpp:315
DescriptorType type() const
Returns the type of this node.
Definition: descriptortree.cpp:85
bool subtreeOf(const DescriptorTree *other) const
Returns whether this tree is a subset of the given one (e.g.
Definition: descriptortree.cpp:608
const DescriptorTree * root() const
Returns the root of the tree which this node pertains to.
Definition: descriptortree.cpp:128
DescriptorTree * root()
Returns the root of the tree which this node pertains to.
Definition: descriptortree.h:118
QString descriptorName(DescriptorType type, DescriptorLengthType ltype, int index) const
Returns the name of the descriptor which is located at given position.
Definition: descriptortree.cpp:250
QString name() const
Returns the name of the current node.
Definition: descriptortree.h:79
bool isLeaf() const
Returns whether this node is a leaf (terminal node) or not.
Definition: descriptortree.h:108