1-goldbach/{v3.1 → v4.0}/GoldbachModel.cpp RENAMED
@@ -1,84 +1,114 @@
1
  #include "GoldbachModel.h"
2
  #include "GoldbachWorker.h"
3
 
4
  GoldbachModel::GoldbachModel(QObject *parent)
5
  : QAbstractListModel(parent)
6
  {
7
  }
8
 
9
  int GoldbachModel::rowCount(const QModelIndex &parent) const
10
  {
11
  Q_UNUSED(parent);
12
  return this->fetchedRowCount;
13
  }
14
 
15
  QVariant GoldbachModel::data(const QModelIndex &index, int role) const
16
  {
17
  if (!index.isValid())
18
  return QVariant();
19
 
20
- if (index.row() >= this->results.size() || index.row() < 0)
21
  return QVariant();
22
 
23
  if (role == Qt::DisplayRole)
24
- return this->results[ index.row() ];
25
 
26
  return QVariant();
27
  }
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  void GoldbachModel::calculate(long long number)
30
  {
31
  this->beginResetModel();
32
 
33
- if ( this->worker )
34
- this->worker->deleteLater();
 
 
 
35
 
36
- this->worker = new GoldbachWorker{number, this->results, this};
 
37
 
38
- this->connect( this->worker, &GoldbachWorker::progressUpdated, this, &GoldbachModel::updateProgress );
39
- this->connect( this->worker, &GoldbachWorker::calculationDone, this, &GoldbachModel::workerDone );
 
 
 
 
 
 
40
 
41
- this->worker->start();
 
42
 
43
  this->endResetModel();
44
  }
45
 
46
  void GoldbachModel::stop()
47
  {
48
- Q_ASSERT(this->worker);
49
- this->worker->requestInterruption();
 
50
  }
51
 
52
  bool GoldbachModel::canFetchMore(const QModelIndex &parent) const
53
  {
54
  Q_UNUSED(parent);
55
- return this->fetchedRowCount < this->results.count();
56
  }
57
 
58
  void GoldbachModel::fetchMore(const QModelIndex &parent)
59
  {
60
  Q_UNUSED(parent);
61
 
62
- int remainder = this->results.size() - this->fetchedRowCount;
63
  int itemsToFetch = qMin(100, remainder);
64
 
65
  if (itemsToFetch <= 0)
66
  return;
67
 
68
  beginInsertRows(QModelIndex(), this->fetchedRowCount, this->fetchedRowCount + itemsToFetch - 1);
69
  this->fetchedRowCount += itemsToFetch;
70
  endInsertRows();
71
  }
72
 
73
  void GoldbachModel::workerDone(long long sumCount)
74
  {
75
  emit this->calculationDone(sumCount);
76
  }
77
 
78
  void GoldbachModel::updateProgress(int percent)
79
  {
80
  emit this->progressUpdated(percent);
81
 
82
  if ( this->fetchedRowCount <= 0 )
83
  this->fetchMore(QModelIndex());
84
  }
1
  #include "GoldbachModel.h"
2
  #include "GoldbachWorker.h"
3
 
4
  GoldbachModel::GoldbachModel(QObject *parent)
5
  : QAbstractListModel(parent)
6
  {
7
  }
8
 
9
  int GoldbachModel::rowCount(const QModelIndex &parent) const
10
  {
11
  Q_UNUSED(parent);
12
  return this->fetchedRowCount;
13
  }
14
 
15
  QVariant GoldbachModel::data(const QModelIndex &index, int role) const
16
  {
17
  if (!index.isValid())
18
  return QVariant();
19
 
20
+ if (index.row() >= this->countResults() || index.row() < 0)
21
  return QVariant();
22
 
23
  if (role == Qt::DisplayRole)
24
+ return findValue( index.row() );
25
 
26
  return QVariant();
27
  }
28
 
29
+ const QString &GoldbachModel::findValue(int index) const
30
+ {
31
+ int row = 0;
32
+ while ( index >= this->results[row].count() )
33
+ index -= this->results[row++].count();
34
+
35
+ return this->results[row][index];
36
+ }
37
+
38
+ int GoldbachModel::countResults() const
39
+ {
40
+ int resultCount = 0;
41
+ for ( auto vector : this->results )
42
+ resultCount += vector.count();
43
+
44
+ return resultCount;
45
+ }
46
+
47
  void GoldbachModel::calculate(long long number)
48
  {
49
  this->beginResetModel();
50
 
51
+ for ( GoldbachWorker* worker : this->workers )
52
+ worker->deleteLater();
53
+ this->workers.clear();
54
+
55
+ int workerCount = qMin( QThread::idealThreadCount(), static_cast<int>(number - 2));
56
 
57
+ this->results.clear();
58
+ this->results.resize( workerCount );
59
 
60
+ for ( int current = 0; current < workerCount; ++current )
61
+ {
62
+ //this->worker = new GoldbachWorker{number, this->results, this};
63
+ GoldbachWorker* worker = new GoldbachWorker{number, current, workerCount, this->results[current], this};
64
+ this->workers.append( worker );
65
+
66
+ this->connect( worker, &GoldbachWorker::progressUpdated, this, &GoldbachModel::updateProgress );
67
+ this->connect( worker, &GoldbachWorker::calculationDone, this, &GoldbachModel::workerDone );
68
 
69
+ worker->start();
70
+ }
71
 
72
  this->endResetModel();
73
  }
74
 
75
  void GoldbachModel::stop()
76
  {
77
+ Q_ASSERT(this->workers.count() > 0);
78
+ for ( GoldbachWorker* worker : this->workers )
79
+ worker->requestInterruption();
80
  }
81
 
82
  bool GoldbachModel::canFetchMore(const QModelIndex &parent) const
83
  {
84
  Q_UNUSED(parent);
85
+ return this->fetchedRowCount < this->countResults();
86
  }
87
 
88
  void GoldbachModel::fetchMore(const QModelIndex &parent)
89
  {
90
  Q_UNUSED(parent);
91
 
92
+ int remainder = this->countResults() - this->fetchedRowCount;
93
  int itemsToFetch = qMin(100, remainder);
94
 
95
  if (itemsToFetch <= 0)
96
  return;
97
 
98
  beginInsertRows(QModelIndex(), this->fetchedRowCount, this->fetchedRowCount + itemsToFetch - 1);
99
  this->fetchedRowCount += itemsToFetch;
100
  endInsertRows();
101
  }
102
 
103
  void GoldbachModel::workerDone(long long sumCount)
104
  {
105
  emit this->calculationDone(sumCount);
106
  }
107
 
108
  void GoldbachModel::updateProgress(int percent)
109
  {
110
  emit this->progressUpdated(percent);
111
 
112
  if ( this->fetchedRowCount <= 0 )
113
  this->fetchMore(QModelIndex());
114
  }