407 lines
9.1 KiB
C++
407 lines
9.1 KiB
C++
/*
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2018,
|
|
Faculty of Mathematics and Computer Science,
|
|
Database Systems for New Applications.
|
|
|
|
SECONDO is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SECONDO is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with SECONDO; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
#ifndef ITNode_H_
|
|
#define ITNode_H_
|
|
|
|
#include "BinaryTuple.h"
|
|
#include "sort.h"
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
namespace csj {
|
|
|
|
// structure to reprsent a node in IntSTree
|
|
struct ITNode {
|
|
std::vector<binaryTuple> vtR;
|
|
std::vector<binaryTuple> vtL;
|
|
std::vector<binaryTuple> outL;
|
|
std::vector<binaryTuple> outR;
|
|
double xLeft;
|
|
double xRight;
|
|
double xMedian;
|
|
int height;
|
|
ITNode *left;
|
|
ITNode *right;
|
|
bool rootIsDone;
|
|
bool leftIsDone;
|
|
bool rightIsDone;
|
|
bool nodeIsDone;
|
|
};
|
|
|
|
// function deletes a tree
|
|
void deleteTree(ITNode *root) {
|
|
|
|
if(root == nullptr) {
|
|
return;
|
|
}
|
|
|
|
deleteTree(root->left);
|
|
deleteTree(root->right);
|
|
|
|
root->vtL.clear();
|
|
root->vtR.clear();
|
|
root->outL.clear();
|
|
root->outR.clear();
|
|
delete root;
|
|
root = nullptr;
|
|
}
|
|
|
|
// function to get height of the tree rooted with root
|
|
int getHeight(ITNode *root) {
|
|
|
|
if(root == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
return root->height;
|
|
}
|
|
|
|
// function to get maximum of two integers
|
|
int max(int x, int y) {
|
|
return x > y ? x : y;
|
|
}
|
|
|
|
// function to create a new ITNode
|
|
ITNode *newNode(double xLeft_, double xRight_) {
|
|
|
|
ITNode *node = new ITNode;
|
|
|
|
node->xLeft = xLeft_;
|
|
node->xRight = xRight_;
|
|
node->xMedian = (xRight_ + xLeft_) / 2;
|
|
node->left = nullptr;
|
|
node->right = nullptr;
|
|
node->height = 1;
|
|
node->rootIsDone = false;
|
|
node->leftIsDone = false;
|
|
node->rightIsDone = false;
|
|
node->nodeIsDone = false;
|
|
|
|
return node;
|
|
}
|
|
|
|
// function to right rotate subtree rooted with root
|
|
ITNode *rightRotate(ITNode *root) {
|
|
|
|
ITNode *temp1 = root->left;
|
|
ITNode *temp2 = temp1->right;
|
|
|
|
// perform rotation
|
|
temp1->right = root;
|
|
root->left = temp2;
|
|
|
|
// update heights
|
|
root->height = max(getHeight(root->left), getHeight(root->right)) + 1;
|
|
temp1->height = max(getHeight(temp1->left), getHeight(temp1->right)) + 1;
|
|
|
|
// return new root
|
|
return temp1;
|
|
}
|
|
|
|
// function to left rotate subtree rooted with root
|
|
ITNode *leftRotate(ITNode *root) {
|
|
|
|
ITNode *temp1 = root->right;
|
|
ITNode *temp2 = temp1->left;
|
|
|
|
// perform rotation
|
|
temp1->left = root;
|
|
root->right = temp2;
|
|
|
|
// update heights
|
|
root->height = max(getHeight(root->left), getHeight(root->right)) + 1;
|
|
temp1->height = max(getHeight(temp1->left), getHeight(temp1->right)) + 1;
|
|
|
|
// return new root
|
|
return temp1;
|
|
}
|
|
|
|
// function to get balance of node
|
|
int getBalance(ITNode *node) {
|
|
|
|
if(node == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
return getHeight(node->left) - getHeight(node->right);
|
|
}
|
|
|
|
// function to insert a interval in the subtree rooted with root
|
|
ITNode *insert(ITNode *root, double xLeft_, double xRight_) {
|
|
|
|
if(root == nullptr) {
|
|
return newNode(xLeft_, xRight_);
|
|
}
|
|
|
|
if(xLeft_ < root->xLeft) {
|
|
root->left = insert(root->left, xLeft_, xRight_);
|
|
}
|
|
else
|
|
if(xLeft_ > root->xLeft) {
|
|
root->right = insert(root->right, xLeft_, xRight_);
|
|
}
|
|
else {
|
|
return root;
|
|
}
|
|
|
|
// update height
|
|
root->height = 1 + max(getHeight(root->left), getHeight(root->right));
|
|
|
|
int balance = getBalance(root);
|
|
|
|
// left left case
|
|
if((balance > 1) && (xLeft_ < root->left->xLeft))
|
|
return rightRotate(root);
|
|
|
|
// right right case
|
|
if((balance < -1) && (xLeft_ > root->right->xLeft))
|
|
return leftRotate(root);
|
|
|
|
// left right case
|
|
if((balance > 1) && (xLeft_ > root->left->xLeft)) {
|
|
root->left = leftRotate(root->left);
|
|
return rightRotate(root);
|
|
}
|
|
|
|
// right left case
|
|
if((balance < -1) && (xLeft_ < root->right->xLeft)) {
|
|
root->right = rightRotate(root->right);
|
|
return leftRotate(root);
|
|
}
|
|
|
|
return root;
|
|
} // end of insert
|
|
|
|
// function to create static interval tree
|
|
ITNode *createITree(ITNode *root, double xMin, double xMax,
|
|
uint64_t numOfIntervals) {
|
|
|
|
double tempXLeft;
|
|
double tempXRight;
|
|
|
|
for(uint64_t i = 0; i < numOfIntervals; i++) {
|
|
tempXLeft = xMin + (xMax - xMin)/numOfIntervals*i;
|
|
tempXRight = xMin + (xMax - xMin)/numOfIntervals*(i + 1);
|
|
|
|
root = insert(root, tempXLeft, tempXRight);
|
|
}
|
|
|
|
return root;
|
|
}
|
|
|
|
// function to insert binary tuple
|
|
void sweepPush(ITNode *root, binaryTuple bt) {
|
|
|
|
if(root == nullptr) {
|
|
return;
|
|
}
|
|
|
|
if(bt.xMin <= root->xMedian && bt.xMax >= root->xMedian) {
|
|
root->vtL.push_back(bt);
|
|
root->vtR.push_back(bt);
|
|
MergeSortXLeft(root->vtL);
|
|
MergeSortXRight(root->vtR);
|
|
return;
|
|
}
|
|
else {
|
|
if(bt.xMax < root->xMedian) {
|
|
if(root->left != nullptr) {
|
|
sweepPush(root->left, bt);
|
|
return;
|
|
}
|
|
else {
|
|
root->outL.push_back(bt);
|
|
//MergeSortNode(root->outL);
|
|
return;
|
|
}
|
|
}
|
|
if(bt.xMin > root->xMedian) {
|
|
if(root->right != nullptr) {
|
|
sweepPush(root->right, bt);
|
|
return;
|
|
}
|
|
else {
|
|
root->outR.push_back(bt);
|
|
// MergeSortNode(root->outR);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
} // end of sweepPush
|
|
|
|
void removeFromOutL(ITNode *node, binaryTuple bt) {
|
|
|
|
uint64_t deletePos = 0;
|
|
bool hit = false;
|
|
|
|
// search for tuple
|
|
while(!(deletePos == node->outL.size()) && !hit) {
|
|
if(tuplesAreEqual(bt, node->outL[deletePos])) {
|
|
hit = true;
|
|
}
|
|
else {
|
|
deletePos++;
|
|
}
|
|
} // end of while
|
|
|
|
if(hit) {
|
|
node->outL.erase(node->outL.begin()+deletePos);
|
|
}
|
|
|
|
} // end of removeFRomOutL
|
|
|
|
void removeFromOutR(ITNode *node, binaryTuple bt) {
|
|
|
|
uint64_t deletePos = 0;
|
|
bool hit = false;
|
|
|
|
// search for tuple
|
|
while(!(deletePos == node->outR.size()) && !hit) {
|
|
if(tuplesAreEqual(bt, node->outR[deletePos])) {
|
|
hit = true;
|
|
}
|
|
else {
|
|
deletePos++;
|
|
}
|
|
} // end of while
|
|
|
|
if(hit) {
|
|
node->outR.erase(node->outR.begin()+deletePos);
|
|
}
|
|
|
|
} // end of removeFRomOutR
|
|
|
|
void removeFromLR(ITNode *node, binaryTuple bt) {
|
|
|
|
uint64_t deletePos = 0;
|
|
bool hit = false;
|
|
|
|
// search for tuple
|
|
while(!(deletePos == node->vtL.size()) && !hit) {
|
|
if(tuplesAreEqual(bt, node->vtL[deletePos])) {
|
|
hit = true;
|
|
}
|
|
else {
|
|
deletePos++;
|
|
}
|
|
} // end of while
|
|
|
|
if(hit) {
|
|
node->vtL.erase(node->vtL.begin()+deletePos);
|
|
}
|
|
|
|
deletePos = 0;
|
|
hit = false;
|
|
|
|
// search for tuple
|
|
while(!(deletePos == node->vtR.size()) && !hit) {
|
|
if(tuplesAreEqual(bt, node->vtR[deletePos])) {
|
|
hit = true;
|
|
}
|
|
else {
|
|
deletePos++;
|
|
}
|
|
} // end of while
|
|
|
|
if(hit) {
|
|
node->vtR.erase(node->vtR.begin()+deletePos);
|
|
}
|
|
|
|
} // end of removeFromLR
|
|
|
|
// function to remove binary tuple from tree
|
|
void sweepRemove(ITNode *root, binaryTuple bt) {
|
|
|
|
if(root == nullptr) {
|
|
return;
|
|
}
|
|
|
|
// tuple cut the median by actually root
|
|
if(bt.xMin <= root->xMedian && bt.xMax >= root->xMedian) {
|
|
removeFromLR(root, bt);
|
|
return;
|
|
}
|
|
else {
|
|
// search tuple lies on the left from median
|
|
if(bt.xMax < root->xMedian) {
|
|
if(root->left != nullptr) {
|
|
sweepRemove(root->left, bt);
|
|
return;
|
|
}
|
|
else {
|
|
removeFromOutL(root, bt);
|
|
return;
|
|
}
|
|
} // end of left
|
|
|
|
// search tuple lies on the right from median
|
|
if(bt.xMin > root->xMedian) {
|
|
if(root->right != nullptr) {
|
|
sweepRemove(root->right, bt);
|
|
return;
|
|
}
|
|
else {
|
|
removeFromOutR(root, bt);
|
|
return;
|
|
}
|
|
} // end of right
|
|
} // end of else
|
|
|
|
} // end of sweepRemove
|
|
|
|
// display tree from left to right (root at left)
|
|
void display(ITNode *node, int tab) {
|
|
|
|
if(node != nullptr) {
|
|
display(node->right, tab + 4);
|
|
|
|
for(int i=0; i<tab; i++) {
|
|
cout<<" ";
|
|
}
|
|
|
|
cout<<node->xMedian<<endl;
|
|
|
|
display(node->left, tab + 4);
|
|
}
|
|
} // end of display
|
|
|
|
void stateCleaning(ITNode *node) {
|
|
|
|
if(node == nullptr) {
|
|
return;
|
|
}
|
|
|
|
node->rootIsDone = false;
|
|
node->leftIsDone = false;
|
|
node->rightIsDone = false;
|
|
node->nodeIsDone = false;
|
|
|
|
stateCleaning(node->left);
|
|
stateCleaning(node->right);
|
|
} // end of stateCleaning
|
|
|
|
} // end of namespace csj
|
|
|
|
#endif // ITNode_H_
|