util: add SumTree::iterator

Change-Id: I8304b64634fa3ab92a126fe5d942674b26334b3d
This commit is contained in:
Horst Schirmeier
2015-01-14 23:39:33 +01:00
parent 2f70e05db6
commit f8e0f1bb3f
2 changed files with 66 additions and 1 deletions

View File

@ -4,6 +4,7 @@
#include <assert.h>
#include <stdint.h>
#include <vector>
#include <stack>
// The SumTree implements an efficient tree data structure for
// "roulette-wheel" sampling, or "sampling with fault expansion", i.e.,
@ -44,6 +45,64 @@ class SumTree {
std::vector<T> elements;
};
public:
//! Iterator
class TreeIterator : public std::iterator<std::input_iterator_tag, T> {
//! Buckets and corresponding element indexes down the tree
std::stack<std::pair<Bucket *, unsigned> > hierarchy;
public:
TreeIterator() {}
//MyIterator(int* x) :p(x) {}
TreeIterator(const TreeIterator& i) : hierarchy(i.hierarchy) { }
TreeIterator(const SumTree<T, BUCKETSIZE>& tree)
{
// go down until we see leaves
hierarchy.push(std::pair<Bucket *, unsigned>(tree.m_root, 0));
while (!hierarchy.top().first->elements.size() && hierarchy.top().first->children.size() > 0) {
hierarchy.push(std::pair<Bucket *, unsigned>(hierarchy.top().first->children[hierarchy.top().second], 0));
}
}
TreeIterator& operator++()
{
// advance index in the current level
hierarchy.top().second++;
if (hierarchy.top().second < hierarchy.top().first->elements.size()) {
return *this;
}
// current level is exhausted, go back up to a not yet finished level
do {
hierarchy.pop();
} while (!hierarchy.empty()
&& ++hierarchy.top().second >= hierarchy.top().first->children.size());
// at the end?
if (hierarchy.empty()) {
return *this;
}
// go down until we see leaves again
do {
hierarchy.push(std::pair<Bucket *, unsigned>(hierarchy.top().first->children[hierarchy.top().second], 0));
} while (!hierarchy.top().first->elements.size() && hierarchy.top().first->children.size() > 0);
return *this;
}
TreeIterator operator++(int) { TreeIterator tmp(*this); operator++(); return tmp; }
bool operator==(const TreeIterator& rhs) { return hierarchy == rhs.hierarchy; }
bool operator!=(const TreeIterator& rhs) { return hierarchy != rhs.hierarchy; }
T& operator*() { return hierarchy.top().first->elements[hierarchy.top().second]; }
T *operator->() { return &(operator*()); }
};
typedef TreeIterator iterator;
iterator begin()
{
return iterator(*this);
}
iterator end()
{
return iterator();
}
private:
//! Root node
Bucket *m_root;
//! Tree depth: nodes at level m_depth are leaf nodes, others are inner nodes

View File

@ -17,13 +17,19 @@ struct Pilot {
int main()
{
fail::SumTree<Pilot, 2> tree;
typedef fail::SumTree<Pilot, 2> sumtree_type;
sumtree_type tree;
for (int i = 0; i <= 20; ++i) {
Pilot p;
p.duration = i;
tree.add(p);
}
LOG << "tree contents:" << endl;
for (sumtree_type::iterator it = tree.begin(); it != tree.end(); ++it) {
LOG << it->size() << endl;
}
while (tree.get_size() > 0) {
uint64_t pos = tree.get_size() / 2;
LOG << "MAIN tree.get_size() = " << tree.get_size()