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 Stat;
    HeapFile heapfile = HeapFile(result, Stat);
    if(Stat != OK) {
        cerr << "Open heap file fail" << endl;
        return Stat;
    }
    string relation = projNames[0].relName;
    int unique = 0;
    RID rid;
    Record record;
    Record tuple;
    
    //Open index file
    Index indScan(relation, attrDesc->attrOffset, attrDesc->attrLen, (Datatype)attrDesc->attrType, unique, Stat);
    if(Stat != OK){
        return Stat;
    }
    
    //Heapscan object to access the getRandomRecord() function
    HeapFileScan heapScan=HeapFileScan(relation,attrDesc->attrOffset, attrDesc->attrLen,(Datatype)(attrDesc->attrType),(char *)attrValue,op,Stat);
    if(Stat != OK){
        return Stat;
    }
    
    //Start Index Scan
    Stat = indScan.startScan(attrValue);
    while(indScan.scanNext(rid)==OK){
        heapScan.getRandomRecord(rid,record);
        tuple.length = reclen;
        tuple.data = malloc(reclen);
        int offset = 0;
        
        //Project record
        for(int i=0; i<projCnt; ++i){
            memcpy((char*)tuple.data + offset, (char*)record.data + projNames[i].attrOffset, projNames[i].attrLen);
            offset += projNames[i].attrLen;
        }
        
        Stat = heapfile.insertRecord(tuple, rid);
        free(tuple.data);
        if(Stat != OK){
            return Stat;
        }
    }
    indScan.endScan();
    heapScan.endScan();
    
    return OK;
}
Example #2
0
//-------------------------------------------------------------
// createFiles
//-------------------------------------------------------------
void createFiles()
{
	struct _rec rec;
	memcpy(rec.filler,"    ",4);
	for (int i=0; i< NUMFILES; i++)
	{
		Status		s;
		RID		rid;
		HeapFile*	f = new HeapFile(files[i],s);
		if (s != OK)
			cout<<"this is ridiculous !"<<endl;
		for (int j=0; j<dsize[i]; j++)
		{
			rec.key = data[i][j];
			s = f->insertRecord((char*)&rec,sizeof(rec),rid);
			if (s != OK)
				cout<<"this is ridiculous !"<<endl;
		}
		delete f;
	}
}
Example #3
0
Status Updates::Insert(const string& relation,      // Name of the relation
                       const int attrCnt,           // Number of attributes specified in INSERT statement
                       const attrInfo attrList[])   // Value of attributes specified in INSERT statement
{
    /* Your solution goes here */
    Record record;
    int TempattrCnt;
    AttrDesc *attrd;
    bool insert = true;
    Status Stat;
    
    Stat = attrCat->getRelInfo(relation, TempattrCnt, attrd);
    if(Stat != OK){
        return Stat;
    }
    
    if(TempattrCnt == attrCnt){
        
        //Get length of record and allocate memory for it
        record.length = attrd[TempattrCnt-1].attrOffset+attrd[TempattrCnt-1].attrLen-attrd[0].attrOffset;
        record.data = malloc(record.length);
        
        //Reorder AttrList
        attrInfo Tempattrl[TempattrCnt];
        for(int i=0; i<TempattrCnt; ++i){
            for(int j=0; j<TempattrCnt; ++j){
                if(strcmp(attrd[i].attrName, attrList[j].attrName)==0){
                    Tempattrl[i] = attrList[j];
                }
            }
        }
        
        //Package data into record
        for(int i =0; i<TempattrCnt;i++){
            int len = strlen((char*)Tempattrl[i].attrValue);
            if((Datatype)Tempattrl[i].attrType==2 && len>attrd[i].attrLen){
                insert = false;
            }else{
                memcpy((char*)record.data+attrd[i].attrOffset, Tempattrl[i].attrValue, attrd[i].attrLen);
            }
        }
        
        //Insert Data Entry into Heapfile
        Status openHeapStat, insertHeapStat, openIndexStat, insertIndexStat;
        RID recordId;
        int unique = 0;
        Datatype type;
        //Utilities U;//for insert test
        
        HeapFile tempHeap = HeapFile(relation, openHeapStat);
        if(openHeapStat == OK && insert){
            //insert record into heapfile and release memory
            insertHeapStat = tempHeap.insertRecord(record, recordId);
            //U.Print(relation);//for insert test
            free(record.data);
            if(insertHeapStat == OK){
                for (int i=0; i< TempattrCnt; ++i){
                    if(attrd[i].indexed==1){
                        type = (Datatype)attrd[i].attrType;
                        Index index = Index(relation, attrd[i].attrOffset, attrd[i].attrLen,type, unique, openIndexStat);
                        if (openIndexStat == OK){
                            insertIndexStat = index.insertEntry(Tempattrl[i].attrValue,recordId);
                        }else{
                            delete []attrd;
                            return openIndexStat;
                        }
                    }
                }
            }else{
                delete []attrd;
                return insertHeapStat;
            }
        }else{
            free(record.data);
            if(!insert){
                delete []attrd;
                return ATTRTOOLONG;
            }else{
                delete []attrd;
                return openHeapStat;
            }
        }
    }else{
        delete []attrd;
        return ATTRTYPEMISMATCH;
    }
    delete []attrd;
    return OK;
}
Example #4
0
Status Operators::SMJ(const string& result,           // Output relation name
                      const int projCnt,              // Number of attributes in the projection
                      const AttrDesc attrDescArray[], // Projection list (as AttrDesc)
                      const AttrDesc& attrDesc1,      // The left attribute in the join predicate
                      const Operator op,              // Predicate operator
                      const AttrDesc& attrDesc2,      // The left attribute in the join predicate
                      const int reclen)               // The length of a tuple in the result relation
{
	cout << "Algorithm: SM Join" << endl;

	Status getRes = OK;
	HeapFile res = HeapFile(result, getRes);
	if(getRes != OK){
		return getRes;
	}
	
	//sort the left relation
	//calculate the number of unpinned pages to use
	int k = .8 * (bufMgr->numUnpinnedPages());
	
	//get the description of the relation & add up the size of all the attributes
	AttrDesc *relationStats;
	int numAttr, recSize = 0;
	attrCat->getRelInfo(attrDesc1.relName, numAttr, relationStats);
	for(int i = 0; i < numAttr; i++){
		recSize += relationStats[i].attrLen;
	}
	
	//calculation the number of tuples (aka max items) with k pages available
	int numTuples = k * PAGESIZE / recSize;
	SortedFile left = SortedFile(attrDesc1.relName, attrDesc1.attrOffset, attrDesc1.attrLen, (Datatype)attrDesc1.attrType, numTuples, getRes);
	if (getRes != OK){
		return getRes;
	}
	
	//now do same calculation to sort the right relation
	k = .8 * (bufMgr->numUnpinnedPages());
	recSize = 0;
	attrCat->getRelInfo(attrDesc2.relName, numAttr, relationStats);
	for(int i = 0; i < numAttr; i++){
		recSize += relationStats[i].attrLen;
	}
	numTuples = k * PAGESIZE / recSize;
	SortedFile right = SortedFile(attrDesc2.relName, attrDesc2.attrOffset, attrDesc2.attrLen, (Datatype)attrDesc2.attrType, numTuples, getRes);
	if (getRes != OK){
		return getRes;
	}
	

	Record leftRec, rightRec, newRec;
	newRec.data = malloc(reclen);
	newRec.length = 0;
	RID leftRid, rightRid, newRecRID;
	Status leftIsGood = left.next(leftRec);
	if(leftIsGood != OK){
		free(newRec.data);
		return leftIsGood;
	}
	Status rightIsGood = right.next(rightRec);
	if(rightIsGood != OK){
		free(newRec.data);
		return rightIsGood;
	}
	
	while(rightIsGood == OK && leftIsGood == OK){
		//compare the records
		int compare = matchRec(leftRec, rightRec, attrDesc1, attrDesc2);
		if(compare == 0){
			while(compare == 0 && leftIsGood == OK){
				right.setMark();
				while(compare == 0 and rightIsGood == OK){
					
					//project the joined tuple
					newRec.length = 0;
					for (int i = 0; i < projCnt; i++){
						if (strcmp(attrDescArray[i].relName, attrDesc1.relName) == 0){
							memcpy((char*)newRec.data + newRec.length, (char*)leftRec.data+attrDescArray[i].attrOffset, attrDescArray[i].attrLen);
						}
						else {
							memcpy((char*)newRec.data + newRec.length, (char*)rightRec.data+attrDescArray[i].attrOffset, attrDescArray[i].attrLen);
						}
						newRec.length += attrDescArray[i].attrLen;
					}
					//insert projected record into result
					res.insertRecord(newRec, newRecRID);
					
					//get next record and compare if next() works
					rightIsGood = right.next(rightRec);
					if(rightIsGood == OK){
						compare = matchRec(leftRec, rightRec, attrDesc1, attrDesc2);
					}
					
				}
				right.gotoMark();
				rightIsGood = right.next(rightRec);
				leftIsGood = left.next(leftRec);
				if(leftIsGood == OK && rightIsGood == OK){
					compare = matchRec(leftRec, rightRec, attrDesc1, attrDesc2);
				}
			}
			
		} else if (compare < 0){
			//scan the next on the left
			leftIsGood = left.next(leftRec);
		} else {
			rightIsGood = right.next(rightRec);
		}
		
		
	}
	
	
	free(newRec.data);
	return OK;
}
Example #5
0
Status Operators::INL(const string& result,           // Name of the output relation
                      const int projCnt,              // Number of attributes in the projection
                      const AttrDesc attrDescArray[], // The projection list (as AttrDesc)
                      const AttrDesc& attrDesc1,      // The left attribute in the join predicate
                      const Operator op,              // Predicate operator
                      const AttrDesc& attrDesc2,      // The right attribute in the join predicate (INDEXED)
                      const int reclen)               // Length of a tuple in the output relation
{
  	cout << "Algorithm: Indexed NL Join" << endl;

	AttrDesc* r;
	int num;
	Status status = attrCat->getRelInfo(result, num, r);
	if(status != OK) return status;

	// Load heap 1
	HeapFileScan heap1 = HeapFileScan(attrDesc1.relName, status);
	if (status != OK) return status; 
	
	// Load heap 2
	HeapFileScan heap2 = HeapFileScan(attrDesc2.relName, status);
	if (status != OK) return status;
	
	// Open output heap
	HeapFile heapOut = HeapFile(result, status);
	if (status != OK) return status; 

	// Get size of output record
	int size = 0;
	for (int x = 0; x < projCnt; x++) 
	{
		size += attrDescArray[x].attrLen;
	}

	// Create/find the index (checked to ensure indexed before entering this fn)
	Index index = Index(attrDesc2.relName, attrDesc2.attrOffset, attrDesc2.attrLen, (Datatype)attrDesc2.attrType, 1, status);
    	if (status != OK) return status;

	//Start Join 
	RID rid, rid1, rid2;
	Record record1, record2;

	while(heap1.scanNext(rid1, record1) == OK)
	{
		char* data1 = (char *) record1.data;

		// Update Heapfile Scan for Next Loop
		heap2 = HeapFileScan(attrDesc2.relName, status);
		if(status != OK) return status;

		// Restart the Index Scan for Next Loop
		status = index.startScan((char *) record1.data + attrDesc1.attrOffset);
		if(status != OK) return status;

		while(index.scanNext(rid2) == OK)
		{
			status = heap2.getRandomRecord(rid2, record2);
			if(status != OK) return status;

			char* data2 = (char *) record2.data;

			// Compare the values stored in both records
			int valueDif = matchRec(record1, record2, attrDesc1, attrDesc2);
			if(!valueDif)
			{
				// Add to output heap
				Record record;
				record.data = malloc(size);
				record.length = size;

				//Need to check through attrDescArray to find outside heap attrDescs
				for(int i = 0; i < projCnt; i++)
				{
					AttrDesc tempAttr = attrDescArray[i];

					//Insert from attrDesc1
					if( !strcmp(attrDesc1.relName, tempAttr.relName))
					{
						memcpy(((char*) record.data) + r[i].attrOffset, data1 + tempAttr.attrOffset, tempAttr.attrLen);
					} 
					else
					{
						memcpy(((char*) record.data) + r[i].attrOffset, data2 + tempAttr.attrOffset, tempAttr.attrLen);
					}
				}
				// Now insert the record into the output
				status = heapOut.insertRecord(record, rid);
				if(status != OK) return status;
			}
		}
		// End the scan and restart it again next iteration
		status = index.endScan();
		if(status != OK) return status;
	}

	status = heap1.endScan();
	if(status != OK) return status;

	return OK;
}