コード例 #1
0
ファイル: join.cpp プロジェクト: hunshih/minidb
Status Operators::Join(const string& result,           // Name of the output relation 
                       const int projCnt,              // Number of attributes in the projection
    	               const attrInfo projNames[],     // List of projection attributes
    	               const attrInfo* attr1,          // Left attr in the join predicate
    	               const Operator op,              // Predicate operator
    	               const attrInfo* attr2)          // Right attr in the join predicate
{
    /* Your solution goes here */
    Status prep_status;
    int rec_len = 0;
    AttrDesc output_attrs[projCnt];
    for (int i = 0; i < projCnt; i++) {
        prep_status = attrCat->getInfo(projNames[i].relName, projNames[i].attrName, output_attrs[i]);
        if (prep_status != OK) {
            return prep_status;
        }
        rec_len += output_attrs[i].attrLen;
    }
    AttrDesc attrdesc1, attrdesc2;
    prep_status = attrCat->getInfo(attr1->relName, attr1->attrName, attrdesc1);
    if (prep_status != OK) {
        return prep_status;
    }
    prep_status = attrCat->getInfo(attr2->relName, attr2->attrName, attrdesc2);
    if (prep_status != OK) {
        return prep_status;
    }

    Status status;
    if (op != EQ) { // non-equi join
        status = SNL(result, projCnt, output_attrs, attrdesc1, op, attrdesc2, rec_len);
    }
    else {
        if (attrdesc1.indexed) {
            status = INL(result, projCnt, output_attrs, attrdesc2, op, attrdesc1, rec_len);
        }
        else if (attrdesc2.indexed) {
            status = INL(result, projCnt, output_attrs, attrdesc1, op, attrdesc2, rec_len);
        }
        else {
            status = SMJ(result, projCnt, output_attrs, attrdesc1, op, attrdesc2, rec_len);
        }
        
    }
    if (status != OK) {
        return status;
    }

	return OK;
}
コード例 #2
0
ファイル: join.cpp プロジェクト: caogl/EECS484
Status Operators::Join(const string& result,           // Name of the output relation 
                       const int projCnt,              // Number of attributes in the projection
    	               const attrInfo projNames[],     // List of projection attributes
    	               const attrInfo* attr1,          // Left attr in the join predicate
    	               const Operator op,              // Predicate operator
    	               const attrInfo* attr2)          // Right attr in the join predicate
{
    Status status;

    /* Minirel guarantees there will be a Join Condition => Populate the attr_desc objects */
    AttrDesc attr_desc1, attr_desc2;
    status = attrCat->getInfo(attr1->relName, attr1->attrName, attr_desc1);
    if(status != OK) return status;
    status = attrCat->getInfo(attr2->relName, attr2->attrName, attr_desc2);
    if(status != OK) return status;

    /* Find the length of a resulting record and populate the proj_names array */
    int reclen;
    AttrDesc *proj_names = new AttrDesc[projCnt];
    status = ConvertInfoToDesc(projNames, projCnt, proj_names, reclen);
    if(status != OK) {
        delete [] proj_names;
        return status;
    }

    if(op != EQ)
	SNL(result, projCnt, proj_names, attr_desc1, op, attr_desc2, reclen);
    else {
	if(attr_desc1.indexed)
	    INL(result, projCnt, proj_names, attr_desc2, negate_operator(op), attr_desc1, reclen);
	else if(attr_desc1.indexed)
	    INL(result, projCnt, proj_names, attr_desc1, op, attr_desc2, reclen);
	else
	    SMJ(result, projCnt, proj_names, attr_desc1, op, attr_desc2, reclen);
    }

    return OK;
}
コード例 #3
0
ファイル: join.cpp プロジェクト: trevorassaf/mineral
Status Operators::Join(const string& result,           // Name of the output relation 
                       const int projCnt,              // Number of attributes in the projection
    	               const attrInfo projNames[],     // List of projection attributes
    	               const attrInfo* attr1,          // Left attr in the join predicate
    	               const Operator op,              // Predicate operator
    	               const attrInfo* attr2)          // Right attr in the join predicate
{
  // Fetch attribute descriptions
  string relation1 = attr1->relName;
  string relation2 = attr2->relName;
  
  AttrDesc* inputDescs1, * inputDescs2;
  
  int attrCnt1, attrCnt2;
  
  Status status = attrCat->getRelInfo(relation1, attrCnt1, inputDescs1);
  if (status != OK) {
    return status;
  }
  status = attrCat->getRelInfo(relation2, attrCnt2, inputDescs2);
  if (status != OK) {
    return status;
  }
  
  // Construct list of projected attribute descriptions
  AttrDesc* projAttrDescs = new AttrDesc[projCnt];
  int reclen = 0;
  
  //search through the first relation for an attribute match
  for (int i = 0; i < projCnt; ++i) {
    bool found = false;
    int j;
    for (j = 0; j < attrCnt1; ++j) {
      if (!strcmp(projNames[i].attrName, inputDescs1->attrName) && 
          !strcmp(projNames[i].relName, inputDescs1->relName)) {
        *projAttrDescs++ = *inputDescs1;
        reclen += inputDescs1->attrLen;  
        found = true;
        break;
      } 
      inputDescs1++;
    }
    inputDescs1 -= j;
    
    if (found) {
      continue;
    }
    
    //If not found in the first relation, search for the attribute in the second relation
    for (j = 0; j < attrCnt2; ++j) {
      if (!strcmp(projNames[i].attrName, inputDescs2->attrName) && 
          !strcmp(projNames[i].relName, inputDescs2->relName)) {
        *projAttrDescs++ = *inputDescs2;
        reclen += inputDescs2->attrLen;
        found = true;
        break;
      } 
      inputDescs2++;
    }
    inputDescs2 -= j;
    assert(found); 
  }
  projAttrDescs -= projCnt;
  
  // Convert criterion attributes to AttrDesc
  AttrDesc cDesc1, cDesc2;
  status = attrCat->getInfo(relation1, attr1->attrName, cDesc1);
  if (status != OK) {
    return status;
  }
  status = attrCat->getInfo(relation2, attr2->attrName, cDesc2);
  if (status != OK) {
    return status;
  } 
  
  // Delegate sub-join operations
  if (op != EQ) {
    //Perform SNL. Might have to switch relation 1 and relation2 
    //based on which is more efficient as the outer relation
    HeapFileScan hfs1(relation1, status);
    if(status != OK)
    { return status;
    }
    HeapFileScan hfs2(relation2, status);
    if(status != OK)
    { return status;
    }
    
    //Get num tuples for each file
    int numTuples1 = hfs1.getRecCnt();
    int numTuples2 = hfs2.getRecCnt();
    int relSize1 = 0, relSize2 = 0;
    for (int i = 0; i < attrCnt1; ++i) {
     relSize1 += (inputDescs1 + i)->attrLen;
    }
    for (int i = 0; i < attrCnt1; ++i) {
     relSize2 += (inputDescs2 + i)->attrLen;
    }
    
    //Calculate num pages for each file
    int relPages1 = ceil((numTuples1*relSize1)*1.0/PAGESIZE);
    int relPages2 = ceil((numTuples2*relSize2)*1.0/PAGESIZE);
    
    //Use formula to calculate total IOs, to decide in which order to send
    //SNL the two AttrDesc structs (first parameter is outer, second is inner)
    if(relPages1 + numTuples1*relPages2 <= relPages2 + numTuples2*relPages1) {
      return SNL(
        result,
        projCnt,
        projAttrDescs,
        cDesc1,
        op,
        cDesc2,
        reclen);
     } else {
       //Operator needs to be flipped if the order is switched
       Operator op2;
       switch(op)
       {
         case LT: op2 = GT; break;
         case GT: op2 = LT; break;
         case LTE: op2 = GTE; break;
         case GTE: op2 = LTE; break;
         default: break;
       } 
       return SNL(
        result,
        projCnt,
        projAttrDescs,
        cDesc2,
        op2,
        cDesc1,
        reclen);
     }
  }
  
  if (cDesc1.indexed || cDesc2.indexed) {
    return INL(
      result,
      projCnt,
      projAttrDescs,
      cDesc1,
      op,
      cDesc2,
      reclen);  
  }
  
  return SMJ(
      result,
      projCnt,
      projAttrDescs,
      cDesc1,
      op,
      cDesc2,
      reclen);
}