-
Notifications
You must be signed in to change notification settings - Fork 0
/
qe.h
314 lines (261 loc) · 10.1 KB
/
qe.h
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#ifndef _qe_h_
#define _qe_h_
#include <vector>
#include "../rbf/rbfm.h"
#include "../rm/rm.h"
#include "../ix/ix.h"
# define QE_EOF (-1) // end of the index scan
# define MAX_ATTRI_NUM 1020 //max number of attributes in a temp page
using namespace std;
typedef enum{ MIN = 0, MAX, SUM, AVG, COUNT } AggregateOp;
// The following functions use the following
// format for the passed data.
// For INT and REAL: use 4 bytes
// For VARCHAR: use 4 bytes for the length followed by
// the characters
struct Value {
AttrType type; // type of value
void *data; // value
};
struct Condition {
string lhsAttr; // left-hand side attribute
CompOp op; // comparison operator
bool bRhsIsAttr; // TRUE if right-hand side is an attribute and not a value; FALSE, otherwise.
string rhsAttr; // right-hand side attribute if bRhsIsAttr = TRUE
Value rhsValue; // right-hand side value if bRhsIsAttr = FALSE
};
class Iterator {
// All the relational operators and access methods are iterators.
public:
virtual RC getNextTuple(void *data) = 0;
virtual void getAttributes(vector<Attribute> &attrs) const = 0;
virtual ~Iterator() {};
};
class TableScan : public Iterator
{
// A wrapper inheriting Iterator over RM_ScanIterator
public:
RelationManager &rm;
RM_ScanIterator *iter;
string tableName;
vector<Attribute> attrs;
vector<string> attrNames;
RID rid;
TableScan(RelationManager &rm, const string &tableName, const char *alias = NULL):rm(rm)
{
//Set members
this->tableName = tableName;
// Get Attributes from RM
rm.getAttributes(tableName, attrs);
// Get Attribute Names from RM
unsigned i;
for(i = 0; i < attrs.size(); ++i)
{
// convert to char *
attrNames.push_back(attrs[i].name);
}
// Call rm scan to get iterator
iter = new RM_ScanIterator();
rm.scan(tableName, "", NO_OP, NULL, attrNames, *iter);
// Set alias
if(alias) this->tableName = alias;
};
// Start a new iterator given the new compOp and value
void setIterator()
{
iter->close();
delete iter;
iter = new RM_ScanIterator();
rm.scan(tableName, "", NO_OP, NULL, attrNames, *iter);
};
RC getNextTuple(void *data)
{
return iter->getNextTuple(rid, data);
};
void getAttributes(vector<Attribute> &attrs) const
{
attrs.clear();
attrs = this->attrs;
unsigned i;
// For attribute in vector<Attribute>, name it as rel.attr
for(i = 0; i < attrs.size(); ++i)
{
string tmp = tableName;
tmp += ".";
tmp += attrs[i].name;
attrs[i].name = tmp;
}
};
~TableScan()
{
iter->close();
};
};
class IndexScan : public Iterator
{
// A wrapper inheriting Iterator over IX_IndexScan
public:
RelationManager &rm;
RM_IndexScanIterator *iter;
string tableName;
string attrName;
vector<Attribute> attrs;
char key[PAGE_SIZE];
RID rid;
IndexScan(RelationManager &rm, const string &tableName, const string &attrName, const char *alias = NULL):rm(rm)
{
// Set members
this->tableName = tableName;
this->attrName = attrName;
// Get Attributes from RM
rm.getAttributes(tableName, attrs);
// Call rm indexScan to get iterator
iter = new RM_IndexScanIterator();
rm.indexScan(tableName, attrName, NULL, NULL, true, true, *iter);
// Set alias
if(alias) this->tableName = alias;
};
// Start a new iterator given the new key range
void setIterator(void* lowKey,
void* highKey,
bool lowKeyInclusive,
bool highKeyInclusive)
{
iter->close();
delete iter;
iter = new RM_IndexScanIterator();
rm.indexScan(tableName, attrName, lowKey, highKey, lowKeyInclusive,
highKeyInclusive, *iter);
};
RC getNextTuple(void *data)
{
int rc = iter->getNextEntry(rid, key);
if(rc == 0)
{
rc = rm.readTuple(tableName.c_str(), rid, data);
}
return rc;
};
void getAttributes(vector<Attribute> &attrs) const
{
attrs.clear();
attrs = this->attrs;
unsigned i;
// For attribute in vector<Attribute>, name it as rel.attr
for(i = 0; i < attrs.size(); ++i)
{
string tmp = tableName;
tmp += ".";
tmp += attrs[i].name;
attrs[i].name = tmp;
}
};
~IndexScan()
{
iter->close();
};
};
class Filter : public Iterator {
// Filter operator
public:
Filter(Iterator *input, // Iterator of input R
const Condition &condition // Selection condition
);
~Filter(){};
RC getNextTuple(void *data) {return QE_EOF;};
// For attribute in vector<Attribute>, name it as rel.attr
void getAttributes(vector<Attribute> &attrs) const{};
};
class Project : public Iterator {
// Projection operator
public:
Project(Iterator *input, // Iterator of input R
const vector<string> &attrNames){}; // vector containing attribute names
~Project(){};
RC getNextTuple(void *data) {return QE_EOF;};
// For attribute in vector<Attribute>, name it as rel.attr
void getAttributes(vector<Attribute> &attrs) const{};
};
class GHJoin : public Iterator {
// Grace hash join operator
public:
GHJoin(Iterator *leftIn, // Iterator of input R
Iterator *rightIn, // Iterator of input S
const Condition &condition, // Join condition (CompOp is always EQ)
const unsigned numPartitions // # of partitions for each relation (decided by the optimizer)
);
~GHJoin(){};
RC getNextTuple(void *data);
// For attribute in vector<Attribute>, name it as rel.attr
void getAttributes(vector<Attribute> &attrs) const;
private:
RC Partitons(unsigned numPartitions,Condition condition);
int partitionHash(const void *data, const Attribute attrs,unsigned numPartitions);
int getAttribute(const unsigned int attriNum,const vector<Attribute> attrs,const void*data, const string attributeName, void *attribute);
int insertAttrToTempPage(FileHandle filehandle,int partitionNum,void *dataPage,const void* attribute,const Attribute attr);
// suffixNum=0;
private:
Iterator *leftIn;
Iterator *rightIn;
Condition condition;
unsigned numPartitions;
RecordBasedFileManager *rbfm;
static int suffixNum;
static int jPartition;
static int jPageNum;
static int jSlotNum;
};
int GHJoin::suffixNum=0;
int GHJoin::jPartition=0;
int GHJoin::jPageNum=0;
int GHJoin::jSlotNum=1;
class BNLJoin : public Iterator {
// Block nested-loop join operator
public:
BNLJoin(Iterator *leftIn, // Iterator of input R
TableScan *rightIn, // TableScan Iterator of input S
const Condition &condition, // Join condition
const unsigned numRecords // # of records can be loaded into memory, i.e., memory block size (decided by the optimizer)
){};
~BNLJoin(){};
RC getNextTuple(void *data){return QE_EOF;};
// For attribute in vector<Attribute>, name it as rel.attr
void getAttributes(vector<Attribute> &attrs) const{};
};
class INLJoin : public Iterator {
// Index nested-loop join operator
public:
INLJoin(Iterator *leftIn, // Iterator of input R
IndexScan *rightIn, // IndexScan Iterator of input S
const Condition &condition // Join condition
){};
~INLJoin(){};
RC getNextTuple(void *data){return QE_EOF;};
// For attribute in vector<Attribute>, name it as rel.attr
void getAttributes(vector<Attribute> &attrs) const{};
};
class Aggregate : public Iterator {
// Aggregation operator
public:
// Mandatory for graduate teams only
// Basic aggregation
Aggregate(Iterator *input, // Iterator of input R
Attribute aggAttr, // The attribute over which we are computing an aggregate
AggregateOp op // Aggregate operation
){};
// Optional for everyone. 5 extra-credit points
// Group-based hash aggregation
Aggregate(Iterator *input, // Iterator of input R
Attribute aggAttr, // The attribute over which we are computing an aggregate
Attribute groupAttr, // The attribute over which we are grouping the tuples
AggregateOp op, // Aggregate operation
const unsigned numPartitions // Number of partitions for input (decided by the optimizer)
){};
~Aggregate(){};
RC getNextTuple(void *data){return QE_EOF;};
// Please name the output attribute as aggregateOp(aggAttr)
// E.g. Relation=rel, attribute=attr, aggregateOp=MAX
// output attrname = "MAX(rel.attr)"
void getAttributes(vector<Attribute> &attrs) const{};
};
#endif