Skip to content

Commit

Permalink
Rework tags for performance (#1960)
Browse files Browse the repository at this point in the history
* Optimize tagreload, remove unused method

* Use unused count method for counting

* Optimize untagged note count

* Dont reloadTagTree if the tag panel is not visible
  • Loading branch information
Waqar144 committed Nov 24, 2020
1 parent 8168e7e commit b9bb160
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 93 deletions.
44 changes: 20 additions & 24 deletions src/entities/note.cpp
Expand Up @@ -746,27 +746,6 @@ QVector<int> Note::noteIdListFromNoteList(const QVector<Note> &noteList) {
return idList;
}

/**
* Returns all notes that are not tagged
*/
QVector<Note> Note::fetchAllNotTagged(int activeNoteSubFolderId) {
QVector<Note> noteList;
if (activeNoteSubFolderId < 0) {
noteList = Note::fetchAll();
} else {
noteList = Note::fetchAllByNoteSubFolderId(activeNoteSubFolderId);
}
QVector<Note> untaggedNoteList;
untaggedNoteList.reserve(noteList.size());

QVector<Note>::const_iterator i;
for (i = noteList.constBegin(); i != noteList.constEnd(); ++i) {
const int tagCount = Tag::countAllOfNote(*i);
if (tagCount == 0) untaggedNoteList.append(*i);
}
return untaggedNoteList;
}

/**
* Returns all notes names that are not tagged
*/
Expand All @@ -777,8 +756,9 @@ QVector<int> Note::fetchAllNotTaggedIds() {

QVector<Note>::const_iterator it = noteList.constBegin();
for (; it != noteList.constEnd(); ++it) {
const int tagCount = Tag::countAllOfNote(*it);
if (tagCount == 0) untaggedNoteIdList << it->getId();
if (!Tag::noteHasTags(*it, QString())) {
untaggedNoteIdList << it->getId();
}
}

return untaggedNoteIdList;
Expand All @@ -788,7 +768,23 @@ QVector<int> Note::fetchAllNotTaggedIds() {
* Counts all notes that are not tagged
*/
int Note::countAllNotTagged(int activeNoteSubFolderId) {
return Note::fetchAllNotTagged(activeNoteSubFolderId).count();
QVector<Note> noteList;
QString path;
if (activeNoteSubFolderId < 0) {
noteList = Note::fetchAll();
} else {
noteList = Note::fetchAllByNoteSubFolderId(activeNoteSubFolderId);
path = NoteSubFolder::fetch(activeNoteSubFolderId).relativePath();
}

QVector<Note>::const_iterator i;
int count = 0;
for (i = noteList.constBegin(); i != noteList.constEnd(); ++i) {
if (!Tag::noteHasTags(*i, path)) {
count++;
}
}
return count;
}

QVector<Note> Note::search(const QString &text) {
Expand Down
2 changes: 0 additions & 2 deletions src/entities/note.h
Expand Up @@ -66,8 +66,6 @@ class Note {

static QVector<Note> fetchAll(int limit = -1);

static QVector<Note> fetchAllNotTagged(int activeNoteSubFolderId);

static QVector<int> fetchAllNotTaggedIds();

static int countAllNotTagged(int activeNoteSubFolderId = -1);
Expand Down
32 changes: 19 additions & 13 deletions src/entities/tag.cpp
Expand Up @@ -583,27 +583,28 @@ Tag Tag::fetchOneOfNoteWithColor(const Note &note) {
}

/**
* Count all linked tags of a note
* Checks if a note has tags
*/
int Tag::countAllOfNote(const Note &note) {
bool Tag::noteHasTags(const Note &note, const QString& path) {
QSqlDatabase db = DatabaseService::getNoteFolderDatabase();
QSqlQuery query(db);

query.prepare(
QStringLiteral("SELECT COUNT(*) AS cnt FROM noteTagLink "
"WHERE note_file_name = :fileName AND "
"note_sub_folder_path = :noteSubFolderPath"));
QStringLiteral("SELECT "
"EXISTS (SELECT tag_id FROM noteTagLink "
"WHERE note_file_name=:fileName AND "
"note_sub_folder_path=:noteSubFolderPath) AS cnt"));
query.bindValue(QStringLiteral(":fileName"), note.getName());
query.bindValue(QStringLiteral(":noteSubFolderPath"),
note.getNoteSubFolder().relativePath());
path.isEmpty() ? note.getNoteSubFolder().relativePath() : path);

if (!query.exec()) {
qWarning() << __func__ << ": " << query.lastError();
} else if (query.first()) {
int result = query.value(QStringLiteral("cnt")).toInt();
DatabaseService::closeDatabaseConnection(db, query);

return result;
return result == 1;
}

DatabaseService::closeDatabaseConnection(db, query);
Expand Down Expand Up @@ -871,11 +872,16 @@ QStringList Tag::fetchAllNames() {
* Count the linked note file names for a note sub folder
*/
int Tag::countLinkedNoteFileNamesForNoteSubFolder(
const NoteSubFolder &noteSubFolder, const bool recursive) const {
int tagId, const NoteSubFolder &noteSubFolder,
bool fromAllSubfolders, const bool recursive) {
QSqlDatabase db = DatabaseService::getNoteFolderDatabase();
QSqlQuery query(db);

if (recursive) {
if (fromAllSubfolders) {
query.prepare(QStringLiteral(
"SELECT COUNT(note_file_name) AS cnt FROM noteTagLink "
"WHERE tag_id = :id"));
} else if (recursive) {
query.prepare(QStringLiteral(
"SELECT COUNT(note_file_name) AS cnt FROM noteTagLink "
"WHERE tag_id = :id AND "
Expand All @@ -890,7 +896,7 @@ int Tag::countLinkedNoteFileNamesForNoteSubFolder(
query.bindValue(QStringLiteral(":noteSubFolderPath"),
noteSubFolder.relativePath() + QLatin1Char('%'));
}
query.bindValue(QStringLiteral(":id"), _id);
query.bindValue(QStringLiteral(":id"), tagId);

if (!query.exec()) {
qWarning() << __func__ << ": " << query.lastError();
Expand All @@ -909,8 +915,8 @@ int Tag::countLinkedNoteFileNamesForNoteSubFolder(
/**
* Count the linked note file names
*/
int Tag::countLinkedNoteFileNames(const bool fromAllSubfolders,
const bool recursive) const {
int Tag::countLinkedNoteFileNames(int tagId, bool fromAllSubfolders,
bool recursive) {
QSqlDatabase db = DatabaseService::getNoteFolderDatabase();
QSqlQuery query(db);

Expand All @@ -934,7 +940,7 @@ int Tag::countLinkedNoteFileNames(const bool fromAllSubfolders,
query.bindValue(QStringLiteral(":noteSubFolderPath"),
NoteSubFolder::activeNoteSubFolder().relativePath());
}
query.bindValue(QStringLiteral(":id"), _id);
query.bindValue(QStringLiteral(":id"), tagId);

if (!query.exec()) {
qWarning() << __func__ << ": " << query.lastError();
Expand Down
11 changes: 6 additions & 5 deletions src/entities/tag.h
Expand Up @@ -75,11 +75,12 @@ class Tag : protected TagHeader {

bool isLinkedToNote(const Note &note) const;

int countLinkedNoteFileNames(const bool fromAllSubfolder,
const bool recursive) const;
static int countLinkedNoteFileNames(int tagId, bool fromAllSubfolders,
bool recursive);

int countLinkedNoteFileNamesForNoteSubFolder(
const NoteSubFolder &noteSubFolder, const bool recursive) const;
static int countLinkedNoteFileNamesForNoteSubFolder(
int tagId, const NoteSubFolder &noteSubFolder,
bool fromAllSubfolders, bool recursive);

int getParentId() const;

Expand Down Expand Up @@ -138,7 +139,7 @@ class Tag : protected TagHeader {

static int countAllParentId(const int parentId);

static int countAllOfNote(const Note &note);
static bool noteHasTags(const Note &note, const QString& path);

static void setAsActive(const int tagId);

Expand Down
62 changes: 15 additions & 47 deletions src/mainwindow.cpp
Expand Up @@ -8011,6 +8011,7 @@ void MainWindow::reloadTagTree() {
QIcon::fromTheme(QStringLiteral("edit-copy"),
QIcon(QStringLiteral(
":icons/breeze-qownnotes/16x16/edit-copy.svg"))));

// this time, the tags come first
buildTagTreeForParentItem();
// and get sorted
Expand Down Expand Up @@ -8299,7 +8300,7 @@ QTreeWidgetItem *MainWindow::addTagToTagTreeWidget(QTreeWidgetItem *parent,
const QString name = tag._name;
auto hideCount = QSettings().value("tagsPanelHideNoteCount", false).toBool();

QVector<int> linkedNoteIds;
int count = 0;
if (!hideCount) {
const QVector<int> tagIdListToCount = Tag::isTaggingShowNotesRecursively() ?
Tag::fetchTagIdsRecursivelyByParentId(tagId) : QVector<int>{tag._id};
Expand All @@ -8310,7 +8311,6 @@ QTreeWidgetItem *MainWindow::addTagToTagTreeWidget(QTreeWidgetItem *parent,
NoteSubFolder::isNoteSubfoldersPanelShowNotesRecursively();

if (selectedSubFolderItems.count() > 1) {
linkedNoteIds.reserve(tagIdListToCount.size());
for (const int tagIdToCount : tagIdListToCount) {
for (QTreeWidgetItem *folderItem : selectedSubFolderItems) {
int id = folderItem->data(0, Qt::UserRole).toInt();
Expand All @@ -8320,29 +8320,22 @@ QTreeWidgetItem *MainWindow::addTagToTagTreeWidget(QTreeWidgetItem *parent,
continue;
}

linkedNoteIds << Tag::fetchAllLinkedNoteIdsForFolder(
tagIdToCount,
folder, showNotesFromAllSubFolders,
isShowNotesRecursively);
count = Tag::countLinkedNoteFileNamesForNoteSubFolder(
tagIdToCount, folder,
showNotesFromAllSubFolders, isShowNotesRecursively);
}
}
} else {
linkedNoteIds.reserve(tagIdListToCount.size());
for (const int tagToCount : tagIdListToCount) {
linkedNoteIds << Tag::fetchAllLinkedNoteIds(
count = Tag::countLinkedNoteFileNames(
tagToCount,
showNotesFromAllSubFolders,
isShowNotesRecursively);
}
}

// remove duplicate note ids
linkedNoteIds.erase(
std::unique(linkedNoteIds.begin(), linkedNoteIds.end()),
linkedNoteIds.end());
}

const int linkCount = linkedNoteIds.count();
const int linkCount = count;
const QString toolTip = tr("show all notes tagged with '%1' (%2)")
.arg(name, QString::number(linkCount));
auto *item = new QTreeWidgetItem();
Expand Down Expand Up @@ -9796,33 +9789,6 @@ void MainWindow::copySelectedNotesToNoteSubFolder(
}
}

/**
* Returns true if one of the selected notes has a linked tag
*
* @return
*/
bool MainWindow::selectedNotesHaveTags() {
const auto items = ui->noteTreeWidget->selectedItems();
for (QTreeWidgetItem *item : items) {
if (item->data(0, Qt::UserRole + 1) != NoteType) {
continue;
}

const int noteId = item->data(0, Qt::UserRole).toInt();
const Note note = Note::fetch(noteId);

if (!note.isFetched()) {
continue;
}

if (Tag::countAllOfNote(note) > 0) {
return true;
}
}

return false;
}

/**
* Opens the widget to replace text in the current note
*/
Expand Down Expand Up @@ -10718,21 +10684,23 @@ void MainWindow::on_noteSubFolderTreeWidget_currentItemChanged(
filterNotes();
}

reloadTagTree();
if (isTagsEnabled()) {
reloadTagTree();
}
}

void MainWindow::on_noteSubFolderTreeWidget_itemSelectionChanged() {
const auto items = ui->noteSubFolderTreeWidget->selectedItems();
// if no items selected or only one selected
if (ui->noteSubFolderTreeWidget->selectedItems().count() <= 1) {
if (items.count() == 1) {
// on_noteSubFolderTreeWidget_currentItemChanged(items.first(),
// Q_NULLPTR);
}
return;
}

filterNotes();
reloadTagTree();

if (isTagsEnabled()) {
reloadTagTree();
}
}

void MainWindow::clearTagFilteringColumn() {
Expand Down
2 changes: 0 additions & 2 deletions src/mainwindow.h
Expand Up @@ -954,8 +954,6 @@ class MainWindow : public QMainWindow {
void createNewNote(QString noteName = QString(),
bool withNameAppend = true);

bool selectedNotesHaveTags();

void initTagButtonScrollArea();

static QIcon getSystemTrayIcon();
Expand Down

0 comments on commit b9bb160

Please sign in to comment.