diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-12-19 21:13:31 -0500 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2020-02-04 03:33:18 -0500 |
| commit | 0a908c49625fe0e54bc45e29fe8c4908d20b0dbe (patch) | |
| tree | 98b2b6d7ebb5224b33c2ad55690ff9ceb72d16df | |
| parent | 72394faa750ac05871f62583c7c922879a20bc7b (diff) | |
added a map for directories in DirectoryEntry
more optimizations for filetree
| -rw-r--r-- | src/filetreeitem.cpp | 103 | ||||
| -rw-r--r-- | src/filetreeitem.h | 124 | ||||
| -rw-r--r-- | src/filetreemodel.cpp | 25 | ||||
| -rw-r--r-- | src/shared/directoryentry.cpp | 56 | ||||
| -rw-r--r-- | src/shared/directoryentry.h | 19 |
5 files changed, 186 insertions, 141 deletions
diff --git a/src/filetreeitem.cpp b/src/filetreeitem.cpp index c2f3a1fc..0469dfcc 100644 --- a/src/filetreeitem.cpp +++ b/src/filetreeitem.cpp @@ -27,11 +27,6 @@ FileTreeItem::FileTreeItem( { } -void FileTreeItem::add(std::unique_ptr<FileTreeItem> child) -{ - m_children.push_back(std::move(child)); -} - void FileTreeItem::insert(std::unique_ptr<FileTreeItem> child, std::size_t at) { if (at > m_children.size()) { @@ -55,26 +50,6 @@ void FileTreeItem::remove(std::size_t i) m_children.erase(m_children.begin() + i); } -const std::vector<std::unique_ptr<FileTreeItem>>& FileTreeItem::children() const -{ - return m_children; -} - -FileTreeItem* FileTreeItem::parent() -{ - return m_parent; -} - -int FileTreeItem::originID() const -{ - return m_originID; -} - -const QString& FileTreeItem::virtualParentPath() const -{ - return m_virtualParentPath; -} - QString FileTreeItem::virtualPath() const { QString s = "Data\\"; @@ -88,11 +63,6 @@ QString FileTreeItem::virtualPath() const return s; } -QString FileTreeItem::dataRelativeParentPath() const -{ - return m_virtualParentPath; -} - QString FileTreeItem::dataRelativeFilePath() const { auto path = dataRelativeParentPath(); @@ -103,31 +73,6 @@ QString FileTreeItem::dataRelativeFilePath() const return path += m_file; } -const QString& FileTreeItem::realPath() const -{ - return m_realPath; -} - -const QString& FileTreeItem::filename() const -{ - return m_file; -} - -const std::wstring& FileTreeItem::filenameWs() const -{ - return m_wsFile; -} - -const std::wstring& FileTreeItem::filenameWsLowerCase() const -{ - return m_wsLcFile; -} - -const QString& FileTreeItem::mod() const -{ - return m_mod; -} - QFont FileTreeItem::font() const { QFont f; @@ -150,49 +95,11 @@ QFileIconProvider::IconType FileTreeItem::icon() const } } -bool FileTreeItem::isDirectory() const -{ - return (m_flags & Directory); -} - -bool FileTreeItem::isFromArchive() const -{ - return (m_flags & FromArchive); -} - -bool FileTreeItem::isConflicted() const -{ - return (m_flags & Conflicted); -} - bool FileTreeItem::isHidden() const { return m_file.endsWith(ModInfo::s_HiddenExt); } -bool FileTreeItem::hasChildren() const -{ - if (!isDirectory()) { - return false; - } - - if (isLoaded() && m_children.empty()) { - return false; - } - - return true; -} - -void FileTreeItem::setLoaded(bool b) -{ - m_loaded = b; -} - -bool FileTreeItem::isLoaded() const -{ - return m_loaded; -} - void FileTreeItem::unload() { if (!m_loaded) { @@ -203,16 +110,6 @@ void FileTreeItem::unload() m_children.clear(); } -void FileTreeItem::setExpanded(bool b) -{ - m_expanded = b; -} - -bool FileTreeItem::isStrictlyExpanded() const -{ - return m_expanded; -} - bool FileTreeItem::areChildrenVisible() const { if (m_expanded) { diff --git a/src/filetreeitem.h b/src/filetreeitem.h index 423038ba..1e820f3f 100644 --- a/src/filetreeitem.h +++ b/src/filetreeitem.h @@ -27,39 +27,125 @@ public: FileTreeItem(FileTreeItem&&) = default; FileTreeItem& operator=(FileTreeItem&&) = default; - void add(std::unique_ptr<FileTreeItem> child); + void add(std::unique_ptr<FileTreeItem> child) + { + m_children.push_back(std::move(child)); + } + void insert(std::unique_ptr<FileTreeItem> child, std::size_t at); void remove(std::size_t i); - const std::vector<std::unique_ptr<FileTreeItem>>& children() const; - FileTreeItem* parent(); - int originID() const; - const QString& virtualParentPath() const; + const std::vector<std::unique_ptr<FileTreeItem>>& children() const + { + return m_children; + } + + + FileTreeItem* parent() + { + return m_parent; + } + + int originID() const + { + return m_originID; + } + + const QString& virtualParentPath() const + { + return m_virtualParentPath; + } + QString virtualPath() const; - const QString& filename() const; - const std::wstring& filenameWs() const; - const std::wstring& filenameWsLowerCase() const; - const QString& mod() const; + const QString& filename() const + { + return m_file; + } + + const std::wstring& filenameWs() const + { + return m_wsFile; + } + + const std::wstring& filenameWsLowerCase() const + { + return m_wsLcFile; + } + + const QString& mod() const + { + return m_mod; + } + QFont font() const; - const QString& realPath() const; - QString dataRelativeParentPath() const; + const QString& realPath() const + { + return m_realPath; + } + + const QString& dataRelativeParentPath() const + { + return m_virtualParentPath; + } + QString dataRelativeFilePath() const; QFileIconProvider::IconType icon() const; - bool isDirectory() const; - bool isFromArchive() const; - bool isConflicted() const; + bool isDirectory() const + { + return (m_flags & Directory); + } + + bool isFromArchive() const + { + return (m_flags & FromArchive); + } + + bool isConflicted() const + { + return (m_flags & Conflicted); + } + bool isHidden() const; - bool hasChildren() const; - void setLoaded(bool b); - bool isLoaded() const; + bool hasChildren() const + { + if (!isDirectory()) { + return false; + } + + if (isLoaded() && m_children.empty()) { + return false; + } + + return true; + } + + + void setLoaded(bool b) + { + m_loaded = b; + } + + bool isLoaded() const + { + return m_loaded; + } + void unload(); - void setExpanded(bool b); - bool isStrictlyExpanded() const; + void setExpanded(bool b) + { + m_expanded = b; + } + + bool isStrictlyExpanded() const + { + return m_expanded; + } + bool areChildrenVisible() const; QString debugName() const; diff --git a/src/filetreemodel.cpp b/src/filetreemodel.cpp index b5ae9dc8..9332b354 100644 --- a/src/filetreemodel.cpp +++ b/src/filetreemodel.cpp @@ -255,7 +255,7 @@ void FileTreeModel::updateDirectories( break; } - if (auto d=parentEntry.findSubDirectory(item->filenameWsLowerCase())) { + if (auto d=parentEntry.findSubDirectory(item->filenameWsLowerCase(), true)) { // directory still exists seen.insert(item->filenameWs()); @@ -418,7 +418,7 @@ void FileTreeModel::updateFiles( parentItem.debugName(), (path.empty() ? L"\\" : path)); }); - std::unordered_set<std::wstring_view> seen; + std::unordered_set<FileEntry::Index> seen; std::vector<FileTreeItem*> remove; for (auto&& item : parentItem.children()) { @@ -430,7 +430,7 @@ void FileTreeModel::updateFiles( if (shouldShowFile(*f)) { // file still exists trace([&]{ log::debug("{} still exists", item->debugName()); }); - seen.insert(item->filenameWs()); + seen.emplace(f->getIndex()); continue; } } @@ -483,9 +483,14 @@ void FileTreeModel::updateFiles( std::size_t insertPos = firstFile; - for (auto&& file : parentEntry.getFiles()) { - if (shouldShowFile(*file)) { - if (!seen.contains(file->getName())) { + parentEntry.forEachFileIndex([&](auto&& fileIndex) { + if (!seen.contains(fileIndex)) { + const auto& file = parentEntry.getFileByIndex(fileIndex); + if (!file) { + return true; + } + + if (shouldShowFile(*file)) { trace([&]{ log::debug( "{}: new file {}", parentItem.debugName(), QString::fromStdWString(file->getName())); @@ -532,11 +537,15 @@ void FileTreeModel::updateFiles( beginInsertRows(parentIndex, first, last); parentItem.insert(std::move(child), insertPos); endInsertRows(); + } else { + ++insertPos; } - + } else { ++insertPos; } - } + + return true; + }); } std::wstring FileTreeModel::makeModName(const FileEntry& file, int originID) const diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index c6b29fbb..97da1061 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -485,7 +485,9 @@ void DirectoryEntry::clear() for (DirectoryEntry *entry : m_SubDirectories) {
delete entry;
}
+
m_SubDirectories.clear();
+ m_SubDirectoriesMap.clear();
}
@@ -665,7 +667,9 @@ void DirectoryEntry::removeDirRecursive() entry->removeDirRecursive();
delete entry;
}
+
m_SubDirectories.clear();
+ m_SubDirectoriesMap.clear();
}
void DirectoryEntry::removeDir(const std::wstring &path)
@@ -676,6 +680,20 @@ void DirectoryEntry::removeDir(const std::wstring &path) DirectoryEntry *entry = *iter;
if (CaseInsensitiveEqual(entry->getName(), path)) {
entry->removeDirRecursive();
+
+ bool found = false;
+ for (auto iter2=m_SubDirectoriesMap.begin(); iter2!=m_SubDirectoriesMap.end(); ++iter2) {
+ if (iter2->second == entry) {
+ m_SubDirectoriesMap.erase(iter2);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ log::error("entry {} not in sub directories map", entry->getName());
+ }
+
m_SubDirectories.erase(iter);
delete entry;
break;
@@ -858,14 +876,22 @@ const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring &path, const }
-DirectoryEntry *DirectoryEntry::findSubDirectory(const std::wstring &name) const
+DirectoryEntry *DirectoryEntry::findSubDirectory(
+ const std::wstring &name, bool alreadyLowerCase) const
{
- for (DirectoryEntry *entry : m_SubDirectories) {
- if (CaseInsensitiveEqual(entry->getName(), name)) {
- return entry;
- }
+ SubDirectoriesMap::const_iterator itor;
+
+ if (alreadyLowerCase) {
+ itor = m_SubDirectoriesMap.find(name);
+ } else {
+ itor = m_SubDirectoriesMap.find(ToLower(name));
+ }
+
+ if (itor == m_SubDirectoriesMap.end()) {
+ return nullptr;
}
- return nullptr;
+
+ return itor->second;
}
@@ -878,7 +904,13 @@ DirectoryEntry *DirectoryEntry::findSubDirectoryRecursive(const std::wstring &pa const FileEntry::Ptr DirectoryEntry::findFile(
const std::wstring &name, bool alreadyLowerCase) const
{
- auto iter = m_Files.find(alreadyLowerCase ? name : ToLower(name));
+ std::map<std::wstring, FileEntry::Index>::const_iterator iter;
+
+ if (alreadyLowerCase) {
+ iter = m_Files.find(name);
+ } else {
+ iter = m_Files.find(ToLower(name));
+ }
if (iter != m_Files.end()) {
return m_FileRegister->getFile(iter->second);
@@ -900,9 +932,13 @@ DirectoryEntry *DirectoryEntry::getSubDirectory(const std::wstring &name, bool c }
}
if (create) {
- std::vector<DirectoryEntry*>::iterator iter = m_SubDirectories.insert(m_SubDirectories.end(),
- new DirectoryEntry(name, this, originID, m_FileRegister, m_OriginConnection));
- return *iter;
+ auto* entry = new DirectoryEntry(
+ name, this, originID, m_FileRegister, m_OriginConnection);
+
+ m_SubDirectories.push_back(entry);
+ m_SubDirectoriesMap.emplace(ToLower(name), entry);
+
+ return entry;
} else {
return nullptr;
}
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h index d33b495a..79bc5cf2 100644 --- a/src/shared/directoryentry.h +++ b/src/shared/directoryentry.h @@ -271,7 +271,22 @@ public: }
}
- DirectoryEntry *findSubDirectory(const std::wstring &name) const;
+ template <class F>
+ void forEachFileIndex(F&& f) const
+ {
+ for (auto&& p : m_Files) {
+ if (!f(p.second)) {
+ break;
+ }
+ }
+ }
+
+ FileEntry::Ptr getFileByIndex(FileEntry::Index index) const
+ {
+ return m_FileRegister->getFile(index);
+ }
+
+ DirectoryEntry *findSubDirectory(const std::wstring &name, bool alreadyLowerCase=false) const;
DirectoryEntry *findSubDirectoryRecursive(const std::wstring &path);
/** retrieve a file in this directory by name.
@@ -352,6 +367,7 @@ private: void removeDirRecursive();
private:
+ using SubDirectoriesMap = std::unordered_map<std::wstring, DirectoryEntry*>;
boost::shared_ptr<FileRegister> m_FileRegister;
boost::shared_ptr<OriginConnection> m_OriginConnection;
@@ -359,6 +375,7 @@ private: std::wstring m_Name;
std::map<std::wstring, FileEntry::Index> m_Files;
std::vector<DirectoryEntry*> m_SubDirectories;
+ SubDirectoriesMap m_SubDirectoriesMap;
DirectoryEntry *m_Parent;
std::set<int> m_Origins;
|
