Пример #1
0
void BufferManager::deleteRecord(const std::string& fileName, int blockOffset, int start)//给recordManager
{
	int n = fileName.find(".table",0);
	std::string tableName = fileName.substr(0, n);

	Table* tablePtr = Cat.getTablePtr(tableName);
	std::string ss = "";
	for (int i = 0; i < tablePtr->recordSize; i++)
		ss += '\0';
	std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset);
	
	if (start + tablePtr->recordSize>BLOCK_SIZE)
	{
		int length1 = BLOCK_SIZE - start;
		int length2 = tablePtr->recordSize - length1;
		(*it)->changeContent(start,ss.substr(0,length1));
		it = readFileBlock(fileName, blockOffset+1);
		(*it)->changeContent(0,ss.substr(0,length2));
	}
	else
		(*it)->changeContent(start, ss);

	int recordOffset = (blockOffset*BLOCK_SIZE + start) / tablePtr->recordSize;
	tablePtr->emptyRecordOffset.push_back(recordOffset);
}
Пример #2
0
int BufferManager::insertBlock(const std::string &fileName, const std::string& content)
{
	int n = fileName.find(".index", 0);
	std::string indexName = fileName.substr(0, n);
	Index* indexPtr = Cat.getIndexPtr(indexName);

	std::list<Block*>::iterator it;

	if (indexPtr->emptyBlockOffset.empty() == 1)
	{
		it = addBlockInFile(fileName);
		(*it)->blockOffset = indexPtr->blockNum;
		(*it)->fileName = fileName;
		(*it)->isDirty = 1;
		indexPtr->blockNum++;
		(*it)->changeContent(0, content);
	}
	else
	{
		int blockOffset = indexPtr->emptyBlockOffset.back();
		indexPtr->emptyBlockOffset.pop_back();
		it = readFileBlock(fileName, blockOffset);
		(*it)->changeContent(0, content);
	}
	return (*it)->blockOffset;
}
Пример #3
0
/*
 * Reads a file and locks it
 */
