optimize git log speed

This commit is contained in:
Roy Qu 2022-02-23 19:25:34 +08:00
parent 205d517fcd
commit 735eb92a13
2 changed files with 40 additions and 20 deletions

View File

@ -5,6 +5,10 @@
#include <QMenu> #include <QMenu>
//this is not thread safe, but it's the only solution i can find
static GitLogModel::CommitInfoCacheManager GitLogModel_CacheManager;
GitLogDialog::GitLogDialog(const QString& folder, QWidget *parent) : GitLogDialog::GitLogDialog(const QString& folder, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::GitLogDialog), ui(new Ui::GitLogDialog),
@ -27,6 +31,13 @@ GitLogModel::GitLogModel(const QString &folder, QObject *parent):
{ {
GitManager manager; GitManager manager;
mCount = manager.logCounts(folder); mCount = manager.logCounts(folder);
PCommitInfoCache infoCache = std::make_shared<CommitInfoCache>();
GitLogModel_CacheManager.insert(this,infoCache);
}
GitLogModel::~GitLogModel()
{
GitLogModel_CacheManager.remove(this);
} }
int GitLogModel::rowCount(const QModelIndex &parent) const int GitLogModel::rowCount(const QModelIndex &parent) const
@ -44,20 +55,15 @@ QVariant GitLogModel::data(const QModelIndex &index, int role) const
if (!index.isValid()) if (!index.isValid())
return QVariant(); return QVariant();
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
int row = index.row(); PGitCommitInfo info = commitInfo(index);
GitManager manager;
QList<PGitCommitInfo> listCommitInfos =
manager.log(mFolder,row,1);
if (listCommitInfos.isEmpty()) {
return QVariant();
}
switch(index.column()) { switch(index.column()) {
case 0: case 0:
return listCommitInfos[0]->authorDate; return info->authorDate;
case 1: case 1:
return listCommitInfos[0]->author; return info->author;
case 2: case 2:
return listCommitInfos[0]->title; return info->title;
} }
} }
return QVariant(); return QVariant();
@ -78,18 +84,28 @@ QVariant GitLogModel::headerData(int section, Qt::Orientation orientation, int r
return QVariant(); return QVariant();
} }
PGitCommitInfo GitLogModel::commitInfo(const QModelIndex &index) PGitCommitInfo GitLogModel::commitInfo(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return PGitCommitInfo(); return PGitCommitInfo();
int row = index.row(); int row = index.row();
GitManager manager; PCommitInfoCache infoCache = GitLogModel_CacheManager.value(this);
QList<PGitCommitInfo> listCommitInfos = PGitCommitInfo commitInfo;
manager.log(mFolder,row,1); if (!infoCache->contains(row)) {
if (listCommitInfos.isEmpty()) { GitManager manager;
return PGitCommitInfo(); QList<PGitCommitInfo> listCommitInfos =
} manager.log(mFolder,row,50);
return listCommitInfos[0]; if (listCommitInfos.isEmpty()) {
return PGitCommitInfo();
}
for (int i=0;i<listCommitInfos.count();i++) {
infoCache->insert(row+i,listCommitInfos[i]);
}
commitInfo = listCommitInfos[0];
} else
commitInfo = (*infoCache)[row];
return commitInfo;
} }
const QString &GitLogModel::folder() const const QString &GitLogModel::folder() const

View File

@ -12,7 +12,11 @@ class GitLogDialog;
class GitLogModel: public QAbstractTableModel { class GitLogModel: public QAbstractTableModel {
public: public:
using CommitInfoCache=QMap<int, PGitCommitInfo>;
using PCommitInfoCache=std::shared_ptr<CommitInfoCache>;
using CommitInfoCacheManager = QMap<const GitLogModel*, PCommitInfoCache>;
explicit GitLogModel(const QString& folder,QObject *parent = nullptr); explicit GitLogModel(const QString& folder,QObject *parent = nullptr);
~GitLogModel();
// QAbstractItemModel interface // QAbstractItemModel interface
public: public:
@ -20,7 +24,7 @@ public:
int columnCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
PGitCommitInfo commitInfo(const QModelIndex &index); PGitCommitInfo commitInfo(const QModelIndex &index) const;
const QString &folder() const; const QString &folder() const;
private: private:
@ -31,7 +35,6 @@ private:
class GitLogDialog : public QDialog class GitLogDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit GitLogDialog(const QString& folder, QWidget *parent = nullptr); explicit GitLogDialog(const QString& folder, QWidget *parent = nullptr);
~GitLogDialog(); ~GitLogDialog();
@ -47,4 +50,5 @@ private:
GitLogModel mModel; GitLogModel mModel;
}; };
#endif // GITLOGDIALOG_H #endif // GITLOGDIALOG_H