Skip to content

Commit f967246

Browse files
authored
Added Files via Upload
1 parent d3aaf2a commit f967246

10 files changed

+1274
-2
lines changed

B+ Tree.cpp

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <algorithm>
4+
#include <fstream>
5+
#include <string>
6+
#include<bits/stdc++.h>
7+
#include <dirent.h>
8+
//#include <filesystem>
9+
#include "B+ Tree.h"
10+
11+
12+
#define _CRT_SECURE_NO_DEPRECATE //for VS 2019
13+
14+
15+
16+
17+
bool hasEnding (std::string const &fullString, std::string const &ending)
18+
{
19+
if (fullString.length() >= ending.length())
20+
{
21+
return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
22+
} else
23+
{
24+
return false;
25+
}
26+
}
27+
28+
29+
void printvec(vector<string> vec)
30+
{
31+
for (auto a : vec)
32+
cout<<a<<" ";
33+
cout << endl;
34+
}
35+
36+
void printvec(vector<int> vec)
37+
{
38+
for (auto a : vec)
39+
cout<<a<<" ";
40+
cout << endl;
41+
}
42+
43+
44+
inline bool file_exists(string name) {
45+
name="./DBFiles/"+name+".txt";
46+
//cout<<"Checking if "<<name<<" exists"<<endl;
47+
if (FILE *file = fopen(name.c_str(), "r"))
48+
{
49+
fclose(file);
50+
return true;
51+
} else
52+
{
53+
return false;
54+
}
55+
}
56+
57+
58+
inline bool isNumber(const string str)
59+
{
60+
for (char const &c : str) {
61+
if (isdigit(c) == 0)
62+
return false;
63+
}
64+
return true;
65+
}
66+
67+
68+
69+
70+
void importMethod(BPTree** bPTree)
71+
{
72+
int ch;
73+
while(1)
74+
{
75+
cout<<"\n\n\t\t\tWARNING!!"<<endl;
76+
cout<<"This option is to import multiple record files into the tree at once.\nIt will scan the DBFiles folder and place all the files of the format \"RecordNo.txt\" in the B+ Tree.\nIt will insert only the Files/Records which are not already present in the tree\n\n";
77+
cout<<"STEPS TO IMPORT :\n";
78+
cout<<"\t1.Place the record text files in the DBFiles Folder\n\t2.Rename each file to the Record Number(The key that has to be used by B+ Tree)\n\nTo Continue \t: \tEnter 1\nTo Abort \t: \tEnter 2\nEnter your choice : ";
79+
cin>>ch;
80+
if(ch==2)
81+
return;
82+
else if(ch==1)
83+
break;
84+
else cout<<"Enter a valid choice.\n";
85+
};
86+
DIR *dir;
87+
struct dirent *diread;
88+
vector<string> files;
89+
90+
if ((dir = opendir("./DBFiles")) != nullptr) {
91+
while ((diread = readdir(dir)) != nullptr) {
92+
files.push_back(diread->d_name);
93+
}
94+
closedir (dir);
95+
} else {
96+
perror ("opendir");
97+
exit(1);
98+
}
99+
vector<string> textfiles;
100+
for (auto file : files)
101+
{
102+
if (hasEnding(file,".txt"))
103+
textfiles.push_back(file.substr(0,file.size()-4));
104+
};
105+
vector<int> numbers;
106+
for (auto file : textfiles)
107+
{
108+
if (isNumber(file))
109+
{
110+
if(file_exists(file))
111+
numbers.push_back(atoi(file.c_str()));
112+
}
113+
};
114+
//printvec(numbers);
115+
if(numbers.size()==0)
116+
{
117+
cout<<"No eligible files found for importing!\n";
118+
return;
119+
}
120+
for(int i=0;i<numbers.size();i++)
121+
{
122+
if((*bPTree)->search(numbers[i]).second==-1)
123+
{
124+
string fileName = "./DBFiles/";
125+
fileName += to_string(numbers[i]) + ".txt";
126+
FILE* filePtr = fopen(fileName.c_str(), "r");
127+
(*bPTree)->insert(numbers[i], filePtr);
128+
cout << "Insertion of Record No. : " << numbers[i] << " Successful"<<endl;
129+
};
130+
};
131+
}
132+
133+
134+
135+
136+
137+
138+
void insertionMethod(BPTree** bPTree) {
139+
int rNo,dose;
140+
string name,vaccine,mNo;
141+
142+
cout << "Please provide the Record No. : ";
143+
cin >> rNo;
144+
145+
cout<<"Record "<<rNo<<" details :\n";
146+
cout << "Name : ";
147+
cin >> name ;
148+
cout<<"Mobile No. : ";
149+
cin>>mNo;
150+
cout<<"Vaccine(Covishield/Covaxin) : ";
151+
cin>> vaccine ;
152+
cout<<"Dose number(1/2) : ";
153+
cin>> dose;
154+
155+
string fileName = "DBFiles/";
156+
fileName += to_string(rNo) + ".txt";
157+
FILE* filePtr = fopen(fileName.c_str(), "w");
158+
string userTuple = name + " " + mNo + " " + vaccine +" "+ to_string(dose) + "\n";
159+
fprintf(filePtr, userTuple.c_str());
160+
fclose(filePtr);
161+
filePtr = fopen(fileName.c_str(), "r");
162+
(*bPTree)->insert(rNo, filePtr);
163+
//fclose(filePtr);
164+
cout << "Insertion of Record No. : " << rNo << " Successful"<<endl;
165+
}
166+
167+
void searchMethod(BPTree* bPTree) {
168+
int rNo;
169+
cout << "What's the Record No. to Search? ";
170+
cin >> rNo;
171+
pair<Node*,int> found=bPTree->search(rNo);
172+
if(found.second==-1)
173+
cout<<"Key Not found\n";
174+
else
175+
{
176+
Node* cursor=found.first;
177+
int idx=found.second;
178+
cout << "Hurray!! Key FOUND" << endl;
179+
cout << "Corresponding Tuple Data is: ";
180+
char ch = fgetc(cursor->ptr2TreeOrData.dataPtr[idx]);
181+
while (ch != EOF) {
182+
printf("%c", ch);
183+
ch = fgetc(cursor->ptr2TreeOrData.dataPtr[idx]);
184+
};
185+
cout<<endl;
186+
};
187+
}
188+
189+
void printMethod(BPTree* bPTree) {
190+
int opt;
191+
cout << "Press \n\t1.Hierarical-Display \n\t2.Sequential-Display\n";
192+
cin >> opt;
193+
if (opt == 1)
194+
bPTree->display(bPTree->getRoot());
195+
else
196+
bPTree->seqDisplay(bPTree->getRoot());
197+
}
198+
199+
void deleteMethod(BPTree* bPTree) {
200+
cout << "Showing you the Tree, Choose a key from here: " << endl;
201+
bPTree->display(bPTree->getRoot());
202+
203+
int tmp;
204+
cout << "Enter a key to delete: " << endl;
205+
cin >> tmp;
206+
bPTree->removeKey(tmp);
207+
208+
//Displaying
209+
bPTree->display(bPTree->getRoot());
210+
}
211+
212+
int main() {
213+
/*
214+
Please have a look at the default schema to get to know about the table
215+
Reference - img/database.jpg
216+
*/
217+
218+
cout << "\n***Welcome to DATABASE SERVER***\n"
219+
<< endl;
220+
221+
bool flag = true;
222+
int option;
223+
224+
int maxChildInt = 4, maxNodeLeaf = 3;
225+
cout << "Please provide the value to limit maximum child Internal Nodes can have: ";
226+
cin >> maxChildInt;
227+
cout << "\nAnd Now Limit the value to limit maximum Nodes Leaf Nodes can have: ";
228+
cin >> maxNodeLeaf;
229+
230+
BPTree* bPTree = new BPTree(maxChildInt, maxNodeLeaf);
231+
232+
do {
233+
cout << "\nPlease provide the queries with respective keys : " << endl;
234+
cout << "\tPress 1: Import \n\tPress 2: Insertion \n\tPress 3: Search \n\tPress 4: Print Tree\n\tPress 5: Delete Key In Tree\n\tPress 6: ABORT!" << endl;
235+
cin >> option;
236+
237+
switch (option) {
238+
case 1:
239+
importMethod(&bPTree);
240+
break;
241+
case 2:
242+
insertionMethod(&bPTree);
243+
break;
244+
case 3:
245+
searchMethod(bPTree);
246+
break;
247+
case 4:
248+
printMethod(bPTree);
249+
break;
250+
case 5:
251+
deleteMethod(bPTree);
252+
break;
253+
case 6:
254+
flag=false;
255+
break;
256+
default:
257+
cout<<"Enter valid option !"<<endl;
258+
}
259+
}while (flag);
260+
261+
return 0;
262+
}