bool Directory::openFile(string path, string name, string &data) {
	if (!initialised) throw std::runtime_error("Directory not Initialised");
	if (isPathNameLegal(path) && isNameLegal(name)) {
		// check the path is valid
		int directoryNode = directoryTree->getPathNode(path);
		if (directoryNode < 0) {
			cout << "path " << path << " is invalid" << endl;
			return false;
		}
		// cache the directory (path) if it is not already cached
		int directoryNodeCache = getCachedDirectory(directoryNode);
		// check the filename exists
		if (cachedDirectory[directoryNodeCache]->cache.count(name) < 1) {
			cout << "file " << name << " does not exist" << endl;
			freeCachedDirectory(directoryNodeCache);
			return false;
		} else if (iNodeList->isINodeDirectory(cachedDirectory[directoryNodeCache]->cache[name])) {
			cout << name << " refers to directory - unable to read" << endl;
			freeCachedDirectory(directoryNodeCache);
			return false;
		}
		data.clear();
		iNodeList->lockINode(cachedDirectory[directoryNodeCache]->cache[name]);
		// read the file and put the data in data and the length in fileLength
		for (int i=0;i<iNodeList->getNumberOfBlocks(cachedDirectory[directoryNodeCache]->cache[name]);i++) {
			readFileBlock(iNodeList->getBlockNumber(cachedDirectory[directoryNodeCache]->cache[name],i),data);
		}
		freeCachedDirectory(directoryNodeCache);
		return true;
	} else {
		cout << "Path or filename not legal" << endl;
		return false;
	}
}
Пример #4
0
std::string BufferManager::getBlock(const std::string& fileName, int blockOffset,int start,int end)
{
	int n = fileName.find(".index", 0);
	Index *indexPtr = Cat.getIndexPtr(fileName.substr(0, n));

	std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset);
	std::string record = "";
	for (int i = start; i < end; i++)
		record += (*it)->content[i];
	return record;
}
Пример #5
0
std::string BufferManager::getRecord(const std::string& fileName, int blockOffset, int start)
{
	int n = fileName.find(".table",0);
	Table* tablePtr = Cat.getTablePtr(fileName.substr(0, n));
	
	std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset);
	std::string record = "";
	if (start + tablePtr->recordSize > BLOCK_SIZE)
	{
		int length1 = BLOCK_SIZE - start;
		int length2 = tablePtr->recordSize - length1;
		for (int i = 0; i < length1; i++)
			record += (*it)->content[start + i];
		it = readFileBlock(fileName, blockOffset+1);
		for (int i = 0; i < length2; i++)
			record += (*it)->content[i];
	}
	else
		for (int i = 0; i < tablePtr->recordSize; i++)
			record += (*it)->content[i+start];
	return record;
}
Пример #6
0
void BufferManager::changeValue(const std::string& fileName, int blockOffset, int start, std::string& c)
{
	std::list<Block*>::iterator it = findBlockInBuffer(fileName, blockOffset);
	if (it != fullBuffer.end())
	{
		(*it)->changeContent(start, c);
		fullBuffer.push_front((*it));
		fullBuffer.erase(it);
	}
	else
	{
		std::list<Block*>::iterator it = readFileBlock(fileName, blockOffset);
		(*it)->changeContent(start, c);
	}
}
Пример #7
0
void BufferManager::readFile(const std::string& fileName)
{
	int blockNum; int n;
	if ((n = fileName.find(".table", 0)) != std::string::npos)
	{
		Table* tablePtr = Cat.getTablePtr(fileName.substr(0,n));
		blockNum = tablePtr->blockNum;
	}
	if ((n = fileName.find(".index", 0)) != std::string::npos)
	{
		Index* indexPtr = Cat.getIndexPtr(fileName.substr(0, n));
		blockNum = indexPtr->blockNum;
	}
	std::list<Block*>::iterator it;
	for (int i = 0; i < blockNum; i++)
		it = readFileBlock(fileName, i);
}
Пример #8
0
void BufferManager::deleteBlock(const std::string &fileName, int blockOffset)//给indexManager
{
	int n = fileName.find(".index", 0);
	std::string indexName = fileName.substr(0, n);

	std::vector<Index*>::iterator indexPtr = Cat.findIndex(indexName);
	std::string ss = "";
	for (int i = 0; i < BLOCK_SIZE; i++)
		ss += '\0';
	std::list<Block*>::iterator it = findBlockInBuffer(fileName, blockOffset);
	if (it != fullBuffer.end())
	{
		(*it)->changeContent(0, ss);
		fullBuffer.push_front((*it));
		fullBuffer.erase(it);
	}
	else
	{
		it = readFileBlock(fileName, blockOffset);
		(*it)->changeContent(0, ss);
	}
	(*indexPtr)->emptyBlockOffset.push_back(blockOffset);
}
Пример #9
0
int BufferManager::insertRecord(const std::string& fileName, const std::string& content)
{
	int n = fileName.find(".table", 0);
	std::string tableName = fileName.substr(0, fileName.size()-6);
	Table* tablePtr = Cat.getTablePtr(tableName);

	std::list<Block*>::iterator it;

	if (tablePtr->emptyRecordOffset.empty() == 1)//没有空位
	{
		it = addBlockInFile(fileName);
		(*it)->blockOffset = tablePtr->blockNum;
		(*it)->fileName = fileName;
		(*it)->isDirty = 1;
		tablePtr->blockNum++;
		(*it)->changeContent(0, content);
		int recordOffset = ((tablePtr->blockNum - 1)*BLOCK_SIZE )/ tablePtr->recordSize;
		int num;
		if (BLOCK_SIZE % tablePtr->recordSize == 0)
			num = BLOCK_SIZE / tablePtr->recordSize;
		else
			num = BLOCK_SIZE / tablePtr->recordSize + 1;

		for (int i = 1; i < num; i++)
			tablePtr->emptyRecordOffset.push_back(recordOffset + i);
		
		return (*it)->blockOffset << 16;
	}
	else//有空位
	{
		int recordOffset = *((tablePtr->emptyRecordOffset).begin());
		(tablePtr->emptyRecordOffset).erase((tablePtr->emptyRecordOffset).begin());

		int blockOffset = (recordOffset*tablePtr->recordSize) / BLOCK_SIZE;
		int start = (recordOffset*tablePtr->recordSize) % BLOCK_SIZE;
		it = readFileBlock(fileName, blockOffset);
		if (start + tablePtr->recordSize > BLOCK_SIZE)//记录跨block
		{
			int length1 = BLOCK_SIZE - start;
			int length2 = tablePtr->recordSize - length1;
			(*it)->changeContent(start, content.substr(0, length1));
			if (blockOffset + 1 == tablePtr->blockNum)//所跨block的下一个需要生成
			{
				it = addBlockInFile(fileName);
				(*it)->blockOffset = tablePtr->blockNum;
				(*it)->fileName = fileName;
				(*it)->isDirty = 1;
				tablePtr->blockNum++;
				(*it)->changeContent(0, content.substr(length1, length2));
				int i = recordOffset+1;
				int size = length2;
				while (size < BLOCK_SIZE)
				{
					tablePtr->emptyRecordOffset.push_back(i);
					size += tablePtr->recordSize;
					i++;
				}
			}
			else//所跨block的下一个不需要生成
			{
				it = readFileBlock(fileName,blockOffset+1);
				(*it)->changeContent(0, content.substr(length1, length2));
			}
			
		}
		else//记录不跨block
			(*it)->changeContent(start, content); 

		return (blockOffset << 16) | start;
			
	}
}
Пример #10
0
/**
 * @brief
 * try opening a legal pathname with "." and ".."
 * @return 1 if successful, 0 otherwise
 */
