-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIndexManager.cpp
More file actions
387 lines (364 loc) · 9.99 KB
/
IndexManager.cpp
File metadata and controls
387 lines (364 loc) · 9.99 KB
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
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
//
// IndexManager.cpp
// Minisql
//
// Created by 陈泓宇 on 2017/6/20.
// Copyright (c) 2017年 陈泓宇. All rights reserved.
//
#include "IndexManager.h"
#include <iostream>
#include "API.h"
#include "IndexInfo.h"
#include <vector>//用到迭代器
using namespace std;
/**
* Constructor Function: create the existing index by the index files.//构造函数
*
* @param API*
*/
IndexManager::IndexManager(API *m_api)//API在API.h和API.cpp里
{
api = m_api;
vector<IndexInfo> allIndexInfo;
api->allIndexAddressInfoGet(&allIndexInfo);//所有索引文件的名字赋值给向量allIndexInfo
for(vector<IndexInfo>::iterator i = allIndexInfo.begin();i != allIndexInfo.end();i ++)//第一个索引信息,到最后一个
{
createIndex(i->indexName, i->type);//每一个创建索引,初始化一颗新的b+树,将具体的索引文件名和b+关联起来
}
}
/**
* Destructor Function: write the dirty indexs back to the disk.
*
*/
IndexManager::~IndexManager()
{
//write back to the disk
for(intMap::iterator itInt = indexIntMap.begin();itInt != indexIntMap.end(); itInt ++)
{
if(itInt->second)//若第二个值value不为0,则写灰磁盘,再删除
{
itInt -> second->writtenbackToDiskAll();
delete itInt->second;
}
}
for(stringMap::iterator itString = indexStringMap.begin();itString != indexStringMap.end(); itString ++)
{
if(itString->second)
{
itString ->second-> writtenbackToDiskAll();
delete itString->second;
}
}
for(floatMap::iterator itFloat = indexFloatMap.begin();itFloat != indexFloatMap.end(); itFloat ++)
{
if(itFloat->second)
{
itFloat ->second-> writtenbackToDiskAll();
delete itFloat->second;
}
}
}
/**
* Create index on the specific type.
* If there exists the index before, read data from file path and then rebuild the b+ tree.
*
* @param string the file path
* @param int type
*
* @return void
*
*/
void IndexManager::createIndex(string filePath,int type)
{
int keySize = getKeySize(type);//返回type类型的所占字节数,
int degree = getDegree(type);//B+分叉度数
if(type == TYPE_INT)
{
BPlusTree<int> *tree = new BPlusTree<int>(filePath,keySize,degree);//初始化一棵int型B+树
indexIntMap.insert(intMap::value_type(filePath, tree));
}
else if(type == TYPE_FLOAT)
{
BPlusTree<float> *tree = new BPlusTree<float>(filePath,keySize,degree);
indexFloatMap.insert(floatMap::value_type(filePath, tree));
}
else // string
{
BPlusTree<string> *tree = new BPlusTree<string>(filePath,keySize,degree);
indexStringMap.insert(stringMap::value_type(filePath, tree));
}
}
/**
* Drop the specific index.
*
* @param
*
* @return void
*
*/
void IndexManager::dropIndex(string filePath,int type)
{
if(type == TYPE_INT)
{
intMap::iterator itInt = indexIntMap.find(filePath);//关联器自己组成序列吗?
//Find 返回一个迭代器,指定的排序关键字的第一个元素等于键。如果没有这样的元素存在,则迭代器等于 end()。
if(itInt == indexIntMap.end())
{
cout << "Error:in drop index, no index " << filePath <<" exits" << endl;
return;
}
else
{
delete itInt->second;//删除b+树
indexIntMap.erase(itInt);//擦除迭代器
}
}
else if(type == TYPE_FLOAT)
{
floatMap::iterator itFloat = indexFloatMap.find(filePath);
if(itFloat == indexFloatMap.end())
{
cout << "Error:in drop index, no index " << filePath <<" exits" << endl;
return;
}
else
{
delete itFloat->second;
indexFloatMap.erase(itFloat);
}
}
else // string
{
stringMap::iterator itString = indexStringMap.find(filePath);
if(itString == indexStringMap.end())
{
cout << "Error:in drop index, no index " << filePath <<" exits" << endl;
return;
}
else
{
delete itString->second;
indexStringMap.erase(itString);
}
}
}
/**
* Search the b+ tree by the key and return the value of that key.
* If the key is not in the index, return -1.
*
* @param string the file path.
* @param string key.
* @param int type
*
* @return offsetNumber(int型)
*
*/
offsetNumber IndexManager::searchIndex(string filePath,string key,int type)//失败返回-1,否则返回位置offsetNumber
{
setKey(type, key);
if(type == TYPE_INT)
{
intMap::iterator itInt = indexIntMap.find(filePath);
if(itInt == indexIntMap.end())//序列最后一个说明没有找到
{
cout << "Error:in search index, no index " << filePath <<" exits" << endl;
return -1;
}
else
{
return itInt->second->search(kt.intTmp);
}
}
else if(type == TYPE_FLOAT)
{
floatMap::iterator itFloat = indexFloatMap.find(filePath);
if(itFloat == indexFloatMap.end())
{
cout << "Error:in search index, no index " << filePath <<" exits" << endl;
return -1;
}
else
{
return itFloat->second->search(kt.floatTmp);
}
}
else // string
{
stringMap::iterator itString = indexStringMap.find(filePath);
if(itString == indexStringMap.end())
{
cout << "Error:in search index, no index " << filePath <<" exits" << endl;
return -1;
}
else
{
return itString->second->search(key);
}
}
}
/**
* Insert the key and value to the b+ tree.
*
* @param string the file path
* @param string key
* @param offsetNumber the block offset number
* @param int type
*
* @return void
*
*/
void IndexManager::insertIndex(string filePath,string key,offsetNumber blockOffset,int type)//filePath-索引文件名字,先找到对应的关联器,通过第二个值b+树修改增加索引
{
setKey(type, key);//将string转化为具体基本数值类型
if(type == TYPE_INT)
{
intMap::iterator itInt = indexIntMap.find(filePath);
if(itInt == indexIntMap.end())
{
cout << "Error:in search index, no index " << filePath <<" exits" << endl;
return;
}
else
{
itInt->second->insertKey(kt.intTmp,blockOffset);//kt是转到具体类型的结构体,含有要插入的值
}
}
else if(type == TYPE_FLOAT)
{
floatMap::iterator itFloat = indexFloatMap.find(filePath);
if(itFloat == indexFloatMap.end())
{
cout << "Error:in search index, no index " << filePath <<" exits" << endl;
return;
}
else
{
itFloat->second->insertKey(kt.floatTmp,blockOffset);
}
}
else // string
{
stringMap::iterator itString = indexStringMap.find(filePath);
if(itString == indexStringMap.end())
{
cout << "Error:in search index, no index " << filePath <<" exits" << endl;
return;
}
else
{
itString->second->insertKey(key,blockOffset);
}
}
}
/**
* Delete the key and its value
*
* @param string file path
* @param int type
*
* @return void
*
*/
void IndexManager::deleteIndexByKey(string filePath,string key,int type)//先找到对应关联器,第二个值b+树进行删除操作
{
setKey(type, key);//先转化一下
if(type == TYPE_INT)
{
intMap::iterator itInt = indexIntMap.find(filePath);
if(itInt == indexIntMap.end())
{
cout << "Error:in search index, no index " << filePath <<" exits" << endl;
return;
}
else
{
itInt->second->deleteKey(kt.intTmp);
}
}
else if(type == TYPE_FLOAT)
{
floatMap::iterator itFloat = indexFloatMap.find(filePath);
if(itFloat == indexFloatMap.end())
{
cout << "Error:in search index, no index " << filePath <<" exits" << endl;
return;
}
else
{
itFloat->second->deleteKey(kt.floatTmp);
}
}
else // string
{
stringMap::iterator itString = indexStringMap.find(filePath);
if(itString == indexStringMap.end())
{
cout << "Error:in search index, no index " << filePath <<" exits" << endl;
return;
}
else
{
itString->second->deleteKey(key);
}
}
}
/**
* Get the degree by the type.
* The tree node size equals to the block size.
*
* @param int type
*
* @return int the degree
*
*/
int IndexManager::getDegree(int type)//根据属性类型计算b+树分叉度数
{
int degree = bm.getBlockSize()/(getKeySize(type)+sizeof(offsetNumber));
if(degree %2 == 0) degree -= 1;
return degree;
}
/**
* Get the key size by the type
*
* @param int type
*
* @return int the key size
*
*/
int IndexManager::getKeySize(int type)//获得类型大小,占字节数多少
{
if(type == TYPE_FLOAT)
return sizeof(float);
else if(type == TYPE_INT)
return sizeof(int);
else if(type > 0)
return type + 1;//"\0"
else
{
cout << "ERROR: in getKeySize: invalid type" << endl;
return -100;
}
}
/**
* Get the key of its type by the inputed string.
* Users input string whatever type the key is.
*
* @param int type
* @param string key
*
* @return void
*
*/
void IndexManager::setKey(int type,string key)//将输入的key转化到对应类型,存储在kt结构里
{
stringstream ss;
ss << key;
if(type == this->TYPE_INT)
ss >> this->kt.intTmp;
else if(type == this->TYPE_FLOAT)
ss >> this->kt.floatTmp;
else if(type > 0)
ss >> this->kt.stringTmp;
else
cout << "Error: in getKey: invalid type" << endl;
}