Ejemplo n.º 1
0
// **********************************************************
// Delete a record from a page. Returns OK if everything went okay.
// Compacts remaining records but leaves a hole in the slot array.
// Use memmove() rather than memcpy() as space may overlap.
Status HFPage::deleteRecord(const RID& rid)
{
	// fill in the body
	//--- deal with errors ----
	if(rid.pageNo < 0 || rid.slotNo < 0)
		return MINIBASE_FIRST_ERROR(HEAPFILE, INVALID_SLOTNO);
		//return FAIL;
	if(rid.slotNo >= this->slotCnt)	
		return MINIBASE_FIRST_ERROR(HEAPFILE, INVALID_SLOTNO);
		//return FAIL;
	//--- deal with empty page case ---
	if(empty())
		return MINIBASE_FIRST_ERROR(HEAPFILE, NO_RECORDS);
		//return FAIL;
 
	//--- get record offset ---
	int offset = getRecordOffset(rid);
	//--- clean corresponding slot & get record length---
	int len = cleanSlot(rid);
	
	//--- deal with already deleted case ---
	if(offset == INVALID_SLOT || len == EMPTY_SLOT)
		return MINIBASE_FIRST_ERROR(HEAPFILE, ALREADY_DELETED);
		//return FAIL;
	//-- shrink slot directory ---
	shrinkSlotDir();
	//--- delete record & relocate behind records & slot dir ---
	//--- & update usedPtr, freeSpace -----
	deleteRec(offset, len);

	return OK;
}
Ejemplo n.º 2
0
char* Page::getRecord ( int index ){
    int offset = getRecordOffset( index );
    int length = getRecordLength( index );

	tempStrCounter = length;
	memcpy( tempStr, content + offset, sizeof( char ) * length );

    tempStr[ length ] = '\0';

    return tempStr;
}
Ejemplo n.º 3
0
// **********************************************************
// Delete a record from a page. Returns OK if everything went okay.
// Compacts remaining records but leaves a hole in the slot array.
// Use memmove() rather than memcpy() as space may overlap.
Status HFPage::deleteRecord(const RID& rid)
{
	// fill in the body
	//---?? 注意未处理delete不存在record得特殊情况----
	
	//--- get record offset ---
	int offset = getRecordOffset(rid);
	//--- clean corresponding slot & get record length---
	int len = cleanSlot(rid);
	//-- shrink slot directory ---
	shrinkSlotDir();
	//--- delete record & relocate behind records & slot dir ---
	//--- & update usedPtr, freeSpace -----
	deleteRec(offset, len);

	return OK;
}
Ejemplo n.º 4
0
//compress a page, used for split page
void Page::adjustPage( ){

	int nextFree = 4;
	int slotSize = getSlotNumber();
	int length, offset;
	int counter = getSlotNumber();
	int location = 0;

	for ( int i = 0; i < slotSize; i ++ )
	{
		length = getRecordLength( i );

		//if the length is -1,it means that this data not in this page

		if ( length == -1 ) counter --;
		else{

			bool flag = 0;

			//find a slot with record length of -1,if it succeed, then move the data into this slot
			for (int j = location; j < i; j ++  )
				if ( getRecordLength( j ) == -1 ) { location = j; flag = 1; break; }

			if ( flag == 1 ){
					offset = getRecordOffset( i );

					memcpy( content + nextFree, content + offset, sizeof( char ) * length );
					setRecordOffset( location, nextFree );
					setRecordLength( location, length );
					setRecordLength( i, -1 );
			}
			
			 nextFree += length;
		}
	}

	//update free offset and slot number
	setSlotNumber( counter );
	setFreeOffset( nextFree );
}
Ejemplo n.º 5
0
XAttrList* getAllExtendedAttributes(HFSCatalogNodeID CNID, Volume* volume) {
	BTree* tree;
	HFSPlusAttrKey key;
	HFSPlusAttrRecord* record;
	uint32_t nodeNumber;
	int recordNumber;
	BTNodeDescriptor* descriptor;
	HFSPlusAttrKey* currentKey;
	off_t recordOffset;
	XAttrList* list = NULL;
	XAttrList* lastItem = NULL;
	XAttrList* item = NULL;

	if(!volume->attrTree)
		return NULL;

	memset(&key, 0 , sizeof(HFSPlusAttrKey));
	key.fileID = CNID;
	key.startBlock = 0;
	key.name.length = 0;
	key.keyLength = sizeof(HFSPlusAttrKey) - sizeof(HFSUniStr255) + sizeof(key.name.length) + (sizeof(uint16_t) * key.name.length);

	tree = volume->attrTree;
	record = (HFSPlusAttrRecord*) search(tree, (BTKey*)(&key), NULL, &nodeNumber, &recordNumber);
	if(record == NULL)
		return NULL;

	free(record);
	
	while(nodeNumber != 0) {    
		descriptor = readBTNodeDescriptor(nodeNumber, tree);

		while(recordNumber < descriptor->numRecords) {
			recordOffset = getRecordOffset(recordNumber, nodeNumber, tree);
			currentKey = (HFSPlusAttrKey*) READ_KEY(tree, recordOffset, tree->io);

			if(currentKey->fileID == CNID) {
				item = (XAttrList*) malloc(sizeof(XAttrList));
				item->name = (char*) malloc(currentKey->name.length + 1);
				int i;
				for(i = 0; i < currentKey->name.length; i++) {
					item->name[i] = currentKey->name.unicode[i];
				}
				item->name[currentKey->name.length] = '\0';
				item->next = NULL;

				if(lastItem != NULL) {
					lastItem->next = item;
				} else {
					list = item;
				}

				lastItem = item;

				free(currentKey);
			} else {
				free(currentKey);
				free(descriptor);
				return list;
			}

			recordNumber++;
		}

		nodeNumber = descriptor->fLink;
		recordNumber = 0;

		free(descriptor);
	}
	return list;
}
Ejemplo n.º 6
0
CatalogRecordList* getFolderContents(HFSCatalogNodeID CNID, Volume* volume) {
	BTree* tree;
	HFSPlusCatalogThread* record; 
	HFSPlusCatalogKey key;
	uint32_t nodeNumber;
	int recordNumber;

	BTNodeDescriptor* descriptor;
	off_t recordOffset;
	off_t recordDataOffset;
	HFSPlusCatalogKey* currentKey;

	CatalogRecordList* list;
	CatalogRecordList* lastItem;
	CatalogRecordList* item;

	char pathBuffer[1024];
	HFSPlusCatalogRecord* toReturn;
	HFSPlusCatalogKey nkey;
	int exact;

	tree = volume->catalogTree;

	key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length);
	key.parentID = CNID;
	key.nodeName.length = 0;

	list = NULL;

	record = (HFSPlusCatalogThread*) search(tree, (BTKey*)(&key), NULL, &nodeNumber, &recordNumber);

	if(record == NULL)
		return NULL;

	free(record);

	++recordNumber;

	while(nodeNumber != 0) {    
		descriptor = readBTNodeDescriptor(nodeNumber, tree);

		while(recordNumber < descriptor->numRecords) {
			recordOffset = getRecordOffset(recordNumber, nodeNumber, tree);
			currentKey = (HFSPlusCatalogKey*) READ_KEY(tree, recordOffset, tree->io);
			recordDataOffset = recordOffset + currentKey->keyLength + sizeof(currentKey->keyLength);

			if(currentKey->parentID == CNID) {
				item = (CatalogRecordList*) malloc(sizeof(CatalogRecordList));
				item->name = currentKey->nodeName;
				item->record = (HFSPlusCatalogRecord*) READ_DATA(tree, recordDataOffset, tree->io);

				if(item->record->recordType == kHFSPlusFileRecord && (((HFSPlusCatalogFile*)item->record)->userInfo.fileType) == kHardLinkFileType) {
					sprintf(pathBuffer, "iNode%d", ((HFSPlusCatalogFile*)item->record)->permissions.special.iNodeNum);
					nkey.parentID = volume->metadataDir;
					ASCIIToUnicode(pathBuffer, &nkey.nodeName); 
					nkey.keyLength = sizeof(nkey.parentID) + sizeof(nkey.nodeName.length) + (sizeof(uint16_t) * nkey.nodeName.length);

					toReturn = (HFSPlusCatalogRecord*) search(volume->catalogTree, (BTKey*)(&nkey), &exact, NULL, NULL);

					free(item->record);
					item->record = toReturn;
				}
				item->next = NULL;

				if(list == NULL) {
					list = item;
				} else {
					lastItem->next = item;
				}

				lastItem = item;
				free(currentKey);
			} else {
				free(currentKey);
				free(descriptor);
				return list;
			}

			recordNumber++;
		}

		nodeNumber = descriptor->fLink;
		recordNumber = 0;

		free(descriptor);
	}

	return list;
}
Ejemplo n.º 7
0
CatalogRecordList* getFolderContents(HFSCatalogNodeID CNID, Volume* volume) {
  BTree* tree;
  HFSPlusCatalogThread* record; 
  HFSPlusCatalogKey key;
  uint32_t nodeNumber;
  int recordNumber;
  
  BTNodeDescriptor* descriptor;
  off_t recordOffset;
  off_t recordDataOffset;
  HFSPlusCatalogKey* currentKey;
  
  CatalogRecordList* list;
  CatalogRecordList* lastItem;
  CatalogRecordList* item;
  
  tree = volume->catalogTree;
  
  key.keyLength = sizeof(key.parentID) + sizeof(key.nodeName.length);
  key.parentID = CNID;
  key.nodeName.length = 0;
  
  list = NULL;
  
  record = (HFSPlusCatalogThread*) search(tree, (BTKey*)(&key), NULL, &nodeNumber, &recordNumber);
  
  if(record == NULL)
    return NULL;
  
  free(record);
  
  ++recordNumber;
  
  while(nodeNumber != 0) {    
    descriptor = readBTNodeDescriptor(nodeNumber, tree);
       
    while(recordNumber < descriptor->numRecords) {
      recordOffset = getRecordOffset(recordNumber, nodeNumber, tree);
      currentKey = (HFSPlusCatalogKey*) READ_KEY(tree, recordOffset, tree->io);
      recordDataOffset = recordOffset + currentKey->keyLength + sizeof(currentKey->keyLength);
      
      if(currentKey->parentID == CNID) {
        item = (CatalogRecordList*) malloc(sizeof(CatalogRecordList));
        item->name = currentKey->nodeName;
        item->record = (HFSPlusCatalogRecord*) READ_DATA(tree, recordDataOffset, tree->io);
        item->next = NULL;

        if(list == NULL) {
          list = item;
        } else {
          lastItem->next = item;
        }
        
        lastItem = item;
        free(currentKey);
      } else {
        free(currentKey);
        free(descriptor);
        return list;
      }
      
      recordNumber++;
    }
    
    nodeNumber = descriptor->fLink;
    recordNumber = 0;
	
	free(descriptor);
  }
  
  return list;
}