Beispiel #1
0
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;
}
Beispiel #2
0
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;
}