error_t openTest26(){
	bool_t cpWritten;
	INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(prev_log_addr);
	INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr_file);
	INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr_dir2);
	INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr_dir1);
	INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr_root);
	INIT_LOGICAL_ADDRESS_STRUCT_AND_PTR(log_addr);
	dirent_flash *dirent_ptr = CAST_TO_DIRENT(fs_buffer);
	inode_t *ino_ptr = CAST_TO_INODE(fs_buffer);
	uint8_t *f_full_name = "/directory1/../directory1/directory2/file1.dat";
	uint32_t i;
	int32_t fd, flags = NANDFS_O_RDONLY;
	user_id user = 1;

	init_logical_address(prev_log_addr);
	init_logical_address(log_addr_file);
	init_logical_address(log_addr_dir2);
	init_logical_address(log_addr_dir1);
	init_logical_address(log_addr_root);
	init_logical_address(log_addr);

	/* set user in process*/
	SET_CURRENT_USER(user);

	/* write file inode */
	VERIFY(!writeNewInode(4, INO_NUM_EMPTY, FTYPE_FILE, log_addr_file));

	/* write directory2 inode*/
	VERIFY(!writeNewInode(3, 2, FTYPE_DIR, log_addr_dir2));

	/* write directory1 inode*/
	VERIFY(!writeNewInode(2, 1, FTYPE_DIR, log_addr_dir1));

	/* write file1.dat direntry in directory2*/
	VERIFY(!readFileBlock(fs_buffer, 3, INODE_FILE_DATA_SIZE, log_addr_dir2, TID_EMPTY));

	/* iterate until we find an empty directory entry*/
	while(!IS_DIRENT_EMPTY(dirent_ptr))
		moveToNextDirentry(&dirent_ptr, DIRENT_GET_LEN(dirent_ptr));

	setNewDirentry(dirent_ptr, 4, FTYPE_FILE, "file1.dat");
	VERIFY(!allocAndWriteBlock(log_addr, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0));

	/* write directory2 inode with new pointer to the above block*/
	VERIFY(!fsReadBlockSimple(log_addr_dir2, fs_buffer));
	INODE_SET_DIRECT(ino_ptr,0,log_addr);

	VERIFY(!allocAndWriteBlock(log_addr_dir2, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0));

	/* write directory2 direntry in directory1*/
	VERIFY(!readFileBlock(fs_buffer, 2, INODE_FILE_DATA_SIZE, log_addr_dir1,TID_EMPTY));

	/* iterate until we find an empty directory entry*/
	while(!IS_DIRENT_EMPTY(dirent_ptr))
		moveToNextDirentry(&dirent_ptr, DIRENT_GET_LEN(dirent_ptr));

	setNewDirentry(dirent_ptr, 3, FTYPE_DIR, "directory2");
	VERIFY(!allocAndWriteBlock(log_addr, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0));

	/* write directory1 inode with new pointer to the above block*/
	VERIFY(!fsReadBlockSimple(log_addr_dir1, fs_buffer));
	INODE_SET_DIRECT(ino_ptr,0,log_addr);

	VERIFY(!allocAndWriteBlock(log_addr_dir1, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0));

	/* write directory1 direntry in root*/
	VERIFY(!readFileBlock(fs_buffer, 1, INODE_FILE_DATA_SIZE, log_addr_root, TID_EMPTY));

	/* iterate until we find an empty directory entry*/
	while(!IS_DIRENT_EMPTY(dirent_ptr))
		moveToNextDirentry(&dirent_ptr, DIRENT_GET_LEN(dirent_ptr));

	setNewDirentry(dirent_ptr, 2, FTYPE_DIR, "directory1");
	VERIFY(!allocAndWriteBlock(log_addr, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0));

	/* write directory1 inode with new pointer to the above block*/
	VERIFY(!fsReadBlockSimple(log_addr_root, fs_buffer));
	INODE_SET_DIRECT(ino_ptr,0,log_addr);
	VERIFY(!allocAndWriteBlock(log_addr_root, fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0));

	/* write inode0 with pointers to the new root address*/
	VERIFY(!fsReadBlockSimple(FS_GET_INO0_ADDR_PTR(), fs_buffer));

	INODE_SET_DIRECT(ino_ptr,0,log_addr_root);
	INODE_SET_DIRECT(ino_ptr,1,log_addr_dir1);
	INODE_SET_DIRECT(ino_ptr,2,log_addr_dir2);
	INODE_SET_DIRECT(ino_ptr,3,log_addr_file);
	INODE_SET_NBYTES(ino_ptr, CAST_VAL_TO_UINT32(INODE_FILE_DATA_SIZE+4*FS_BLOCK_SIZE));
	VERIFY(!allocAndWriteBlock(FS_GET_INO0_ADDR_PTR(), fs_buffer, 0, prev_log_addr, &cpWritten, fsCheckpointWriter, 0));

	/* and now try opening file1.dat*/
	fd = open(f_full_name, flags, 0);

	VERIFY(!IS_NEGATIVE(fd));
	VERIFY(COMPARE(VNODE_GET_INO_NUM(OPEN_FILE_GET_VNODE(fd)), 4));
	VERIFY(IS_RDONLY(OPEN_FILE_GET_FLAGS(fd)));

	for(i=0; i< FS_MAX_OPEN_FILES;i++){
		if(i==fd){
			VERIFY(verifyOpenFileEntry(fd, flags,0,user, 0));
		}
		else{
			VERIFY(verifyOpenFileEntryEmpty(i));
		}
	}

	for(i=0; i<FS_MAX_VNODES;i++){
		if(i!=fd){
			VERIFY(verifyVnodeEmpty(i));
		}
		else{
			VERIFY(verifyVnode(i, 4, 1));
		}
	}
//

	return 1;
}