1-goldbach/{v4.2 → v5.0}/GoldbachModel.cpp RENAMED
@@ -1,135 +1,149 @@
1
  #include "GoldbachModel.h"
2
  #include "GoldbachWorker.h"
3
 
4
  #include <algorithm>
5
 
6
  GoldbachModel::GoldbachModel(QObject *parent)
7
  : QAbstractListModel(parent)
8
  {
9
  }
10
 
11
  int GoldbachModel::rowCount(const QModelIndex &parent) const
12
  {
13
  Q_UNUSED(parent);
14
  return this->fetchedRowCount;
15
  }
16
 
17
  QVariant GoldbachModel::data(const QModelIndex &index, int role) const
18
  {
19
  if (!index.isValid())
20
  return QVariant();
21
 
22
  if (index.row() >= this->countResults() || index.row() < 0)
23
  return QVariant();
24
 
25
  if (role == Qt::DisplayRole)
26
  return tr("%1: %2").arg( index.row() + 1 ).arg( this->findValue( index.row() ) );
27
 
28
  return QVariant();
29
  }
30
 
31
  const QString &GoldbachModel::findValue(int index) const
32
  {
33
  int row = 0;
34
  while ( index >= this->results[row].count() )
35
  index -= this->results[row++].count();
36
 
37
  return this->results[row][index];
38
  }
39
 
40
  int GoldbachModel::countResults() const
41
  {
42
  int resultCount = 0;
43
  for ( auto vector : this->results )
44
  resultCount += vector.count();
45
 
46
  return resultCount;
47
  }
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  void GoldbachModel::calculate(long long number)
50
  {
51
  this->beginResetModel();
52
 
53
  for ( GoldbachWorker* worker : this->workers )
54
  worker->deleteLater();
55
  this->workers.clear();
56
 
57
  int workerCount = qMin( QThread::idealThreadCount(), static_cast<int>(number - 2));
 
58
 
59
  this->progressPercents.clear();
60
  this->progressPercents.resize(workerCount);
61
 
62
  this->finishedWorkerCount = 0;
63
 
64
  this->results.clear();
65
  this->results.resize( workerCount );
66
 
67
  this->workers.reserve(workerCount);
68
 
69
  for ( int current = 0; current < workerCount; ++current )
70
  {
71
  //this->worker = new GoldbachWorker{number, this->results, this};
72
  GoldbachWorker* worker = new GoldbachWorker{number, current, workerCount, this->results[current], this};
73
  this->workers.append( worker );
74
 
75
  this->connect( worker, &GoldbachWorker::progressUpdated, this, &GoldbachModel::updateProgress );
76
  this->connect( worker, &GoldbachWorker::calculationDone, this, &GoldbachModel::workerDone );
77
 
78
  worker->start();
79
  }
80
 
81
  this->endResetModel();
82
  }
83
 
84
  void GoldbachModel::stop()
85
  {
86
  Q_ASSERT(this->workers.count() > 0);
87
  for ( GoldbachWorker* worker : this->workers )
88
  worker->requestInterruption();
89
  }
90
 
91
  bool GoldbachModel::canFetchMore(const QModelIndex &parent) const
92
  {
93
  Q_UNUSED(parent);
94
  return this->fetchedRowCount < this->countResults();
95
  }
96
 
97
  void GoldbachModel::fetchMore(const QModelIndex &parent)
98
  {
99
  Q_UNUSED(parent);
100
 
101
  int remainder = this->countResults() - this->fetchedRowCount;
102
  int itemsToFetch = qMin(100, remainder);
103
 
104
  if (itemsToFetch <= 0)
105
  return;
106
 
107
  beginInsertRows(QModelIndex(), this->fetchedRowCount, this->fetchedRowCount + itemsToFetch - 1);
108
  this->fetchedRowCount += itemsToFetch;
109
  endInsertRows();
110
  }
111
 
112
  void GoldbachModel::workerDone(long long sumCount)
113
  {
114
  Q_UNUSED(sumCount);
115
  Q_ASSERT( this->finishedWorkerCount < this->workers.count() );
116
  if ( ++this->finishedWorkerCount == this->workers.count() )
117
  emit this->calculationDone( this->countResults() );
118
  }
119
 
120
  void GoldbachModel::updateProgress(int workerId, int percent)
121
  {
122
  Q_ASSERT(workerId >= 0 && workerId < this->progressPercents.count());
123
  this->progressPercents[workerId] = percent;
124
 
125
  int minProgressPercent = * std::min_element( this->progressPercents.constBegin(), this->progressPercents.constEnd() );
126
 
127
  if ( this->overallProgressPercent != minProgressPercent )
128
  {
129
  this->overallProgressPercent = minProgressPercent;
130
  emit this->progressUpdated(percent);
131
  }
132
 
133
  if ( this->fetchedRowCount <= 0 )
134
  this->fetchMore(QModelIndex());
135
  }
1
  #include "GoldbachModel.h"
2
  #include "GoldbachWorker.h"
3
 
4
  #include <algorithm>
5
 
6
  GoldbachModel::GoldbachModel(QObject *parent)
