diff options
Diffstat (limited to 'lib/db_file.cpp')
-rw-r--r-- | lib/db_file.cpp | 398 |
1 files changed, 201 insertions, 197 deletions
diff --git a/lib/db_file.cpp b/lib/db_file.cpp index ab7f9212..1c2a34f3 100644 --- a/lib/db_file.cpp +++ b/lib/db_file.cpp @@ -24,16 +24,12 @@ namespace { //------------------------------------------------------------------------------------------------------------------------------- const char FILE_FORMAT_DESCR[] = "FreeFileSync"; -const int DB_FILE_FORMAT_VER = 9; - -warn_static("wee need two version ids!") -//const int DB_FILE_FORMAT_CONTAINER = 10; -//const int DB_FILE_FORMAT_STREAM = 1; - +const int DB_FORMAT_CONTAINER = 9; +const int DB_FORMAT_STREAM = 1; //------------------------------------------------------------------------------------------------------------------------------- typedef std::string UniqueId; -typedef std::map<UniqueId, BinaryStream> StreamMapping; //list of streams ordered by session UUID +typedef std::map<UniqueId, BinaryStream> DbStreams; //list of streams ordered by session UUID //----------------------------------------------------------------------------------- //| ensure 32/64 bit portability: use fixed size data types only e.g. std::uint32_t | @@ -58,7 +54,7 @@ Zstring getDBFilename(const BaseDirPair& baseDirObj, bool tempfile = false) //####################################################################################################################################### -void saveStreams(const StreamMapping& streamList, const Zstring& filename) //throw FileError +void saveStreams(const DbStreams& streamList, const Zstring& filename) //throw FileError { BinStreamOut streamOut; @@ -66,15 +62,15 @@ void saveStreams(const StreamMapping& streamList, const Zstring& filename) //thr writeArray(streamOut, FILE_FORMAT_DESCR, sizeof(FILE_FORMAT_DESCR)); //save file format version - writeNumber<std::int32_t>(streamOut, DB_FILE_FORMAT_VER); + writeNumber<std::int32_t>(streamOut, DB_FORMAT_CONTAINER); //save stream list writeNumber<std::uint32_t>(streamOut, static_cast<std::uint32_t>(streamList.size())); //number of streams, one for each sync-pair - for (auto it = streamList.begin(); it != streamList.end(); ++it) + for (const auto& stream : streamList) { - writeContainer<std::string >(streamOut, it->first ); - writeContainer<BinaryStream>(streamOut, it->second); + writeContainer<std::string >(streamOut, stream.first ); + writeContainer<BinaryStream>(streamOut, stream.second); } assert(!somethingExists(filename)); //orphan tmp files should be cleaned up already at this point! @@ -87,7 +83,7 @@ void saveStreams(const StreamMapping& streamList, const Zstring& filename) //thr } -StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorDatabaseNotExisting +DbStreams loadStreams(const Zstring& filename) //throw FileError, FileErrorDatabaseNotExisting { try { @@ -101,12 +97,12 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorD throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename))); const int version = readNumber<std::int32_t>(streamIn); //throw UnexpectedEndOfStreamError - if (version != DB_FILE_FORMAT_VER) //read file format version number + if (version != DB_FORMAT_CONTAINER) //read file format version number throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename))); - //read stream lists - StreamMapping output; + DbStreams output; + //read stream lists size_t dbCount = readNumber<std::uint32_t>(streamIn); //number of streams, one for each sync-pair while (dbCount-- != 0) { @@ -159,16 +155,16 @@ public: { /* Zlib: optimal level - testcase 1 million files level/size [MB]/time [ms] - 0 49.54 272 (uncompressed) - 1 14.53 1013 - 2 14.13 1106 - 3 13.76 1288 - best compromise between speed and compression - 4 13.20 1526 - 5 12.73 1916 - 6 12.58 2765 - 7 12.54 3633 - 8 12.51 9032 - 9 12.50 19698 (maximal compression) */ + 0 49.54 272 (uncompressed) + 1 14.53 1013 + 2 14.13 1106 + 3 13.76 1288 - best compromise between speed and compression + 4 13.20 1526 + 5 12.73 1916 + 6 12.58 2765 + 7 12.54 3633 + 8 12.51 9032 + 9 12.50 19698 (maximal compression) */ return compress(stream, 3); //throw ZlibInternalError } catch (ZlibInternalError&) @@ -181,14 +177,18 @@ public: const BinaryStream tmpR = compStream(generator.outputRight.get(), filenameR); const BinaryStream tmpB = compStream(generator.outputBoth .get(), filenameL + Zstr("/") + filenameR); - //distribute "outputBoth" over left and right streams: BinStreamOut outL; BinStreamOut outR; - writeNumber<bool>(outL, true); //this side contains first part of "outputBoth" - writeNumber<bool>(outR, false); + //save format version + writeNumber<std::int32_t>(outL, DB_FORMAT_STREAM); + writeNumber<std::int32_t>(outR, DB_FORMAT_STREAM); + + //distribute "outputBoth" over left and right streams: + writeNumber<std::int8_t>(outL, true); //this side contains first part of "outputBoth" + writeNumber<std::int8_t>(outR, false); - size_t size1stPart = tmpB.size() / 2; - size_t size2ndPart = tmpB.size() - size1stPart; + const size_t size1stPart = tmpB.size() / 2; + const size_t size2ndPart = tmpB.size() - size1stPart; writeNumber<std::uint64_t>(outL, size1stPart); writeNumber<std::uint64_t>(outR, size2ndPart); @@ -207,24 +207,42 @@ public: private: void recurse(const InSyncDir& container) { - // for (const auto& dbFile : container.files) { processFile(dbFile); }); ! - writeNumber<std::uint32_t>(outputBoth, static_cast<std::uint32_t>(container.files.size())); - std::for_each(container.files.begin(), container.files.end(), [&](const std::pair<Zstring, InSyncFile>& dbFile) { this->process(dbFile); }); + for (const auto& dbFile : container.files) + { + writeUtf8(outputBoth, dbFile.first); + writeNumber<std::int32_t>(outputBoth, dbFile.second.cmpVar); + writeNumber<std::uint64_t>(outputBoth, to<std::uint64_t>(dbFile.second.fileSize)); + + writeFile(outputLeft, dbFile.second.left); + writeFile(outputRight, dbFile.second.right); + } writeNumber<std::uint32_t>(outputBoth, static_cast<std::uint32_t>(container.symlinks.size())); - std::for_each(container.symlinks.begin(), container.symlinks.end(), [&](const std::pair<Zstring, InSyncSymlink>& dbSymlink) { this->process(dbSymlink); }); + for (const auto& dbSymlink : container.symlinks) + { + writeUtf8(outputBoth, dbSymlink.first); + writeNumber<std::int32_t>(outputBoth, dbSymlink.second.cmpVar); + + writeLink(outputLeft, dbSymlink.second.left); + writeLink(outputRight, dbSymlink.second.right); + } writeNumber<std::uint32_t>(outputBoth, static_cast<std::uint32_t>(container.dirs.size())); - std::for_each(container.dirs.begin(), container.dirs.end(), [&](const std::pair<Zstring, InSyncDir>& dbDir) { this->process(dbDir); }); + for (const auto& dbDir : container.dirs) + { + writeUtf8(outputBoth, dbDir.first); + writeNumber<std::int32_t>(outputBoth, dbDir.second.status); + + recurse(dbDir.second); + } } static void writeUtf8(BinStreamOut& output, const Zstring& str) { writeContainer(output, utfCvrtTo<Zbase<char>>(str)); } - static void writeFile(BinStreamOut& output, const InSyncDescrFile& descr, const UInt64& fileSize) + static void writeFile(BinStreamOut& output, const InSyncDescrFile& descr) { writeNumber<std:: int64_t>(output, to<std:: int64_t>(descr.lastWriteTimeRaw)); - writeNumber<std::uint64_t>(output, to<std::uint64_t>(fileSize)); writeNumber<std::uint64_t>(output, descr.fileId.first); writeNumber<std::uint64_t>(output, descr.fileId.second); assert_static(sizeof(descr.fileId.first ) <= sizeof(std::uint64_t)); @@ -234,47 +252,6 @@ private: static void writeLink(BinStreamOut& output, const InSyncDescrLink& descr) { writeNumber<std::int64_t>(output, to<std:: int64_t>(descr.lastWriteTimeRaw)); - - warn_static("implement proper migration!") - //writeUtf8(output, descr.targetPath); - writeUtf8(output, Zstring()); - //writeNumber<std::int32_t>(output, descr.type); - writeNumber<std::int32_t>(output, 0); - } - - static void writeDir(BinStreamOut& output, const InSyncDir::InSyncStatus& status) - { - writeNumber<std::int32_t>(output, status); - } - - void process(const std::pair<Zstring, InSyncFile>& dbFile) - { - writeUtf8(outputBoth, dbFile.first); - writeNumber<std::int32_t>(outputBoth, dbFile.second.inSyncType); - - warn_static("implement proper migration: get rid of duplicate fileSize!") - - writeFile(outputLeft, dbFile.second.left, dbFile.second.fileSize); - writeFile(outputRight, dbFile.second.right, dbFile.second.fileSize); - } - - void process(const std::pair<Zstring, InSyncSymlink>& dbSymlink) - { - writeUtf8(outputBoth, dbSymlink.first); - - warn_static("new parameter: imp proper migration!") - //writeNumber<std::int32_t>(outputBoth, dbSymlink.second.inSyncType); - - writeLink(outputLeft, dbSymlink.second.left); - writeLink(outputRight, dbSymlink.second.right); - } - - void process(const std::pair<Zstring, InSyncDir>& dbDir) - { - writeUtf8(outputBoth, dbDir.first); - writeDir(outputBoth, dbDir.second.status); - - recurse(dbDir.second); } BinStreamOut outputLeft; //data related to one side only @@ -283,7 +260,7 @@ private: }; -class StreamParser //for db-file back-wards compatibility we stick with two output streams until further +class StreamParser { public: static std::shared_ptr<InSyncDir> execute(const BinaryStream& streamL, //throw FileError @@ -308,8 +285,33 @@ public: BinStreamIn inL(streamL); BinStreamIn inR(streamR); - bool has1stPartL = readNumber<bool>(inL); //throw UnexpectedEndOfStreamError - bool has1stPartR = readNumber<bool>(inR); // + const int streamVersion = readNumber<std::int32_t>(inL); //throw UnexpectedEndOfStreamError + warn_static("remove this case after migration:") + bool migrateStreamFromOldFormat = streamVersion != DB_FORMAT_STREAM; + if (migrateStreamFromOldFormat) + inL = BinStreamIn(streamL); + else + { + const int streamVersionRef = readNumber<std::int32_t>(inR); //throw UnexpectedEndOfStreamError + if (streamVersionRef != streamVersion) //throw UnexpectedEndOfStreamError + throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filenameR), L"stream format mismatch")); + if (streamVersion != DB_FORMAT_STREAM) + throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filenameL), L"stream format")); + } + + bool has1stPartL = false; + bool has1stPartR = false; + if (migrateStreamFromOldFormat) + { + has1stPartL = readNumber<bool>(inL) != 0; //throw UnexpectedEndOfStreamError + has1stPartR = readNumber<bool>(inR) != 0; // + } + else + { + has1stPartL = readNumber<std::int8_t>(inL) != 0; //throw UnexpectedEndOfStreamError + has1stPartR = readNumber<std::int8_t>(inR) != 0; // + } + if (has1stPartL == has1stPartR) throw UnexpectedEndOfStreamError(); @@ -320,7 +322,7 @@ public: const size_t size2ndPart = static_cast<size_t>(readNumber<std::uint64_t>(in2ndPart)); BinaryStream tmpB; - tmpB.resize(size1stPart + size2ndPart); + tmpB.resize(size1stPart + size2ndPart); //throw bad_alloc readArray(in1stPart, &*tmpB.begin(), size1stPart); readArray(in2ndPart, &*tmpB.begin() + size1stPart, size2ndPart); @@ -330,7 +332,7 @@ public: auto output = std::make_shared<InSyncDir>(InSyncDir::DIR_STATUS_IN_SYNC); StreamParser parser(decompStream(tmpL, filenameL), decompStream(tmpR, filenameR), - decompStream(tmpB, filenameL + Zstr("/") + filenameR)); + decompStream(tmpB, filenameL + Zstr("/") + filenameR), migrateStreamFromOldFormat); parser.recurse(*output); //throw UnexpectedEndOfStreamError return output; } @@ -338,7 +340,7 @@ public: { throw FileError(_("Database file is corrupt:") + L"\n" + fmtFileName(filenameL) + L"\n" + fmtFileName(filenameR)); } - catch (const std::bad_alloc& e) //still required? + catch (const std::bad_alloc& e) { throw FileError(_("Database file is corrupt:") + L"\n" + fmtFileName(filenameL) + L"\n" + fmtFileName(filenameR), _("Out of memory.") + L" " + utfCvrtTo<std::wstring>(e.what())); @@ -348,57 +350,47 @@ public: private: StreamParser(const BinaryStream& bufferL, const BinaryStream& bufferR, - const BinaryStream& bufferB) : + const BinaryStream& bufferB, + bool migrateStreamFromOldFormat) : + migrateStreamFromOldFormat_(migrateStreamFromOldFormat), inputLeft (bufferL), inputRight(bufferR), inputBoth (bufferB) {} - static Zstring readUtf8(BinStreamIn& input) { return utfCvrtTo<Zstring>(readContainer<Zbase<char>>(input)); } //throw UnexpectedEndOfStreamError - - static InSyncDescrFile readFile(BinStreamIn& input, UInt64& fileSize) - { - //attention: order of function argument evaluation is undefined! So do it one after the other... - auto lastWriteTimeRaw = readNumber<std::int64_t>(input); //throw UnexpectedEndOfStreamError - warn_static("implement proper migration!") - fileSize = readNumber<std::uint64_t>(input); - auto devId = static_cast<DeviceId >(readNumber<std::uint64_t>(input)); // - auto fileIdx = static_cast<FileIndex>(readNumber<std::uint64_t>(input)); //silence "loss of precision" compiler warnings - return InSyncDescrFile(lastWriteTimeRaw, FileId(devId, fileIdx)); - } - - static InSyncDescrLink readLink(BinStreamIn& input) - { - auto lastWriteTimeRaw = readNumber<std::int64_t>(input); - - warn_static("implement proper migration!") - //descr.targetPath = readUtf8(input); - readUtf8(input); - //descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input)); - readNumber<std::int32_t>(input); - - return InSyncDescrLink(lastWriteTimeRaw); - } - - static void readDir(BinStreamIn& input, InSyncDir::InSyncStatus& status) - { - status = static_cast<InSyncDir::InSyncStatus>(readNumber<std::int32_t>(input)); - } - void recurse(InSyncDir& container) { size_t fileCount = readNumber<std::uint32_t>(inputBoth); while (fileCount-- != 0) { - warn_static("migrate from InSyncType to CompareVariant!!!") const Zstring shortName = readUtf8(inputBoth); - const auto inSyncType = static_cast<InSyncType>(readNumber<std::int32_t>(inputBoth)); - warn_static("implement proper migration: get rid of duplicate fileSize!") - - UInt64 fileSize; - const InSyncDescrFile dataL = readFile(inputLeft, fileSize); - const InSyncDescrFile dataR = readFile(inputRight, fileSize); - container.addFile(shortName, dataL, dataR, inSyncType, fileSize); + if (migrateStreamFromOldFormat_) + { + const auto inSyncType = readNumber<std::int32_t>(inputBoth); + const CompareVariant cmpVar = inSyncType == 0 ? CMP_BY_CONTENT : CMP_BY_TIME_SIZE; + + auto lastWriteTimeRawL = readNumber<std::int64_t>(inputLeft); //throw UnexpectedEndOfStreamError + const UInt64 fileSize = readNumber<std::uint64_t>(inputLeft); + auto devIdL = static_cast<DeviceId >(readNumber<std::uint64_t>(inputLeft)); // + auto fileIdxL = static_cast<FileIndex>(readNumber<std::uint64_t>(inputLeft)); //silence "loss of precision" compiler warnings + const InSyncDescrFile dataL = InSyncDescrFile(lastWriteTimeRawL, FileId(devIdL, fileIdxL)); + + auto lastWriteTimeRaw = readNumber<std::int64_t>(inputRight); //throw UnexpectedEndOfStreamError + readNumber<std::uint64_t>(inputRight); + auto devId = static_cast<DeviceId >(readNumber<std::uint64_t>(inputRight)); // + auto fileIdx = static_cast<FileIndex>(readNumber<std::uint64_t>(inputRight)); //silence "loss of precision" compiler warnings + const InSyncDescrFile dataR = InSyncDescrFile(lastWriteTimeRaw, FileId(devId, fileIdx)); + + container.addFile(shortName, dataL, dataR, cmpVar, fileSize); + } + else + { + const auto cmpVar = static_cast<CompareVariant>(readNumber<std::int32_t>(inputBoth)); + const UInt64 fileSize = readNumber<std::uint64_t>(inputBoth); + const InSyncDescrFile dataL = readFile(inputLeft); + const InSyncDescrFile dataR = readFile(inputRight); + container.addFile(shortName, dataL, dataR, cmpVar, fileSize); + } } size_t linkCount = readNumber<std::uint32_t>(inputBoth); @@ -406,28 +398,61 @@ private: { const Zstring shortName = readUtf8(inputBoth); - warn_static("new parameter: imp proper migration!") - const auto inSyncType = IN_SYNC_BINARY_EQUAL; - //const auto inSyncType = static_cast<InSyncType>(readNumber<std::int32_t>(inputBoth)); - - InSyncDescrLink dataL = readLink(inputLeft); - InSyncDescrLink dataR = readLink(inputRight); - container.addSymlink(shortName, dataL, dataR, inSyncType); + if (migrateStreamFromOldFormat_) + { + const CompareVariant cmpVar = CMP_BY_CONTENT; + auto lastWriteTimeRaw = readNumber<std::int64_t>(inputLeft); + readUtf8(inputLeft);//descr.targetPath = readUtf8(input); + readNumber<std::int32_t>(inputLeft);//descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input)); + InSyncDescrLink dataL = InSyncDescrLink(lastWriteTimeRaw); + + auto lastWriteTimeRawR = readNumber<std::int64_t>(inputRight); + readUtf8(inputRight);//descr.targetPath = readUtf8(input); + readNumber<std::int32_t>(inputRight);//descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input)); + InSyncDescrLink dataR = InSyncDescrLink(lastWriteTimeRawR); + + container.addSymlink(shortName, dataL, dataR, cmpVar); + } + else + { + const auto cmpVar = static_cast<CompareVariant>(readNumber<std::int32_t>(inputBoth)); + InSyncDescrLink dataL = readLink(inputLeft); + InSyncDescrLink dataR = readLink(inputRight); + container.addSymlink(shortName, dataL, dataR, cmpVar); + } } size_t dirCount = readNumber<std::uint32_t>(inputBoth); while (dirCount-- != 0) { const Zstring shortName = readUtf8(inputBoth); - - InSyncDir::InSyncStatus status = InSyncDir::DIR_STATUS_STRAW_MAN; - readDir(inputBoth, status); + auto status = static_cast<InSyncDir::InSyncStatus>(readNumber<std::int32_t>(inputBoth)); InSyncDir& subDir = container.addDir(shortName, status); recurse(subDir); } } + static Zstring readUtf8(BinStreamIn& input) { return utfCvrtTo<Zstring>(readContainer<Zbase<char>>(input)); } //throw UnexpectedEndOfStreamError + + static InSyncDescrFile readFile(BinStreamIn& input) + { + //attention: order of function argument evaluation is undefined! So do it one after the other... + auto lastWriteTimeRaw = readNumber<std::int64_t>(input); //throw UnexpectedEndOfStreamError + auto devId = static_cast<DeviceId >(readNumber<std::uint64_t>(input)); // + auto fileIdx = static_cast<FileIndex>(readNumber<std::uint64_t>(input)); //silence "loss of precision" compiler warnings + return InSyncDescrFile(lastWriteTimeRaw, FileId(devId, fileIdx)); + } + + static InSyncDescrLink readLink(BinStreamIn& input) + { + auto lastWriteTimeRaw = readNumber<std::int64_t>(input); + return InSyncDescrLink(lastWriteTimeRaw); + } + + warn_static("remove after migration") + bool migrateStreamFromOldFormat_; + BinStreamIn inputLeft; //data related to one side only BinStreamIn inputRight; // BinStreamIn inputBoth; //data concerning both sides @@ -446,24 +471,14 @@ class UpdateLastSynchronousState public: static void execute(const BaseDirPair& baseDirObj, InSyncDir& dir) { - bool binaryComparison = false; - switch (baseDirObj.getCompVariant()) - { - case CMP_BY_TIME_SIZE: - break; - case CMP_BY_CONTENT: - binaryComparison = true; - break; - } - - UpdateLastSynchronousState updater(baseDirObj.getFilter(), binaryComparison); + UpdateLastSynchronousState updater(baseDirObj.getCompVariant(), baseDirObj.getFilter()); updater.recurse(baseDirObj, dir); } private: - UpdateLastSynchronousState(const HardFilter& filter, bool binaryComparison) : + UpdateLastSynchronousState(CompareVariant activeCmpVar, const HardFilter& filter) : filter_(filter), - binaryComparison_(binaryComparison) {} + activeCmpVar_(activeCmpVar) {} void recurse(const HierarchyObject& hierObj, InSyncDir& dir) { @@ -516,8 +531,7 @@ private: void process(const HierarchyObject::SubFileVec& currentFiles, const Zstring& parentRelativeNamePf, InSyncDir::FileList& dbFiles) { hash_set<const InSyncFile*> toPreserve; //referencing fixed-in-memory std::map elements - std::for_each(currentFiles.begin(), currentFiles.end(), [&](const FilePair& fileObj) - { + for (const FilePair& fileObj : currentFiles) if (!fileObj.isEmpty()) { if (fileObj.getCategory() == FILE_EQUAL) //data in sync: write current state @@ -534,9 +548,7 @@ private: fileObj.getFileId <LEFT_SIDE>()), InSyncDescrFile(fileObj.getLastWriteTime<RIGHT_SIDE>(), fileObj.getFileId <RIGHT_SIDE>()), - binaryComparison_ ? - IN_SYNC_BINARY_EQUAL : - IN_SYNC_ATTRIBUTES_EQUAL, + activeCmpVar_, fileObj.getFileSize<LEFT_SIDE>())); toPreserve.insert(&file); } @@ -547,7 +559,6 @@ private: toPreserve.insert(&it->second); } } - }); warn_static("consider temporarily excluded items due to traveral error just like a fixed file filter here!?") //delete removed items (= "in-sync") from database @@ -564,8 +575,7 @@ private: void process(const HierarchyObject::SubLinkVec& currentLinks, const Zstring& parentRelativeNamePf, InSyncDir::LinkList& dbLinks) { hash_set<const InSyncSymlink*> toPreserve; - std::for_each(currentLinks.begin(), currentLinks.end(), [&](const SymlinkPair& linkObj) - { + for (const SymlinkPair& linkObj : currentLinks) if (!linkObj.isEmpty()) { if (linkObj.getLinkCategory() == SYMLINK_EQUAL) //data in sync: write current state @@ -576,9 +586,7 @@ private: InSyncSymlink& link = updateItem(dbLinks, linkObj.getObjShortName(), InSyncSymlink(InSyncDescrLink(linkObj.getLastWriteTime<LEFT_SIDE>()), InSyncDescrLink(linkObj.getLastWriteTime<RIGHT_SIDE>()), - binaryComparison_ ? - IN_SYNC_BINARY_EQUAL : - IN_SYNC_ATTRIBUTES_EQUAL)); + activeCmpVar_)); toPreserve.insert(&link); } else //not in sync: preserve last synchronous state @@ -588,7 +596,6 @@ private: toPreserve.insert(&it->second); } } - }); //delete removed items (= "in-sync") from database map_remove_if(dbLinks, [&](const InSyncDir::LinkList::value_type& v) -> bool @@ -604,8 +611,7 @@ private: void process(const HierarchyObject::SubDirVec& currentDirs, const Zstring& parentRelativeNamePf, InSyncDir::DirList& dbDirs) { hash_set<const InSyncDir*> toPreserve; - std::for_each(currentDirs.begin(), currentDirs.end(), [&](const DirPair& dirObj) - { + for (const DirPair& dirObj : currentDirs) if (!dirObj.isEmpty()) switch (dirObj.getDirCategory()) { @@ -659,7 +665,6 @@ private: } break; } - }); //delete removed items (= "in-sync") from database map_remove_if(dbDirs, [&](const InSyncDir::DirList::value_type& v) -> bool @@ -676,7 +681,7 @@ private: } const HardFilter& filter_; //filter used while scanning directory: generates view on actual files! - const bool binaryComparison_; + const CompareVariant activeCmpVar_; }; } @@ -698,17 +703,17 @@ std::shared_ptr<InSyncDir> zen::loadLastSynchronousState(const BaseDirPair& base } //read file data: list of session ID + DirInfo-stream - const StreamMapping streamListLeft = ::loadStreams(fileNameLeft); //throw FileError, FileErrorDatabaseNotExisting - const StreamMapping streamListRight = ::loadStreams(fileNameRight); // + const DbStreams streamsLeft = ::loadStreams(fileNameLeft); //throw FileError, FileErrorDatabaseNotExisting + const DbStreams streamsRight = ::loadStreams(fileNameRight); // //find associated session: there can be at most one session within intersection of left and right ids - for (auto iterLeft = streamListLeft.begin(); iterLeft != streamListLeft.end(); ++iterLeft) + for (const auto& streamLeft : streamsLeft) { - auto iterRight = streamListRight.find(iterLeft->first); - if (iterRight != streamListRight.end()) + auto itRight = streamsRight.find(streamLeft.first); + if (itRight != streamsRight.end()) { - return StreamParser::execute(iterLeft ->second, //throw FileError - iterRight->second, + return StreamParser::execute(streamLeft.second, //throw FileError + itRight->second, fileNameLeft, fileNameRight); } @@ -732,38 +737,37 @@ void zen::saveLastSynchronousState(const BaseDirPair& baseDirObj) //throw FileEr removeFile(dbNameRightTmp); //throw FileError //(try to) load old database files... - StreamMapping streamListLeft; - StreamMapping streamListRight; + DbStreams streamsLeft; //list of session ID + DirInfo-stream + DbStreams streamsRight; - //read file data: list of session ID + DirInfo-stream - try { streamListLeft = ::loadStreams(dbNameLeft ); } + try { streamsLeft = ::loadStreams(dbNameLeft ); } catch (FileError&) {} - try { streamListRight = ::loadStreams(dbNameRight); } + try { streamsRight = ::loadStreams(dbNameRight); } catch (FileError&) {} //if error occurs: just overwrite old file! User is already informed about issues right after comparing! //find associated session: there can be at most one session within intersection of left and right ids - auto streamIterLeftOld = streamListLeft .cend(); - auto streamIterRightOld = streamListRight.cend(); - for (auto iterLeft = streamListLeft.begin(); iterLeft != streamListLeft.end(); ++iterLeft) + auto itStreamLeftOld = streamsLeft .cend(); + auto itStreamRightOld = streamsRight.cend(); + for (auto iterLeft = streamsLeft.begin(); iterLeft != streamsLeft.end(); ++iterLeft) { - auto iterRight = streamListRight.find(iterLeft->first); - if (iterRight != streamListRight.end()) + auto iterRight = streamsRight.find(iterLeft->first); + if (iterRight != streamsRight.end()) { - streamIterLeftOld = iterLeft; - streamIterRightOld = iterRight; + itStreamLeftOld = iterLeft; + itStreamRightOld = iterRight; break; } } //load last synchrounous state std::shared_ptr<InSyncDir> lastSyncState = std::make_shared<InSyncDir>(InSyncDir::DIR_STATUS_IN_SYNC); - if (streamIterLeftOld != streamListLeft .end() && - streamIterRightOld != streamListRight.end()) + if (itStreamLeftOld != streamsLeft .end() && + itStreamRightOld != streamsRight.end()) try { - lastSyncState = StreamParser::execute(streamIterLeftOld ->second, //throw FileError - streamIterRightOld->second, + lastSyncState = StreamParser::execute(itStreamLeftOld ->second, //throw FileError + itStreamRightOld->second, dbNameLeft, dbNameRight); } @@ -782,28 +786,28 @@ void zen::saveLastSynchronousState(const BaseDirPair& baseDirObj) //throw FileEr updatedStreamRight); //throw FileError //check if there is some work to do at all - if (streamIterLeftOld != streamListLeft .end() && updatedStreamLeft == streamIterLeftOld ->second && - streamIterRightOld != streamListRight.end() && updatedStreamRight == streamIterRightOld->second) + if (itStreamLeftOld != streamsLeft .end() && updatedStreamLeft == itStreamLeftOld ->second && + itStreamRightOld != streamsRight.end() && updatedStreamRight == itStreamRightOld->second) return; //some users monitor the *.ffs_db file with RTS => don't touch the file if it isnt't strictly needed //erase old session data - if (streamIterLeftOld != streamListLeft.end()) - streamListLeft.erase(streamIterLeftOld); - if (streamIterRightOld != streamListRight.end()) - streamListRight.erase(streamIterRightOld); + if (itStreamLeftOld != streamsLeft.end()) + streamsLeft.erase(itStreamLeftOld); + if (itStreamRightOld != streamsRight.end()) + streamsRight.erase(itStreamRightOld); //create new session data const std::string sessionID = zen::generateGUID(); - streamListLeft [sessionID] = std::move(updatedStreamLeft); - streamListRight[sessionID] = std::move(updatedStreamRight); + streamsLeft [sessionID] = std::move(updatedStreamLeft); + streamsRight[sessionID] = std::move(updatedStreamRight); //write (temp-) files... zen::ScopeGuard guardTempFileLeft = zen::makeGuard([&] {zen::removeFile(dbNameLeftTmp); }); - saveStreams(streamListLeft, dbNameLeftTmp); //throw FileError + saveStreams(streamsLeft, dbNameLeftTmp); //throw FileError zen::ScopeGuard guardTempFileRight = zen::makeGuard([&] {zen::removeFile(dbNameRightTmp); }); - saveStreams(streamListRight, dbNameRightTmp); //throw FileError + saveStreams(streamsRight, dbNameRightTmp); //throw FileError //operation finished: rename temp files -> this should work transactionally: //if there were no write access, creation of temp files would have failed |