From: Olivier Goffart Date: Mon, 25 Sep 2017 08:33:12 +0000 (+0200) Subject: csync_rename: optimize lookup X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~701^2~27 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=6583ebdcd9232ac626574238b33b815ce66b7b8c;p=nextcloud-desktop.git csync_rename: optimize lookup Avoid many memory allocations in reconcile --- diff --git a/src/csync/csync_private.h b/src/csync/csync_private.h index 010e884e3..09d627b2c 100644 --- a/src/csync/csync_private.h +++ b/src/csync/csync_private.h @@ -81,29 +81,34 @@ class ByteArrayRef int _begin = 0; int _size = -1; + /* Pointer to the beginning of the data. WARNING: not null terminated */ + const char *data() const { return _arr.constData() + _begin; } + friend struct ByteArrayRefHash; + public: - ByteArrayRef(const QByteArray &arr = {}, int begin = 0, int size = -1) - : _arr(arr) + ByteArrayRef(QByteArray arr = {}, int begin = 0, int size = -1) + : _arr(std::move(arr)) , _begin(begin) - , _size(qMin(arr.size() - begin, size < 0 ? arr.size() : size)) + , _size(qMin(_arr.size() - begin, size < 0 ? _arr.size() - begin : size)) { } ByteArrayRef left(int l) const { return ByteArrayRef(_arr, _begin, l); }; char at(int x) const { return _arr.at(_begin + x); } int size() const { return _size; } - /* Pointer to the beginning of the data. WARNING: not null terminated */ - const char *data() const { return _arr.constData() + _begin; } + int length() const { return _size; } + bool isEmpty() const { return _size == 0; } friend bool operator==(const ByteArrayRef &a, const ByteArrayRef &b) { return a.size() == b.size() && qstrncmp(a.data(), b.data(), a.size()) == 0; } }; +struct ByteArrayRefHash { uint operator()(const ByteArrayRef &a) const { return qHashBits(a.data(), a.size()); } }; /** * @brief csync public structure */ struct OCSYNC_EXPORT csync_s { - struct FileMapHash { uint operator()(const ByteArrayRef &a) const { return qHashBits(a.data(), a.size()); } }; - class FileMap : public std::unordered_map, FileMapHash> { + + class FileMap : public std::unordered_map, ByteArrayRefHash> { public: csync_file_stat_t *findFile(const ByteArrayRef &key) const { auto it = find(key); @@ -137,8 +142,8 @@ struct OCSYNC_EXPORT csync_s { OCC::SyncJournalDb *statedb; struct { - std::map folder_renamed_to; // map from->to - std::map folder_renamed_from; // map to->from + std::unordered_map folder_renamed_to; // map from->to + std::unordered_map folder_renamed_from; // map to->from } renames; struct { diff --git a/src/csync/csync_reconcile.cpp b/src/csync/csync_reconcile.cpp index 80bd91ee1..52ebba36f 100644 --- a/src/csync/csync_reconcile.cpp +++ b/src/csync/csync_reconcile.cpp @@ -47,7 +47,7 @@ static csync_file_stat_t *_csync_check_ignored(csync_s::FileMap *tree, const Byt if (parentlen <= 0) { return nullptr; } - auto parentPath = path.left(parentlen); + ByteArrayRef parentPath = path.left(parentlen); csync_file_stat_t *fs = tree->findFile(parentPath); if (fs) { if (fs->instruction == CSYNC_INSTRUCTION_IGNORE) { diff --git a/src/csync/csync_rename.cpp b/src/csync/csync_rename.cpp index ef825a606..da76cff52 100644 --- a/src/csync/csync_rename.cpp +++ b/src/csync/csync_rename.cpp @@ -23,7 +23,7 @@ #include -static QByteArray _parentDir(const QByteArray &path) { +static ByteArrayRef _parentDir(const ByteArrayRef &path) { int len = path.length(); while(len > 0 && path.at(len-1)!='/') len--; while(len > 0 && path.at(len-1)=='/') len--; @@ -38,8 +38,10 @@ void csync_rename_record(CSYNC* ctx, const QByteArray &from, const QByteArray &t QByteArray csync_rename_adjust_path(CSYNC* ctx, const QByteArray &path) { - for (QByteArray p = _parentDir(path); !p.isEmpty(); p = _parentDir(p)) { - std::map< QByteArray, QByteArray >::iterator it = ctx->renames.folder_renamed_to.find(p); + if (ctx->renames.folder_renamed_to.empty()) + return path; + for (auto p = _parentDir(path); !p.isEmpty(); p = _parentDir(p)) { + auto it = ctx->renames.folder_renamed_to.find(p); if (it != ctx->renames.folder_renamed_to.end()) { QByteArray rep = it->second + path.mid(p.length()); return rep; @@ -50,8 +52,10 @@ QByteArray csync_rename_adjust_path(CSYNC* ctx, const QByteArray &path) QByteArray csync_rename_adjust_path_source(CSYNC* ctx, const QByteArray &path) { - for (QByteArray p = _parentDir(path); !p.isEmpty(); p = _parentDir(p)) { - std::map< QByteArray, QByteArray >::iterator it = ctx->renames.folder_renamed_from.find(p); + if (ctx->renames.folder_renamed_from.empty()) + return path; + for (auto p = _parentDir(path); !p.isEmpty(); p = _parentDir(p)) { + auto it = ctx->renames.folder_renamed_from.find(p); if (it != ctx->renames.folder_renamed_from.end()) { QByteArray rep = it->second + path.mid(p.length()); return rep;