Status Operators::IndexSelect(const string& result, // Name of the output relation const int projCnt, // Number of attributes in the projection const AttrDesc projNames[], // Projection list (as AttrDesc) const AttrDesc* attrDesc, // Attribute in the selection predicate const Operator op, // Predicate operator const void* attrValue, // Pointer to the literal value in the predicate const int reclen) // Length of a tuple in the output relation { cout << "Algorithm: Index Select" << endl; /* Your solution goes here */ Status indexStatus; Index scanIndex(attrDesc->relName, attrDesc->attrOffset, attrDesc->attrLen, (Datatype)attrDesc->attrType, 0, indexStatus); if (indexStatus != OK) return indexStatus; HeapFile indexHeapFile(result, indexStatus); if (indexStatus != OK) return indexStatus; HeapFileScan indexHeapScan (attrDesc->relName, indexStatus); if (indexStatus != OK) return indexStatus; Record newRecord, oldRecord; newRecord.length = reclen; newRecord.data = malloc (reclen); RID rid1, rid2; scanIndex.startScan(attrValue); while(scanIndex.scanNext(rid1)==OK){ int offset = 0; indexStatus = indexHeapScan.getRandomRecord(rid1, oldRecord); if (indexStatus != OK){ free(newRecord.data); return indexStatus; } for (int i = 0; i < projCnt; i++){ memcpy((char*)(newRecord.data) + offset, (char*)(oldRecord.data) + projNames[i].attrOffset, projNames[i].attrLen); offset += projNames[i].attrLen; } indexStatus = indexHeapFile.insertRecord(newRecord, rid2); if (indexStatus != OK){ free(newRecord.data); return indexStatus; } } scanIndex.endScan(); free(newRecord.data); return OK; }
Status SortedFile::generateRun(int items) { Status status; // Sort buffer using library function qsort (quick sort). Use // the appropriate comparison function for integers, floats, // or strings (qsort can't take type as a parameter). if (type == INTEGER) qsort(buffer, items, sizeof(SORTREC), intcmp); else if (type == DOUBLE) qsort(buffer, items, sizeof(SORTREC), floatcmp); else qsort(buffer, items, sizeof(SORTREC), stringcmp); // If this is the first sub-run, malloc space for a RUN object, // otherwise realloc more space. Note that on most systems // realloc(NULL) could be used even when runs == NULL, but // this doesn't work on all systems. RUN newRun; runs.push_back(newRun); // If failed to create space for an additional run. RUN & run = runs.back(); // Generate file name for temporary file. ostringstream outputString; outputString << fileName << ".sort." << runs.size() << ends; run.name = outputString.str(); /* char *tmpString = outputString.str(); run.name = string(tmpString); delete [] tmpString; */ #ifdef DEBUGSORT cout << "%% Writing " << items << " tuples to file " << run->name << endl; #endif // Make sure temporary file does not exist already. We don't // want to corrupt somebody else's sorted files (on another // attribute, for example). if ((status = db.createFile(run.name)) != OK) return status; // file must not exist already if ((status = db.destroyFile(run.name)) != OK) return status; // delete if successful // Open a heap file. This will also create the temporary file. if (!(run.file = new HeapFileScan(run.name, 0, 0, STRING, NULL, EQ, status))) return INSUFMEM; if (status != OK) return status; // Open an unfiltered sequential scan on the source file. The scan // is not actually needed for anything else than just getting // a scanId which getRandomRecord requires. HeapFileScan scan (fileName, 0, 0, STRING, NULL, EQ, status); if (status != OK) return status; // For each sort record (attribute plus RID) in the buffer, fetch // the whole record from the source file and then insert it into // the temporary file. for(int i = 0; i < items; i++) { SORTREC* rec = &buffer[i]; RID rid; Record record; if ((status = scan.getRandomRecord(rec->rid, record)) != OK) return status; if ((status = run.file->insertRecord(record, rid)) != OK) return status; } delete run.file; return OK; }