blob: 7976ac325add37f8edbd8fd81634765211fc602b [file] [log] [blame]
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -04001/*
2 * Copyright (C) 2014 TeamWin - bigbiff and Dees_Troy mtp database conversion to C++
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <iostream>
18#include <utils/threads.h>
19#include "btree.hpp"
20#include "MtpDebug.h"
21
22// Constructor
23Tree::Tree() {
24 root = NULL;
25 count = 0;
26}
27
28// Destructor
29Tree::~Tree() {
30 freeNode(root);
31}
32
33// Free the node
34void Tree::freeNode(Node* leaf)
35{
36 if ( leaf != NULL )
37 {
38 freeNode(leaf->Left());
39 freeNode(leaf->Right());
40 delete leaf;
41 }
42}
43
44int Tree::getCount(void) {
45 MTPD("node count: %d\n", count);
46 return count;
47}
48
49Node* Tree::addNode(int mtpid, std::string path)
50{
51 MTPD("root: %d\n", root);
52 // No elements. Add the root
53 if ( root == NULL ) {
54 Node* n = new Node();
55 count++;
56 MTPD("node count: %d\n", count);
57 MTPD("adding node address: %d\n", n);
58 MTPD("adding mtpid: %d\n", mtpid);
59 n->setMtpid(mtpid);
60 n->setPath(path);
61 root = n;
62 MTPD("set root to %d\n", root);
63 return n;
64 }
65 else {
66 count++;
67 MTPD("node count: %d\n", count);
68 MTPD("adding new child node\n");
69 return addNode(mtpid, root, path);
70 }
71}
72
73// Add a node (private)
74Node* Tree::addNode(int mtpid, Node* leaf, std::string path) {
75 Node* n;
76 if ( mtpid <= leaf->Mtpid() )
77 {
78 if ( leaf->Left() != NULL )
79 return addNode(mtpid, leaf->Left(), path);
80 else {
81 n = new Node();
82 MTPD("adding mtpid: %d node: %d\n", mtpid, n);
83 n->setMtpid(mtpid);
84 n->setPath(path);
85 n->setParent(leaf);
86 leaf->setLeft(n);
87 }
88 }
89 else
90 {
91 if ( leaf->Right() != NULL )
92 return addNode(mtpid, leaf->Right(), path);
93 else {
94 n = new Node();
95 MTPD("adding mtpid: %d node: %d\n", mtpid, n);
96 n->setMtpid(mtpid);
97 n->setPath(path);
98 n->setParent(leaf);
99 leaf->setRight(n);
100 }
101 }
102 return n;
103}
104
105void Tree::setMtpParentId(int mtpparentid, Node* node) {
106 node->setMtpParentId(mtpparentid);
107}
108
109std::string Tree::getPath(Node* node) {
110 return node->getPath();
111}
112
113int Tree::getMtpParentId(Node* node) {
114 return node->getMtpParentId();
115}
116
117Node* Tree::findNodePath(std::string path, Node* node) {
118 Node* n;
119 if ( node == NULL ) {
120 return NULL;
121 }
122 if ( node->getPath().compare(path) == 0 && node->Mtpid() > 0) {
123 return node;
124 }
125 else {
126 n = findNodePath(path, node->Left());
127 if (n)
128 return n;
129 n = findNodePath(path, node->Right());
130 if (n)
131 return n;
132 }
133 return NULL;
134}
135
136Node* Tree::getNext(Node *node) {
137 if (node == NULL)
138 return NULL;
139 else {
140 if (node->Left() != NULL)
141 return node->Left();
142 if (node->Right() != NULL)
143 return node->Right();
144 }
145 return NULL;
146}
147
148Node* Tree::findNode(int key, Node* node) {
149 //MTPD("key: %d\n", key);
150 //MTPD("node: %d\n", node);
151 if ( node == NULL ) {
152 return NULL;
153 }
154 else if ( node->Mtpid() == key ) {
155 return node;
156 }
157 else if ( key <= node->Mtpid() ) {
158 return findNode(key, node->Left());
159 }
160 else if ( key > node->Mtpid() ) {
161 return findNode(key, node->Right());
162 }
163 else {
164 return NULL;
165 }
166 return NULL;
167}
168
169void Tree::getmtpids(Node* node, std::vector<int>* mtpids)
170{
171 if ( node )
172 {
173 MTPD("node: %d\n", node->Mtpid());
174 mtpids->push_back(node->Mtpid());
175 if (node->Left())
176 getmtpids(node->Left(), mtpids);
177 if (node->Right())
178 getmtpids(node->Right(), mtpids);
179 } else {
180 mtpids->push_back(0);
181 }
182 return;
183}
184
185// Find the node with min key
186// Traverse the left sub-tree recursively
187// till left sub-tree is empty to get min
188Node* Tree::min(Node* node)
189{
190 if ( node == NULL )
191 return NULL;
192
193 if ( node->Left() )
194 min(node->Left());
195 else
196 return node;
197 return NULL;
198}
199
200// Find the node with max key
201// Traverse the right sub-tree recursively
202// till right sub-tree is empty to get max
203Node* Tree::max(Node* node)
204{
205 if ( node == NULL )
206 return NULL;
207
208 if ( node->Right() )
209 max(node->Right());
210 else
211 return node;
212 return NULL;
213}
214
215// Find successor to a node
216// Find the node, get the node with max value
217// for the right sub-tree to get the successor
218Node* Tree::successor(int key, Node *node)
219{
220 Node* thisKey = findNode(key, node);
221 if ( thisKey )
222 return max(thisKey->Right());
223 return NULL;
224}
225
226// Find predecessor to a node
227// Find the node, get the node with max value
228// for the left sub-tree to get the predecessor
229Node* Tree::predecessor(int key, Node *node)
230{
231 Node* thisKey = findNode(key, node);
232 if ( thisKey )
233 return max(thisKey->Left());
234 return NULL;
235}
236
237void Tree::deleteNode(int key)
238{
239 // Find the node.
240 Node* thisKey = findNode(key, root);
241 MTPD("Tree::deleteNode found node: %d\n", thisKey);
242 MTPD("handle: %d\n", thisKey->Mtpid());
243
244 if (thisKey == root) {
245 if (thisKey->Right()) {
246 root = thisKey->Right();
247 root->setParent(NULL);
248 return;
249 }
250 if (thisKey->Left()) {
251 root = thisKey->Left();
252 root->setParent(NULL);
253 return;
254 }
255 root = NULL;
256 delete thisKey;
257 return;
258 }
259
260 if ( thisKey->Left() == NULL && thisKey->Right() == NULL )
261 {
262 if ( thisKey->Mtpid() > thisKey->Parent()->Mtpid() ) {
263 thisKey->Parent()->setRight(NULL);
264 }
265 else {
266 thisKey->Parent()->setLeft(NULL);
267 }
268 delete thisKey;
269 return;
270 }
271
272 if ( thisKey->Left() == NULL && thisKey->Right() != NULL )
273 {
274 if ( thisKey->Mtpid() > thisKey->Parent()->Mtpid() )
275 thisKey->Parent()->setRight(thisKey->Right());
276 else
277 thisKey->Parent()->setLeft(thisKey->Right());
278 thisKey->Right()->setParent(thisKey->Parent());
279 delete thisKey;
280 return;
281 }
282 if ( thisKey->Left() != NULL && thisKey->Right() == NULL )
283 {
284 if ( thisKey->Mtpid() > thisKey->Parent()->Mtpid() )
285 thisKey->Parent()->setRight(thisKey->Left());
286 else
287 thisKey->Parent()->setLeft(thisKey->Left());
288 thisKey->Left()->setParent(thisKey->Parent());
289 delete thisKey;
290 return;
291 }
292
293 if ( thisKey->Left() != NULL && thisKey->Right() != NULL )
294 {
295 Node* sub = predecessor(thisKey->Mtpid(), thisKey);
296 if ( sub == NULL )
297 sub = successor(thisKey->Mtpid(), thisKey);
298
299 if ( sub->Parent()->Mtpid() <= sub->Mtpid() )
300 sub->Parent()->setRight(sub->Right());
301 else
302 sub->Parent()->setLeft(sub->Left());
303
304 thisKey->setMtpid(sub->Mtpid());
305 delete sub;
306 return;
307 }
308}