-
Notifications
You must be signed in to change notification settings - Fork 3
/
iterator.cxx
169 lines (142 loc) · 4 KB
/
iterator.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//-< ITERATOR.CXX >--------------------------------------------------*--------*
// Created: 05-Apr-03 Johan Sorensen * / [] \ *
// Last update: 05-Apr-03 Johan Sorensen * GARRET *
//-------------------------------------------------------------------*--------*
// Iterator class implementation
//-------------------------------------------------------------------*--------*
#define INSIDE_POST
#include "iterator.h"
#include "assert.h"
BEGIN_POST_NAMESPACE
Ttree_iterator::Ttree_iterator(dbTtree *t, bool bReverseOrder)
: m_CurrPos(-1)
{
m_CurrNode = (t ? t->root : NULL);
if (m_CurrNode)
{
if (bReverseOrder)
{
// start by going down to the right-most leaf node in the tree
m_CurrPos = m_CurrNode->nItems - 1;
while (m_CurrNode->right != NULL)
{
m_NodeStack.push(m_CurrNode);
m_PositionStack.push(m_CurrPos);
m_CurrNode = m_CurrNode->right;
m_CurrPos = m_CurrNode->nItems - 1;
}
}
else
{
// start by going down to the left-most leaf node in the tree
m_CurrPos = 0;
while (m_CurrNode->left != NULL)
{
m_NodeStack.push(m_CurrNode);
m_PositionStack.push(m_CurrPos);
m_CurrNode = m_CurrNode->left;
}
}
if (m_CurrNode->nItems == 0)
m_CurrPos = -1; // abnormal case to encounter an empty node?!...
}
}
Ttree_iterator::~Ttree_iterator()
{
// m_NodeStack and m_PositionStack will delete themselves :-)
}
bool Ttree_iterator::IsValid () const
{
return m_CurrPos != -1;
}
object* Ttree_iterator::operator* ()
{
if (IsValid())
{
return m_CurrNode->item[m_CurrPos];
}
return NULL;
}
object* Ttree_iterator::operator++ ()
{
if (!IsValid())
return NULL;
// have we traversed the "current" node yet?
if (++m_CurrPos >= m_CurrNode->nItems)
{
// if so, see if there's a child on the right
if (m_CurrNode->right != NULL)
{
m_NodeStack.push(m_CurrNode);
m_PositionStack.push(m_CurrPos);
m_CurrNode = m_CurrNode->right;
m_CurrPos = 0;
// and walk down to the left-most leaf of that branch
while (m_CurrNode->left != NULL)
{
m_NodeStack.push(m_CurrNode);
m_PositionStack.push(m_CurrPos);
m_CurrNode = m_CurrNode->left;
}
}
else
{
// walk up the tree until we find a node we haven't traversed internally yet
size_t s = m_NodeStack.get_size();
while (m_CurrPos >= m_CurrNode->nItems && s > 0)
{
s--;
m_CurrNode = m_NodeStack[s];
m_CurrPos = m_PositionStack[s];
m_NodeStack.set_size(s);
m_PositionStack.set_size(s);
}
if (m_CurrPos >= m_CurrNode->nItems)
m_CurrPos = -1; // we're actually finished!
}
assert(m_CurrNode->nItems > 0);
}
return operator*();
}
object* Ttree_iterator::operator-- ()
{
if (!IsValid())
return NULL;
// have we traversed the "current" node yet?
if (--m_CurrPos < 0)
{
// if so, see if there's a child on the left
if (m_CurrNode->left != NULL)
{
m_NodeStack.push(m_CurrNode);
m_PositionStack.push(m_CurrPos);
m_CurrNode = m_CurrNode->left;
m_CurrPos = m_CurrNode->nItems - 1;
// and walk down to the right-most leaf of that branch
while (m_CurrNode->right != NULL)
{
m_NodeStack.push(m_CurrNode);
m_PositionStack.push(m_CurrPos);
m_CurrNode = m_CurrNode->right;
m_CurrPos = m_CurrNode->nItems - 1;
}
}
else
{
// walk up the tree until we find a node we haven't traversed internally yet
size_t s = m_NodeStack.get_size();
while (m_CurrPos < 0 && s > 0)
{
s--;
m_CurrNode = m_NodeStack[s];
m_CurrPos = m_PositionStack[s];
m_NodeStack.set_size(s);
m_PositionStack.set_size(s);
}
// we're finihsed when we come out here with m_CurrPos == -1
}
assert(m_CurrNode->nItems > 0);
}
return operator*();
}
END_POST_NAMESPACE