void commands_ns::DiskInfo(FileSystem *fs, int argc, char *argv[], std::ostream& out){ if (argc != 0) { out << "Неправильное количество параметров" << std::endl; return; } //размеры файлов даны в байтах size_t totalUsedSpace = 0; size_t fileSystemSize = fs->GetMaxSize(); FileIterator* fileIterator = fs->GetIterator(); while(fileIterator->HasNext()){ fileIterator->Next(); FileDescriptor* fileDescriptor = fileIterator->GetFileDescriptor(); totalUsedSpace += fileDescriptor->GetSize(); } size_t freeDiskSpace = fileSystemSize - totalUsedSpace; double ratio = (double)freeDiskSpace/fileSystemSize; out << "Сведения о диске:" << std::endl; out << "Наименование: " << fs->GetTomName() << std::endl; out << "Размер свободного места: " << freeDiskSpace << " б (" << ratio*100 << "%)" << std::endl; out << "Максимальный объем: " << fileSystemSize << " б" << std::endl; }
void LinkedFile<T>::indexLoad() { FileIterator<T>* ite = this->getIterator(); FILE_OFFSET inFileOffset = ite->getNextOffset(); IndexedElement* lastElem = this->firstElem; while (ite->moveNext()) { Element<T>* current = ite->getCurrent(); IndexedElement* elem = current->getIndexedElement(); elem->inFileOffset = inFileOffset; elem->previous = lastElem; elem->next = NULL; // List lastElem->next = elem; lastElem = elem; this->indexAdd(current->key, elem); inFileOffset = ite->getNextOffset(); } delete ite; }
int File::findChildren(FileFinder& finder, vector<File*>& results, bool recursive, bool archiveEntries) const { int matchCount = 0; FileIterator* it = getIterator(); File* child; while ((child = it->next()) != NULL) { bool matches = finder.matches(*child); if (matches) { results.push_back(child); matchCount++; } if (finder.isInterrupted()) { if (!matches) { delete child; } return matchCount; } if (recursive && (child->isDirectory() || (archiveEntries && child->isArchiveFile()))) { matchCount += child->findChildren(finder, results, true, archiveEntries); } if (!matches) { delete child; } } delete it; return matchCount; }
void commands_ns::Format(FileSystem *fs, int argc, char *argv[], std::ostream& out) // модуль не доработан жду модуля Delete() { if (argc != 3) { out << "Неверное количество параметров"<< std::endl; return; } else { //size_t szt = atoi(argv[2]); if (fs->names_types(argv[0]) || fs->names_types(argv[1]) || fs->fssize(argv[2])) { out << "Некорректные данные" << std::endl; return; } else { FileIterator *fIter = fs->GetIterator(); fs->SetTomName(argv[0]); fs->SetOwner(argv[1]); fs->SetMaxSize(atoi(argv[2])); while (fIter->HasNext()) { fIter->Next(); fIter->Delete(); } fIter->Close(); out << "Форматирование ФС успешно" << std::endl; } } }
int File::indexOf(const File& other) const { if (!isDirectory() && !isArchiveFile()) { char* errmsg = new char[path->toString().length() + 128]; sprintf(errmsg, "Called indexOf(const File&) with an invalid file type: '%s'", path->toString().get()); FileException ex(errmsg, __FILE__, __LINE__); delete[] errmsg; throw ex; } FileIterator* it = getIterator(); int i = 0; File* child; while ((child = it->next()) != NULL) { if (child->getPath()->toString() == other.getPath()->toString()) { delete child; delete it; return i; } i++; delete child; } delete it; return -1; }
File* File::findChild(FileFinder& finder, bool recursive, bool archiveEntries) const { FileIterator* it = getIterator(); File* child; while ((child = it->next()) != NULL) { if (finder.matches(*child)) { delete it; return child; } if (finder.isInterrupted()) { delete child; return NULL; } if (recursive && (child->isDirectory() || (archiveEntries && child->isArchiveFile()))) { File* match = child->findChild(finder, true, archiveEntries); if (match) { delete child; delete it; return match; } } delete child; } delete it; return NULL; }
//--------------------------------------------------------------------------- uint FileIterator::getFilesList (const char* pszDirectory, bool bRecursive, StringAVec& vecOutFiles, flags8 fQueryFilter/*=QUERY_DIRS_AND_FILES*/) { FileIterator fit; FileInfo fi; uint uiCounter = 0; fi.fQueryFlags = QUERY_NAMEONLY | (fQueryFilter & QUERYMASK_FILTERS); if (bRecursive) fi.fQueryFlags |= QUERY_TYPE | QUERY_DIRS; if (fit.openDir(pszDirectory, fi)) { do { if ((fi.eType == TYPE_DIRECTORY && (fQueryFilter & QUERY_DIRS)) || (fi.eType == TYPE_FILE && (fQueryFilter & QUERY_FILES))) { vecOutFiles.push_back(fit.getDirectory() / fi.strName); ++uiCounter; } if (bRecursive && fi.eType == TYPE_DIRECTORY) { uiCounter += FileIterator::getFilesList( fit.getDirectory() / fi.strName, bRecursive, vecOutFiles, fQueryFilter); } } while (fit.getNext(fi)); } return uiCounter; }
int File::getChildCount(bool recursive, bool archiveEntries) const { if (isRegularFile()) { FileContentType type = guessContentType(); if (type != CONTENT_TYPE_DIR && type != CONTENT_TYPE_IMG) { return 0; } else { if (!recursive || archiveEntries) { //IMGArchive img(*this); //return img.getEntryCount(); return getIMGArchive()->getEntryCount(); } else { return 0; } } } else if (!isDirectory()) { return 0; } FileIterator* it = getIterator(); int i = 0; File* child; while ((child = it->next()) != NULL) { if (recursive) { i += child->getChildCount(true, archiveEntries); } delete child; i++; } delete it; return i; }
//--------------------------------------------------------------------------- uint FileIterator::getFilesInfo (const char* pszDirectory, bool bRecursive, std::vector<FileIterator::FileInfo>& vecOutFilesInfo, flags8 fQueryFlags/*=QUERY_DIRS_AND_FILES*/) { FileIterator fit; FileInfo fi; uint uiCounter = 0; fi.fQueryFlags = fQueryFlags; if (bRecursive) fi.fQueryFlags |= QUERY_TYPE | QUERY_DIRS; if (fit.openDir(pszDirectory, fi)) { do { fi.strName = fit.getDirectory() / fi.strName; if ((fi.eType == TYPE_DIRECTORY && (fQueryFlags & QUERY_DIRS)) || (fi.eType == TYPE_FILE && (fQueryFlags & QUERY_FILES))) { vecOutFilesInfo.push_back(fi); ++uiCounter; } if (bRecursive && fi.eType == TYPE_DIRECTORY) { uiCounter += FileIterator::getFilesInfo( fi.strName, bRecursive, vecOutFilesInfo, fQueryFlags); } } while (fit.getNext(fi)); } return uiCounter; }
void commands_ns::AddToFile(FileSystem *fs, int argc, char *argv[], std::ostream& out) { size_t size = 0; if (argc != 2) { out << "Неправильное количество параметров" << std::endl; return; } char *nt[2]; nt[0] = strtok(argv[0], "."); nt[1] = strtok(NULL, ""); char *s = strtok(NULL, ".,-!"); if ((!nt[0]) || (!nt[1]) || (s)) { out << "Введены некорректные данные" << std::endl; return; } if (fs->names_types(nt[0])||fs->names_types(nt[1])) { out << "Введены некорректные данные" << std::endl; return; } if (fs->GetFilesCount() <= 0) { out << "Файл не найден" << std::endl; return; } if ((!argv[1]) || (strlen(argv[1]) <= 0)) { out << "Информация для добавления не введена" << std::endl; return; } int addSize = strlen(argv[1]); int fileIndx = -1; //формируем список блоков из дескрипторов по возрастанию смещения====== std::list < MemList> List; std::list<MemList>::iterator iter; std::list<MemList>::iterator fileToAdd; FileIterator *fi = fs->GetIterator(); FileDescriptor *fd; MemList ml; unsigned int indx = 0, max_indx; while (fi->HasNext()) { fi->Next(); fd = fi->GetFileDescriptor(); if ((strcmpi(fd->GetName(), nt[0]) == 0) && (strcmpi(fd->GetType(), nt[1]) == 0)) { fileIndx = indx; } ml.FDescrPtr = fd; ml.offset = fd->GetOffset(); ml.sz = fd->GetSize(); ml.index = indx; if (List.empty()) { List.push_back(ml); if (indx == fileIndx) {fileToAdd = List.begin();} } else { for (iter = List.begin(); iter != List.end(); iter++) { if ((ml.offset < (*iter).offset) || ((ml.offset == (*iter).offset) && (ml.sz < (*iter).sz))) { List.insert(iter, ml); if (indx == fileIndx) { fileToAdd = std::prev(iter); } break; } } if (iter == List.end()) { List.push_back(ml); if (indx == fileIndx) { fileToAdd = std::prev(List.end()); } } } ++indx; } max_indx = indx - 1; if (fileIndx==-1) { out << "Файл с указанным именем не существует" << std::endl; return; } //вставляем пустой блок в начало, если нужно size_t FD_END = 0; if ((*(List.begin())).offset > FD_END) { ml.offset = FD_END; ml.sz = (*(List.begin())).offset - FD_END; ml.FDescrPtr = NULL; List.insert(List.begin(), ml); } //вставляем пустые блоки в список for (iter = List.begin(); iter != List.end(); iter++) { if (std::next(iter) != List.end()) { if ((*(std::next(iter))).offset != ((*iter).offset + (*iter).sz)) { ml.offset = (*iter).offset + (*iter).sz; ml.sz = (*(std::next(iter))).offset - ml.offset; ml.FDescrPtr = NULL; List.insert(std::next(iter), ml); ++iter; } } } //проверяем размер size_t MaxSz = fs->GetMaxSize(); if (((*(std::prev(List.end()))).offset + (*(std::prev(List.end()))).sz+addSize) > MaxSz) { out << "Недостаточно места для добавления введенной информации" << std::endl; return; } //меняем размер файла, в который добавляется информация (*fileToAdd).sz += addSize; (*fileToAdd).FDescrPtr->SetSize((*fileToAdd).sz); if (std::next(fileToAdd) == List.end())//если файл последний в памяти - просто добавляем в размер { fi = fs->GetIterator(); int i = 0; while (fi->HasNext()) { fi->Next(); if (i == (*fileToAdd).index) { fi->SetFileDescriptor((*fileToAdd).FDescrPtr); break; } } out << "Информация добавлена" << std::endl; return; } //если не последний - ищем подходящую "дырку" bool isMoved = false; for (iter = List.begin(); iter != List.end(); iter++) { if (((*iter).FDescrPtr == NULL) && ((*iter).sz >= (*fileToAdd).sz)) { MemList ml = (*fileToAdd); List.erase(fileToAdd); ml.offset = (*iter).offset; (*iter).sz -= ml.sz; (*iter).offset += ml.sz; std::list<MemList>::iterator movedFile = List.insert(iter, ml); (*movedFile).FDescrPtr->SetOffset((*movedFile).offset); if ((*iter).sz <= 0) { List.erase(iter); } fileToAdd = movedFile; isMoved = true; break; } } //если нет подходящей дырки - сдвигаем все следующие блоки if (!isMoved) { for (iter = std::next(fileToAdd); iter != List.end(); iter++) { (*iter).offset += addSize; } } //меняем дескрипторы и записываем их в файл в нужном порядке fi = fs->GetIterator(); for (indx = 0; indx <= max_indx; indx++) { for (iter = List.begin(); ((iter != List.end()) && ((*iter).index != indx)); iter++) {} fi->Next(); (*iter).FDescrPtr->SetOffset((*iter).offset); fi->SetFileDescriptor((*iter).FDescrPtr); } fi->Close(); out << "Информация добавлена" << std::endl; return; }
void commands_ns::ChType(FileSystem *fs, int argc, char *argv[], std::ostream& out) { FileIterator* fi = fs->GetIterator(); int i = 0, count = strlen(argv[0]), flag = 1; char *arg_name = new char[count]; if (argc != 2) { out << "Неправильное количество параметров" << std::endl; delete[] arg_name; return; } while (argv[0][i] != '.') { arg_name[i] = argv[0][i]; ++i; if (i > count - 2) { out << "Введены некорректные данные" << std::endl; delete[] arg_name; return; } } if (i == 0) { out << "Введены некорректные данные" << std::endl; delete[] arg_name; return; } arg_name[i] = '\0'; count -= i; ++i; char *arg_type = new char[count]; count = 0; while (argv[0][i]) { arg_type[count] = argv[0][i]; ++i; ++count; } arg_type[count] = '\0'; count = 0; if (fs->names_types(arg_name) || fs->names_types(arg_type)||fs->names_types(argv[1])) { out << "Введены некорректные данные" << std::endl; delete[] arg_name; delete[] arg_type; return; } if (fs->GetFilesCount() != 0) { while (fi->HasNext()) { fi->Next(); FileDescriptor* fd = fi->GetFileDescriptor(); if (strcmpi(fd->GetName(), arg_name) == 0 && strcmpi(fd->GetType(), arg_type) == 0) { if (strcmp(arg_type,argv[1])==0){ out << "Изменение имени прошло успешно" << std::endl; delete[] arg_name; delete[] arg_type; return; } FileIterator* fi2 = fs->GetIterator(); while (fi2->HasNext()) { fi2->Next(); FileDescriptor* fd2 = fi2->GetFileDescriptor(); if (strcmpi(fd2->GetName(), arg_name) == 0 && strcmpi(fd2->GetType(), argv[1]) == 0) { out << "Файл с таким именем и типом уже существует" << std::endl; delete[] arg_name; delete[] arg_type; return; } } flag = 0; fd->SetType(argv[1]); fi->SetFileDescriptor(fd); out << "Изменение имени прошло успешно" << std::endl; delete[] arg_name; delete[] arg_type; return; } ++count; } } if (flag == 1) { out << "Файла в системе не обнаружено" << std::endl; } delete[] arg_name; delete[] arg_type; }
void commands_ns::DelFile(FileSystem *fs, int argc, char *argv[], std::ostream& out) { if (argc != 1) { out << "Неправильное количество параметров" << std::endl; return; } if (strlen(argv[0]) > 41) { out << "Введены некорректные данные" << std::endl; return; } char *nt[2]; nt[0] = strtok(argv[0], "."); nt[1] = strtok(NULL, ""); char *s = strtok(NULL, ".,-!"); if ( (!nt[0]) || (!nt[1]) || (s) ) { out << "Введены некорректные данные" << std::endl; return; } if (fs->names_types(nt[0])||fs->names_types(nt[1])) { out << "Введены некорректные данные" << std::endl; return; } FileIterator* fi = fs->GetIterator(); FileIterator* prevfi = fs->GetIterator(); int j = 0; int next_index; int n = fs->GetFilesCount(); if (fs->GetFilesCount() != 0) { while (fi->HasNext()) { fi->Next(); FileDescriptor* fd = fi->GetFileDescriptor(); next_index = fi->GetNextIndex(); if (strcmpi(fd->GetName(), nt[0]) == 0 && strcmpi(fd->GetType(), nt[1]) == 0) { if (j == 0) { fs->set_first_file(next_index); } else { prevfi->set_next(next_index); } fi->Delete(); out << "Файл удален." << std::endl; return; } prevfi->Next(); j++; } out << "Файл с указанным именем не существует" << std::endl; } else out << "Файлов в системе не обнаружено." << std::endl; }
void commands_ns::Cmprs(FileSystem *fs, int argc, char *argv[], std::ostream& out) { if (argc > 0) { out << "This command must be used without argumnents" << std::endl; return; } if (fs->GetFilesCount() <= 0) { out << "no files" << std::endl; return; }//проверяем наличие файлов //формируем список блоков из дескрипторов по возрастанию смещения====== std::list < MemList> List; std::list<MemList>::iterator iter; FileIterator *fi = fs->GetIterator(); FileDescriptor *fd; MemList ml; unsigned int indx = 0, max_indx; while (fi->HasNext()) { fi->Next(); fd = fi->GetFileDescriptor(); ml.FDescrPtr = fd; ml.offset = fd->GetOffset(); ml.sz = fd->GetSize(); ml.index = indx; if (List.empty()) { List.push_front(ml); } else { for (iter = List.begin(); iter != List.end(); iter++) { if ( (ml.offset < (*iter).offset) || ((ml.offset == (*iter).offset) && (ml.sz < (*iter).sz)) ) { List.insert(iter, ml); break; } } if (iter == List.end()) { List.push_back(ml); } } ++indx; } max_indx = indx - 1; //вставляем пустой блок в начало, если нужно size_t FD_END = 0;//START_OF_FILE_SPACE; if ((*(List.begin())).offset > FD_END) { ml.offset = FD_END; ml.sz = (*(List.begin())).offset - FD_END; ml.FDescrPtr = NULL; //List.insert(List.begin(), ml); List.push_front(ml); } //вставляем пустые блоки в список for (iter = List.begin(); iter != List.end(); iter++) { if (std::next(iter) != List.end()) { if ((*(std::next(iter))).offset != ((*iter).offset + (*iter).sz)) { ml.offset = (*iter).offset + (*iter).sz; ml.sz = (*(std::next(iter))).offset - ml.offset; ml.FDescrPtr = NULL; List.insert(std::next(iter), ml); ++iter; } } } //=========================================================*/ out << "The whole data size before compressing: " << ((*(std::prev(List.end()))).offset + (*(std::prev(List.end()))).sz - (*(List.begin())).offset) << std::endl; //сжатие=================================================== for (iter = List.begin(); iter != List.end(); iter++) { if (!((*iter).FDescrPtr))//если текущий блок пустой { if (std::next(iter) != List.end())//если не последний { //ищем наибольший влезающий в текущий пустой блок с конца std::list<MemList>::iterator MaxAppr = List.end(); for (std::list<MemList>::iterator insIter = std::prev(List.end()); insIter != iter; insIter--) { if ((*insIter).FDescrPtr) { if ( ( (MaxAppr == List.end()) || ((*insIter).sz > (*MaxAppr).sz) ) && ((*insIter).sz <= (*iter).sz) && ((*insIter).sz > 0) ) { MaxAppr = insIter; } } } if (MaxAppr != List.end())//если нашёлся { MemList mlCopy = (*MaxAppr);//копируем //делаем перемещаемый блок пустым (*MaxAppr).FDescrPtr = NULL; if ( (std::next(MaxAppr) != List.end()) && ((*(std::next(MaxAppr))).FDescrPtr == NULL) )//если следующий пустой - объединяем { size_t rmv_size = (*(std::next(MaxAppr))).sz; List.erase(std::next(MaxAppr)); (*MaxAppr).sz += rmv_size; } if ((*(std::prev(MaxAppr))).FDescrPtr == NULL)//аналогично с предыдущим { size_t rmv_size = (*MaxAppr).sz; std::list<MemList>::iterator li = std::prev(MaxAppr); (*li).sz += rmv_size; List.erase(MaxAppr); } //вставляем копию перед текущим пустым блоком mlCopy.offset = (*iter).offset; List.insert(iter, mlCopy); //корректируем смещение и размер пустого блока после вставки (*iter).sz -= mlCopy.sz; (*iter).offset += mlCopy.sz; //если перемещаемый блок полностью заполнил пустой блок - удаляем текущий пустой блок if ((*iter).sz == 0) { std::list<MemList>::iterator li = std::prev(iter); List.erase(iter); iter = li;//ставим указатель на предыдущий } else//если пустое место осталось { if ( (std::next(iter) != List.end()) && ((*(std::next(iter))).FDescrPtr == NULL) )//если следущий пуст - объединяем { size_t rmv_size = (*(std::next(iter))).sz; List.erase(std::next(iter)); (*iter).sz += rmv_size; } --iter;//ставим указатель на предыдущий (он существует, так как только что вставили) } } else//если не нашёлся блок для вставки { //удаляем текущий пустой блок size_t rmv_size = (*iter).sz; std::list<MemList>::iterator insIter = List.erase(iter); //уменьшаем смещение всех последующих до пустого блока for (; ((*insIter).FDescrPtr && (insIter != List.end())); insIter++) { (*insIter).offset -= rmv_size; } //если встретился пустой блок if (insIter != List.end()) { (*insIter).offset -= rmv_size;//уменьшаем смещение (*insIter).sz += rmv_size;//увеличиваем размер iter = insIter;//ставим указатель на предыдущий блок --iter; } else//если нет больше пустых блоков - завершаем цикл { break; } } } else//если последний { List.erase(iter);//удаляем break;//выходим из цикла } } } //записываем изменения в файл================ for (iter = List.begin(); iter != List.end(); iter++) { (*iter).FDescrPtr->SetOffset((*iter).offset); }//меняем смещение в дескрипторах fi = fs->GetIterator(); for (indx = 0; indx <= max_indx; indx++) { for (iter = List.begin(); ( (iter != List.end()) && ((*iter).index != indx) ); iter++) {} fi->Next(); fi->SetFileDescriptor((*iter).FDescrPtr); } fi->Close(); //выводим результат out << "The whole data size after compressing: " << ( (*(std::prev(List.end()))).offset + (*(std::prev(List.end()))).sz - (*(List.begin())).offset) << std::endl; }
File* File::getChild(int childIdx) const { if (physicallyExists()) { if (isRegularFile()) { FileContentType type = guessContentType(); if (type == CONTENT_TYPE_DIR || type == CONTENT_TYPE_IMG) { try { boost::shared_ptr<IMGArchive> archive = getIMGArchive(); if (childIdx >= archive->getEntryCount()) { return NULL; } IMGArchive::EntryIterator it = archive->getEntryBegin(); for (int i = 0 ; it != archive->getEntryEnd() && i < childIdx ; it++, i++); return new File(*this, (*it)->name); } catch (Exception& ex) { char* errMsg = new char[path->toString().length() + 64]; sprintf(errMsg, "Exception thrown during child count of IMG archive %s.", path->toString().get()); FileException fex(errMsg, __FILE__, __LINE__, &ex); delete[] errMsg; throw fex; } } else { char* errmsg = new char[path->toString().length() + 128]; sprintf(errmsg, "Called getChild(int) with a regular non-archive file: '%s'", path->toString().get()); FileException ex(errmsg, __FILE__, __LINE__); delete[] errmsg; throw ex; } } else if (isDirectory()) { FileIterator* it = getIterator(); File* nextFile = NULL; for (int i = 0 ; i <= childIdx ; i++) { if (nextFile != NULL) { delete nextFile; } nextFile = it->next(); if (nextFile == NULL) { break; } } delete it; return nextFile; } else { char* errmsg = new char[path->toString().length() + 128]; sprintf(errmsg, "Called getChild(int) with file of invalid type: '%s'", path->toString().get()); FileException ex(errmsg, __FILE__, __LINE__); delete[] errmsg; throw ex; } } else { char* errmsg = new char[path->toString().length() + 128]; sprintf(errmsg, "Called getChild(int) with a non-existant file: '%s'", path->toString().get()); FileException ex(errmsg, __FILE__, __LINE__); delete[] errmsg; throw ex; } }
int CompactBlock::real_compact(LogicBlock* src, LogicBlock* dest) { assert(NULL != src && NULL != dest); BlockInfo dest_blk; BlockInfo* src_blk = src->get_block_info(); dest_blk.block_id_ = src_blk->block_id_; dest_blk.seq_no_ = src_blk->seq_no_; dest_blk.version_ = src_blk->version_; dest_blk.file_count_ = 0; dest_blk.size_ = 0; dest_blk.del_file_count_ = 0; dest_blk.del_size_ = 0; dest->set_last_update(time(NULL)); TBSYS_LOG(DEBUG, "compact block set last update. blockid: %u\n", dest->get_logic_block_id()); char* dest_buf = new char[MAX_COMPACT_READ_SIZE]; int32_t write_offset = 0, data_len = 0; int32_t w_file_offset = 0; RawMetaVec dest_metas; FileIterator* fit = new FileIterator(src); int ret = TFS_SUCCESS; while (fit->has_next()) { ret = fit->next(); if (TFS_SUCCESS != ret) { tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); return ret; } const FileInfo* pfinfo = fit->current_file_info(); if (pfinfo->flag_ & (FI_DELETED | FI_INVALID)) { continue; } FileInfo dfinfo = *pfinfo; dfinfo.offset_ = w_file_offset; // the size returned by FileIterator.current_file_info->size is // the size of file content!!! dfinfo.size_ = pfinfo->size_ + sizeof(FileInfo); dfinfo.usize_ = pfinfo->size_ + sizeof(FileInfo); w_file_offset += dfinfo.size_; dest_blk.file_count_++; dest_blk.size_ += dfinfo.size_; RawMeta tmp_meta; tmp_meta.set_file_id(dfinfo.id_); tmp_meta.set_size(dfinfo.size_); tmp_meta.set_offset(dfinfo.offset_); dest_metas.push_back(tmp_meta); // need flush write buffer if ((0 != data_len) && (fit->is_big_file() || data_len + dfinfo.size_ > MAX_COMPACT_READ_SIZE)) { TBSYS_LOG(DEBUG, "write one, blockid: %u, write offset: %d\n", dest->get_logic_block_id(), write_offset); ret = dest->write_raw_data(dest_buf, data_len, write_offset); if (TFS_SUCCESS != ret) { TBSYS_LOG(ERROR, "write raw data fail, blockid: %u, offset %d, readinglen: %d, ret :%d", dest->get_logic_block_id(), write_offset, data_len, ret); tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); return ret; } write_offset += data_len; data_len = 0; } if (fit->is_big_file()) { ret = write_big_file(src, dest, *pfinfo, dfinfo, write_offset); write_offset += dfinfo.size_; } else { memcpy(dest_buf + data_len, &dfinfo, sizeof(FileInfo)); int left_len = MAX_COMPACT_READ_SIZE - data_len; ret = fit->read_buffer(dest_buf + data_len + sizeof(FileInfo), left_len); data_len += dfinfo.size_; } if (TFS_SUCCESS != ret) { tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); return ret; } } // end of iterate if (0 != data_len) // flush the last buffer { TBSYS_LOG(DEBUG, "write one, blockid: %u, write offset: %d\n", dest->get_logic_block_id(), write_offset); ret = dest->write_raw_data(dest_buf, data_len, write_offset); if (TFS_SUCCESS != ret) { TBSYS_LOG(ERROR, "write raw data fail, blockid: %u, offset %d, readinglen: %d, ret :%d", dest->get_logic_block_id(), write_offset, data_len, ret); tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); return ret; } } tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); TBSYS_LOG(DEBUG, "compact write complete. blockid: %u\n", dest->get_logic_block_id()); ret = dest->batch_write_meta(&dest_blk, &dest_metas); if (TFS_SUCCESS != ret) { TBSYS_LOG(ERROR, "compact write segment meta failed. blockid: %u, meta size %zd\n", dest->get_logic_block_id(), dest_metas.size()); return ret; } TBSYS_LOG(DEBUG, "compact set dirty flag. blockid: %u\n", dest->get_logic_block_id()); ret = dest->set_block_dirty_type(C_DATA_CLEAN); if (TFS_SUCCESS != ret) { TBSYS_LOG(ERROR, "compact blockid: %u set dirty flag fail. ret: %d\n", dest->get_logic_block_id(), ret); return ret; } return TFS_SUCCESS; }