B+ Tree.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <algorithm>
4+
#include <fstream>
5+
#include <string>
6+
#include<bits/stdc++.h>
7+
//#include <filesystem>
8+
using namespace std;
9+
10+
#ifndef NODE_H
11+
#define NODE_H
12+
13+
class Node {
14+
/*
15+
Generally size of the this node should be equal to the block size. Which will limit the number of disk access and increase the accesssing time.
16+
Intermediate nodes only hold the Tree pointers which is of considerably small size(so they can hold more Tree pointers) and only Leaf nodes hold
17+
the data pointer directly to the disc.
18+
19+
IMPORTANT := All the data has to be present in the leaf node
20+
*/
21+
public:
22+
bool isLeaf;
23+
vector<int> keys;
24+
//Node* ptr2parent; //Pointer to go to parent node CANNOT USE check https://stackoverflow.com/questions/57831014/why-we-are-not-saving-the-parent-pointer-in-b-tree-for-easy-upward-traversal-in
25+
Node* ptr2next; //Pointer to connect next node for leaf nodes
26+
union ptr { //to make memory efficient Node
27+
vector<Node*> ptr2Tree; //Array of pointers to Children sub-trees for intermediate Nodes
28+
vector<FILE*> dataPtr; // Data-Pointer for the leaf node
29+
30+
ptr(); // To remove the error !?
31+
~ptr(); // To remove the error !?
32+
} ptr2TreeOrData;
33+
34+
friend class BPTree; // to access private members of the Node and hold the encapsulation concept
35+
public:
36+
Node();
37+
};
38+
39+
class BPTree {
40+
/*
41+
::For Root Node :=
42+
The root node has, at least two tree pointers
43+
::For Internal Nodes:=
44+
1. ceil(maxIntChildLimit/2) <= #of children <= maxIntChildLimit
45+
2. ceil(maxIntChildLimit/2)-1 <= #of keys <= maxIntChildLimit -1
46+
::For Leaf Nodes :=
47+
1. ceil(maxLeafNodeLimit/2) <= #of keys <= maxLeafNodeLimit -1
48+
*/
49+
private:
50+
int maxIntChildLimit; //Limiting #of children for internal Nodes!
51+
int maxLeafNodeLimit; // Limiting #of nodes for leaf Nodes!!!
52+
Node* root; //Pointer to the B+ Tree root
53+
void insertInternal(int x, Node** cursor, Node** child); //Insert x from child in cursor(parent)
54+
Node** findParent(Node* cursor, Node* child);
55+
Node* firstLeftNode(Node* cursor);
56+
57+
public:
58+
BPTree();
59+
BPTree(int degreeInternal, int degreeLeaf);
60+
Node* getRoot();
61+
int getMaxIntChildLimit();
62+
int getMaxLeafNodeLimit();
63+
void setRoot(Node *);
64+
void display(Node* cursor);
65+
void seqDisplay(Node* cursor);
66+
pair<Node*,int> search(int key);
67+
void insert(int key, FILE* filePtr);
68+
void removeKey(int key);
69+
void removeInternal(int x, Node* cursor, Node* child);
70+
};
71+
72+
73+
#endif

B+Tree.exe

399 KB
Binary file not shown.

0 commit comments

Comments
 (0)