summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-12-19 21:13:31 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2020-02-04 03:33:18 -0500
commit0a908c49625fe0e54bc45e29fe8c4908d20b0dbe (patch)
tree98b2b6d7ebb5224b33c2ad55690ff9ceb72d16df
parent72394faa750ac05871f62583c7c922879a20bc7b (diff)
added a map for directories in DirectoryEntry
more optimizations for filetree
-rw-r--r--src/filetreeitem.cpp103
-rw-r--r--src/filetreeitem.h124
-rw-r--r--src/filetreemodel.cpp25
-rw-r--r--src/shared/directoryentry.cpp56
-rw-r--r--src/shared/directoryentry.h19
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;