Relation* Delete(vector<string> &words, SchemaManager &schema_manager, MainMemory &mem){ Relation* relation_ptr = schema_manager.getRelation(words[2]); vector<string>::iterator it = find(words.begin(), words.end(), "WHERE"); // no WHERE, delete everything if (it == words.end()){ relation_ptr->deleteBlocks(0); } // with WHERE clause else{ vector<string> where_list(it, words.end()); preProcess(vector<string> (1, words[2]), where_list, schema_manager); Relation * new_relation = generateDLQP(where_list, words[2], schema_manager, mem); // very .... schema_manager.deleteRelation(words[2]); Relation* newRR = schema_manager.createRelation(words[2], new_relation->getSchema()); assert(!free_blocks.empty()); int memory_block_index = free_blocks.front(); free_blocks.pop(); int dBlocks = new_relation->getNumOfBlocks(); int size = 0; Block * block_ptr = NULL; while(size < dBlocks){ // read the relatioin block by block new_relation->getBlock(size, memory_block_index); block_ptr = mem.getBlock(memory_block_index); vector<Tuple> tuples = block_ptr->getTuples(); if(tuples.empty()){ cerr<<"Warning In Delete: No tuples in the current mem block!"<<endl; } for(int i = 0; i < tuples.size(); ++i){ Tuple t = tuples[i]; appendTupleToRelation(newRR, mem, t); } size++; } free_blocks.push(memory_block_index); // cout<<newRR->getRelationName()<<endl; // cout<<*newRR<<endl; } relation_ptr = schema_manager.getRelation(words[2]); cout<<relation_ptr<<endl; return relation_ptr; }
Relation* Insert(vector<string> &words, string &line, SchemaManager &schema_manager, MainMemory &mem){ Relation* relation_ptr = schema_manager.getRelation(words[2]); vector<string>::iterator it = find(words.begin(), words.end(), "SELECT"); // no select if (it == words.end()){ // get insert vals vector<string> content = splitBy(line, "()"); vector<string> fields = splitBy(content[1], ", "); vector<string> vals = splitBy(content[3], ","); //preProcess(vector<string>(1, words[2]), fields, schema_manager); preProcess(vector<string>(1, words[2]), vals, schema_manager); assert(fields.size() == vals.size()); Tuple tuple = relation_ptr->createTuple(); // standard insert doesn't have table names vector<string> col_names = nakedFieldNames(relation_ptr); // comparing for (int i = 0; i < fields.size(); i++){ for (int j = 0; j < col_names.size(); j++){ // this is a match if (fields[i] == col_names[j]){ if (tuple.getSchema().getFieldType(j) == INT){ tuple.setField(j, atoi(vals[i].c_str())); } else{ tuple.setField(j, vals[i]); } break; } } } appendTupleToRelation(relation_ptr, mem, tuple); } // with SELECT else{ vector<string> SFW(it, words.end()); Relation* new_relation = Select(SFW, schema_manager, mem); assert(new_relation); vector<string> new_field_names = nakedFieldNames(new_relation); vector<string> field_names = nakedFieldNames(relation_ptr); // mapping: index of new_field_names to field_names vector<int> mapping(new_field_names.size(), -1); for (int i = 0; i < new_field_names.size(); i++){ for (int j = 0; j < field_names.size(); j++){ if (new_field_names[i] == field_names[j]){ mapping[i] = j; break; } } } int new_field_size = new_relation->getSchema().getNumOfFields(); // warning: new_relation and relation_ptr might be the same! // get all tuples from the new_relation in one run vector<Tuple> new_tuples; for (int i = 0; i < new_relation->getNumOfBlocks(); i++){ assert(!free_blocks.empty()); int memory_block_index = free_blocks.front(); free_blocks.pop(); // read the relation block by block new_relation->getBlock(i, memory_block_index); Block* block_ptr = mem.getBlock(memory_block_index); assert(block_ptr); vector<Tuple> block_tuples = block_ptr->getTuples(); new_tuples.insert(new_tuples.end(), block_tuples.begin(), block_tuples.end()); if(new_tuples.empty()){ cerr<<"Warning: Insert from SFW, No tuples in the current mem block!"<<endl; } free_blocks.push(memory_block_index); } for (int j = 0; j < new_tuples.size(); j++){ Tuple tuple = relation_ptr->createTuple(); for (int k = 0; k < new_field_size; k++){ if (mapping[k] != -1){ int idx = mapping[k]; assert(idx < relation_ptr->getSchema().getNumOfFields() && idx >= 0); if (tuple.getSchema().getFieldType(idx) == INT){ int val = new_tuples[j].getField(k).integer; tuple.setField(field_names[idx], val); } else{ string *str = new_tuples[j].getField(k).str; tuple.setField(field_names[idx], *str); } } } appendTupleToRelation(relation_ptr, mem, tuple); } cout<<*relation_ptr<<endl; } return relation_ptr; }
Relation * orderByRelationTwoPass(Relation *relation_ptr, vector<string> &field_name, vector<enum FIELD_TYPE> &field_type, bool returnRelation) { Block *block_ptr; // Every 9 blocks of the relation are sorted int sorted_blocks = 9; int num_relation_blocks = relation_ptr->getNumOfBlocks(); int num_groups = (num_relation_blocks - 1) / 9 + 1; int first_min_index; vector<int> blocks_used; Relation *ordered_relation_ptr = NULL; Schema schema; if (returnRelation) { schema = relation_ptr->getSchema(); ordered_relation_ptr = schema_manager.createRelation(relation_ptr->getRelationName() + "_ordered", Schema(schema.getFieldNames(), schema.getFieldTypes())); } // Bring first block of each group in memory for (int i = 0; i < num_groups; i++) { block_ptr = mem.getBlock(i); block_ptr->clear(); relation_ptr->getBlock(i * sorted_blocks, i); blocks_used.push_back(1); } while(1) { Block *min_tuple_block_ptr = NULL; int min_tuple_index = -1; for(int i = 0; i < num_groups; i++) { block_ptr = mem.getBlock(i); vector<Tuple> tuples = block_ptr->getTuples(); // Try to get the first unconsidered tuple from this sublist while ( (first_min_index = getFirstMinTuple(tuples)) == -1) { // Use 1 more block blocks_used[i] += 1; if ( (i == num_groups - 1) && (blocks_used[i] > ((num_relation_blocks - 1) % 9 + 1))) break; if (blocks_used[i] > sorted_blocks) break; // Bring another block from the sublist into the memory relation_ptr->getBlock(i * sorted_blocks + blocks_used[i] - 1, i); tuples = block_ptr->getTuples(); } // This sublist has been exhausted if (first_min_index == -1) continue; if (isSmaller(field_name, field_type, block_ptr->getTuple(first_min_index), min_tuple_block_ptr, min_tuple_index)) { min_tuple_block_ptr = block_ptr; min_tuple_index = first_min_index; } } // If no min tuple found, break if (!min_tuple_block_ptr) break; Tuple min_tuple = min_tuple_block_ptr->getTuple(min_tuple_index); if (!returnRelation) min_tuple.printTuple(); else appendTupleToRelation(ordered_relation_ptr, 9, min_tuple); min_tuple_block_ptr->nullTuple(min_tuple_index); } return ordered_relation_ptr; }