7
  : QAbstractListModel(parent)
8
  {
9
  }
10
 
11
  int GoldbachModel::rowCount(const QModelIndex &parent) const
12
  {
13
  Q_UNUSED(parent);
14
  return this->fetchedRowCount;
15
  }
16
 
17
  QVariant GoldbachModel::data(const QModelIndex &index, int role) const
18
  {
19
  if (!index.isValid())
20
  return QVariant();
21
 
22
  if (index.row() >= this->countResults() || index.row() < 0)
23
  return QVariant();
24
 
25
  if (role == Qt::DisplayRole)
26
  return tr("%1: %2").arg( index.row() + 1 ).arg( this->findValue( index.row() ) );
27
 
28
  return QVariant();
29
  }
30
 
31
  const QString &GoldbachModel::findValue(int index) const
32
  {
33
  int row = 0;
34
  while ( index >= this->results[row].count() )
35
  index -= this->results[row++].count();
36
 
37
  return this->results[row][index];
38
  }
39
 
40
  int GoldbachModel::countResults() const
41
  {
42
  int resultCount = 0;
43
  for ( auto vector : this->results )
44
  resultCount += vector.count();
45
 
46
  return resultCount;
47
  }
48
 
49
+ QVector<QString> GoldbachModel::fetchAllSums() const
50
+ {
51
+ QVector<QString> allSums;
52
+
53
+ allSums.reserve( this->countResults() );
54
+
55
+ for ( const QVector<QString>& resultsOfWorker : this->results )
56
+ for ( const QString& sum : resultsOfWorker )
57
+ allSums.append( tr("%1: %2").arg( allSums.count() + 1 ).arg(sum) );
58
+
59
+ return allSums;
60
+ }
61
+
62
  void GoldbachModel::calculate(long long number)
63
  {
64
  this->beginResetModel();
65
 
66
  for ( GoldbachWorker* worker : this->workers )
67
  worker->deleteLater();
68
  this->workers.clear();
69
 
70
  int workerCount = qMin( QThread::idealThreadCount(), static_cast<int>(number - 2));
71
+ workerCount = qMax(workerCount, 1);
72
 
73
  this->progressPercents.clear();
74
  this->progressPercents.resize(workerCount);
75
 
76
  this->finishedWorkerCount = 0;
77
 
78
  this->results.clear();
79
  this->results.resize( workerCount );
80
 
81
  this->workers.reserve(workerCount);
82
 
83
  for ( int current = 0; current < workerCount; ++current )
84
  {
85
  //this->worker = new GoldbachWorker{number, this->results, this};
86
  GoldbachWorker* worker = new GoldbachWorker{number, current, workerCount, this->results[current], this};
87
  this->workers.append( worker );
88
 
89
  this->connect( worker, &GoldbachWorker::progressUpdated, this, &GoldbachModel::updateProgress );
90
  this->connect( worker, &GoldbachWorker::calculationDone, this, &GoldbachModel::workerDone );
91
 
92
  worker->start();
93
  }
94
 
95
  this->endResetModel();
96
  }
97
 
98
  void GoldbachModel::stop()
99
  {
100
  Q_ASSERT(this->workers.count() > 0);
101
  for ( GoldbachWorker* worker : this->workers )
102
  worker->requestInterruption();
103
  }
104
 
105
  bool GoldbachModel::canFetchMore(const QModelIndex &parent) const
106
  {
107
  Q_UNUSED(parent);
108
  return this->fetchedRowCount < this->countResults();
109
  }
110
 
111
  void GoldbachModel::fetchMore(const QModelIndex &parent)
112
  {
113
  Q_UNUSED(parent);
114
 
115
  int remainder = this->countResults() - this->fetchedRowCount;
116
  int itemsToFetch = qMin(100, remainder);
117
 
118
  if (itemsToFetch <= 0)
119
  return;
120
 
121
  beginInsertRows(QModelIndex(), this->fetchedRowCount, this->fetchedRowCount + itemsToFetch - 1);
122
  this->fetchedRowCount += itemsToFetch;
123
  endInsertRows();
124
  }
125
 
126
  void GoldbachModel::workerDone(long long sumCount)
127
  {
128
  Q_UNUSED(sumCount);
129
  Q_ASSERT( this->finishedWorkerCount < this->workers.count() );
130
  if ( ++this->finishedWorkerCount == this->workers.count() )
131
  emit this->calculationDone( this->countResults() );
132
  }
133
 
134
  void GoldbachModel::updateProgress(int workerId, int percent)
135
  {
136
  Q_ASSERT(workerId >= 0 && workerId < this->progressPercents.count());
137
  this->progressPercents[workerId] = percent;
138
 
139
  int minProgressPercent = * std::min_element( this->progressPercents.constBegin(), this->progressPercents.constEnd() );
140
 
141
  if ( this->overallProgressPercent != minProgressPercent )
142
  {
143
  this->overallProgressPercent = minProgressPercent;
144
  emit this->progressUpdated(percent);
145
  }
146
 
147
  if ( this->fetchedRowCount <= 0 )
148
  this->fetchMore(QModelIndex());
149
  }