cctw  0.2.1
cctwdatachunk.cpp
Go to the documentation of this file.
1 #include "cctwdatachunk.h"
2 #include <stdio.h>
3 #include <QSemaphore>
4 #include "cctwthread.h"
5 
6 static QAtomicInt g_ChunkCount;
7 
8 CctwDataChunk::CctwDataChunk(CctwChunkedData *data, int index, QString name, QObject *parent) :
9  CctwObject(name, parent),
10  m_Data(data),
11  m_ChunkIndex(index),
12  m_ChunkStart(calculateChunkStart()),
13  m_ChunkSize(calculateChunkSize()),
14  m_ChunkData(NULL),
15  m_ChunkWeights(NULL),
16  m_Normalized(0),
17  m_DataWritten(0),
18  m_WeightsWritten(0),
19  m_MergeCounter(0),
20  m_OwnData(true)
21 {
22  g_ChunkCount.fetchAndAddOrdered(1);
23 }
24 
26 {
27 // printMessage(tr("calculateChunkStart(): %1").arg(m_ChunkIndex));
28  if (m_Data) {
29  return m_Data -> chunkStart(m_ChunkIndex);
30  } else {
31  printMessage(tr("Chunk %1, m_Data == NULL").arg(m_ChunkIndex));
32  return CctwIntVector3D(0,0,0);
33  }
34 }
35 
37 {
38  if (m_Data) {
39  CctwIntVector3D chksize = m_Data->chunkSize();
40  CctwIntVector3D chkend = m_ChunkStart + chksize;
42 
43  if (chkend.x() > dim.x()) {
44  chksize.x() = dim.x() - m_ChunkStart.x();
45  }
46 
47  if (chkend.y() > dim.y()) {
48  chksize.y() = dim.y() - m_ChunkStart.y();
49  }
50 
51  if (chkend.z() > dim.z()) {
52  chksize.z() = dim.z() - m_ChunkStart.z();
53  }
54 
55  return chksize;
56  } else {
57  printMessage(tr("Chunk %1, m_Data == NULL").arg(m_ChunkIndex));
58  return CctwIntVector3D(0,0,0);
59  }
60 }
61 
63 {
64  if (dependencyCount()) {
65  printMessage("Deleting chunk with deps");
66  }
67 
68  if (m_OwnData) {
71  }
72 
73  m_ChunkData = NULL;
74  m_ChunkWeights = NULL;
75 
76  g_ChunkCount.fetchAndAddOrdered(-1);
77 }
78 
80 {
81  return g_ChunkCount.fetchAndAddOrdered(0);
82 }
83 
84 static QAtomicInt g_MaxAllocated(0);
85 static QAtomicInt g_Allocated(0);
86 static QAtomicInt g_AllocationLimit(1000);
87 static QSemaphore g_Available(1000);
88 
90 {
91  return m_ChunkData;
92 }
93 
95 {
96  return m_ChunkWeights;
97 }
98 
100 {
101  return m_ChunkData;
102 }
103 
105 {
106  return m_ChunkWeights;
107 }
108 
110 {
111  return m_ChunkStart;
112 }
113 
115 {
117  qDebug("CctwDataChunk::resetChunkStart(): %s", qPrintable(m_ChunkStart.toString()));
118 }
119 
121 {
122  return m_ChunkSize;
123 }
124 
126 {
127  m_ChunkSize = size;
128 }
129 
131 {
132  int cksz = m_ChunkSize.volume();
133 
135 
137 
138  m_ChunkData = newData;
139 
140  return cksz*sizeof(CctwChunkedData::MergeDataType);
141 }
142 
144 {
145  int cksz = m_ChunkSize.volume();
146 
148 
150 
151  m_ChunkWeights = newWeights;
152 
153  return cksz*sizeof(CctwChunkedData::MergeDataType);
154 }
155 
157 {
159 
161 
162  m_ChunkData = NULL;
163 
164  return res;
165 }
166 
168 {
170 
172 
173  m_ChunkWeights = NULL;
174 
175  return res;
176 }
177 
179 {
180  m_ChunkData = NULL;
181 
182  return 0;
183 }
184 
186 {
187  m_ChunkWeights = NULL;
188 
189  return 0;
190 }
191 
192 int CctwDataChunk::pixelOffset(int lx, int ly, int lz)
193 {
194  if (lx < 0 || lx >= m_ChunkSize.x()) {
195  return -1;
196  } else if (ly < 0 || ly >= m_ChunkSize.y()) {
197  return -1;
198  } else if (lz < 0 || lz >= m_ChunkSize.z()) {
199  return -1;
200  } else {
201  int offset = (lz * m_ChunkSize.y() + ly)*m_ChunkSize.x() + lx;
202  return offset;
203  }
204 }
205 
207 {
208  int offset = pixelOffset(lx, ly, lz);
209 
210  if (offset >= 0 && m_ChunkData) {
211  return m_ChunkData[offset];
212  } else {
213  return 0;
214  }
215 }
216 
218 {
219  int offset = pixelOffset(lx, ly, lz);
220 
221  if (offset >= 0 && m_ChunkWeights) {
222  return m_ChunkWeights[offset];
223  } else {
224  return 1;
225  }
226 }
227 
229 {
230  int offset = pixelOffset(lx, ly, lz);
231 
232  if (offset >= 0 && m_ChunkData) {
233  m_ChunkData[offset] = val;
234  }
235 }
236 
238 {
239  int offset = pixelOffset(lx, ly, lz);
240 
241  if (offset >= 0 && m_ChunkWeights) {
242  m_ChunkWeights[offset] = val;
243  }
244 }
245 
247 {
248  g_Allocated.fetchAndStoreOrdered(0);
249  g_MaxAllocated.fetchAndStoreOrdered(0);
250  g_AllocationLimit.fetchAndStoreOrdered(nmax);
251  g_Available.acquire(g_Available.available());
252  g_Available.release(nmax);
253 }
254 
256 {
257  return g_MaxAllocated.fetchAndAddOrdered(0);
258 }
259 
261 {
262  int cksz = m_ChunkSize.volume();
263 
264  int nalloc = g_Allocated.fetchAndAddOrdered(1);
265 
266  if (nalloc > g_MaxAllocated.fetchAndAddOrdered(0)) {
267  g_MaxAllocated.fetchAndStoreOrdered(nalloc);
268  }
269 
270 // printMessage(tr("Acquired 1 blocks, %1 allocated, %2 max")
271 // .arg(nalloc).arg(g_MaxAllocated.fetchAndAddOrdered(0)));
272 
273 // CctwChunkedData::MergeDataType *res = new CctwChunkedData::MergeDataType[cksz];
274 
275 // for (int i=0; i<cksz; i++) {
276 // res[i] = 0;
277 // }
278 
280 
281  return res;
282 }
283 
284 void CctwDataChunk::setBuffer(void *buffer)
285 {
286  printMessage(tr("Setting buffer to: %1").arg((long long) buffer));
288  m_OwnData = false;
289 }
290 
292 {
293  if (buffer) {
294  int nalloc = g_Allocated.fetchAndAddOrdered(-1);
295 
296 // printMessage(tr("Releasing 1 blocks, %1 allocated").arg(nalloc));
297 
298 // delete [] buffer;
299 
300  free(buffer);
301  }
302 }
303 
305 {
306  return m_ChunkIndex;
307 }
308 
310 {
311  QMutexLocker lock(&m_DependenciesLock);
312 
313  m_Dependencies.resize(0);
314 }
315 
317 {
318  QMutexLocker lock(&m_DependenciesLock);
319 
320  qSort(m_Dependencies.begin(), m_Dependencies.end());
321 }
322 
324 {
325  QMutexLocker lock(&m_DependenciesLock);
326 
327  return m_Dependencies.count();
328 }
329 
331 {
332  QMutexLocker lock(&m_DependenciesLock);
333 
334  return m_Dependencies.value(n);
335 }
336 
338 {
339  QMutexLocker lock(&m_DependenciesLock);
340 
341  if (!m_Dependencies.contains(dep)) {
342 // printMessage(tr("Added dependency from chunk [%1,%2,%3] to chunk [%4,%5,%6]")
343 // .arg(m_ChunkIndex.x()).arg(m_ChunkIndex.y()).arg(m_ChunkIndex.z())
344 // .arg(dep.x()).arg(dep.y()).arg(dep.z()));
345 
346  m_Dependencies.append(dep);
347  }
348 }
349 
351 {
352  QMutexLocker lock(&m_DependenciesLock);
353 
354  QString msg(tr("[%1] ->").arg(m_ChunkIndex));
355 
357 
358  foreach (int dep, m_Dependencies) {
359  msg += tr(" [%1]").arg(dep);
360  }
361 
362  printMessage(msg);
363 }
364 
367  int n)
368 {
369  QMutexLocker lock(&m_MergeLock);
370 
371  if (m_ChunkData == NULL) {
372  allocateData();
373  }
374 
375  if (m_ChunkWeights == NULL) {
376  allocateWeights();
377  }
378 
380 
381  if (d && id) {
382  for (int i=0; i<n; i++) {
383  if ((iw && iw[i] != 0 && iw[i] == iw[i]) || !iw) {
384  d[i] += id[i];
385  }
386  }
387  } else {
388  printMessage(tr("Couldn't merge data for chunk [%1]").arg(index()));
389  }
390 
391  if (w && iw) {
392  for (int i=0; i<n; i++) {
393  if ((iw && iw[i] != 0 && iw[i] == iw[i]) || !iw) {
394  w[i] += iw[i];
395  }
396  }
397  }
398 }
399 
401 {
402 // printMessage(tr("Merging chunk [%1]")
403 // .arg(index()));
404 
405  if (c) {
406  if (mergeCount() == 0) {
407 // printMessage(tr("Output chunk [%1] started")
408 // .arg(index()));
409  }
410 
411  if (c->index() != index()) {
412  printMessage(tr("Merging anomaly [%1] != [%2]")
413  .arg(index()).arg(c->index()));
414  }
415 
416  CctwChunkedData::MergeDataType *d, *w, *id, *iw;
417  c -> popMergeData(&id, &iw);
418 
419  while (popMergeData(&d, &w)) {
420 // printMessage(tr("Pop Merge"));
421 
422  CctwIntVector3D cks = chunkSize();
423  CctwIntVector3D icks = c->chunkSize();
424 
425  if (cks == icks) {
426  int n = cks.volume();
427 
428  if (d && id) {
429  for (int i=0; i<n; i++) {
430  if ((w && w[i] != 0) || !w) {
431  id[i] += d[i];
432  }
433  }
434  } else if (d) {
435  id = d;
436  d = NULL;
437  }
438 
439  if (w && iw) {
440  for (int i=0; i<n; i++) {
441  iw[i] += w[i];
442  }
443  } else if (w) {
444  iw = w;
445  w = NULL;
446  }
447  } else {
448  printMessage(tr("Anomaly merging data chunk %1").arg(m_ChunkIndex));
449  }
450 
451  releaseBuffer(d);
452  releaseBuffer(w);
453  }
454 
455  pushMergeData(id, iw);
456 
458 
459  if (mergeCount() == dependencyCount()) {
460 // printMessage(tr("Output chunk [%1] completed")
461 // .arg(index()));
462 
463  if (m_Data) {
464  m_Data->writeChunk(index());
466  m_Data->incChunksHeld(-1);
467  }
468  } else if (mergeCount() == 1) {
469  if (m_Data) {
470  m_Data->incChunksHeld(1);
471  }
472  } else if (mergeCount() > dependencyCount() && dependencyCount()) {
473  printMessage(tr("Exceeded expected number of merges for chunk [%1] %2 > %3")
474  .arg(index()).arg(mergeCount()).arg(dependencyCount()));
475  }
476  }
477 }
478 
480 {
481  m_MergeCounter = 0;
482  m_Normalized = 0;
483 }
484 
486 {
487  m_MergeCounter++;
488 }
489 
491 {
492  return m_MergeCounter;
493 }
494 
497 {
498  QMutexLocker lock(&m_MergeLock);
499 
500  if (data && weights) {
501  *data = m_ChunkData;
502 
503  if (m_MergeData.isEmpty()) {
504  m_ChunkData = NULL;
505  } else {
506  m_ChunkData = m_MergeData.takeLast();
507  }
508 
509  *weights = m_ChunkWeights;
510 
511  if (m_MergeWeights.isEmpty()) {
512  m_ChunkWeights = NULL;
513  } else {
514  m_ChunkWeights = m_MergeWeights.takeLast();
515  }
516 
517  return *data || *weights;
518  } else {
519  return false;
520  }
521 }
522 
525 {
526  QMutexLocker lock(&m_MergeLock);
527 
528  if (m_ChunkData == NULL) {
529  m_ChunkData = data;
530  } else {
531  m_MergeData.push_back(data);
532  }
533 
534  if (m_ChunkWeights == NULL) {
535  m_ChunkWeights = weights;
536  } else {
537  m_MergeWeights.push_back(weights);
538  }
539 }
540 
542 {
543  if (m_Normalized) {
544  printMessage(tr("Chunk %1 - Already normalized").arg(index()));
545  } else if (m_ChunkData && m_ChunkWeights) {
546  int cksz = m_ChunkSize.volume();
547 
548  for (int i=0; i<cksz; i++) {
549  if (m_ChunkWeights[i] != 0.0) {
550  m_ChunkData[i] /= m_ChunkWeights[i];
551  }
552  }
553 
555  }
556 
557  m_Normalized = true;
558 }
void incChunksHeld(int n)
void mergeData(CctwChunkedData::MergeDataType *id, CctwChunkedData::MergeDataType *iw, int n)
int dependencyCount() const
void setChunkSize(CctwIntVector3D size)
static QAtomicInt g_Allocated(0)
CctwChunkedData::MergeDataType * m_ChunkData
Definition: cctwdatachunk.h:89
int index() const
bool dataAllocated() const
CctwIntVector3D m_ChunkStart
Definition: cctwdatachunk.h:87
void releaseBuffer(CctwChunkedData::MergeDataType *)
void addDependency(int dep)
QMutex m_MergeLock
Definition: cctwdatachunk.h:96
QList< CctwChunkedData::MergeDataType * > m_MergeWeights
Definition: cctwdatachunk.h:99
void writeChunk(int n)
CctwIntVector3D chunkSize()
void clearDependencies()
void clearMergeCounters()
CctwChunkedData::MergeDataType * allocateBuffer()
QString toString()
void incMergeCounters()
CctwChunkedData::MergeDataType * m_ChunkWeights
Definition: cctwdatachunk.h:90
CctwIntVector3D dimensions
CctwChunkedData * m_Data
Definition: cctwdatachunk.h:85
virtual void printMessage(QString msg, QDateTime dt=QDateTime::currentDateTime())
Definition: cctwobject.cpp:25
QMutex m_DependenciesLock
Definition: cctwdatachunk.h:95
static QSemaphore g_Available(1000)
static QAtomicInt g_AllocationLimit(1000)
CctwChunkedData::MergeDataType weight(int lx, int ly, int lz)
CctwIntVector3D calculateChunkStart()
T x() const
Definition: cctwvector3d.h:17
static int allocatedChunkCount()
static QAtomicInt g_ChunkCount
int dependency(int n) const
void mergeChunk(CctwDataChunk *c)
void setData(int lx, int ly, int lz, CctwChunkedData::MergeDataType val)
CctwChunkedData::MergeDataType * weightsPointer()
static int maxAllocated()
CctwIntVector3D calculateChunkSize()
bool popMergeData(CctwChunkedData::MergeDataType **data, CctwChunkedData::MergeDataType **weights)
bool weightsAllocated() const
int pixelOffset(int lx, int ly, int lz)
void sortDependencies()
void pushMergeData(CctwChunkedData::MergeDataType *data, CctwChunkedData::MergeDataType *weights)
CctwIntVector3D chunkStart()
CctwDataChunk(CctwChunkedData *data, int index, QString name, QObject *parent)
T z() const
Definition: cctwvector3d.h:19
CctwVector3D< int > CctwIntVector3D
Definition: cctwvector3d.h:70
CctwIntVector3D chunkSize
void setBuffer(void *buffer)
CctwChunkedData::MergeDataType * dataPointer()
QList< CctwChunkedData::MergeDataType * > m_MergeData
Definition: cctwdatachunk.h:98
void incChunksWritten(int n)
static QAtomicInt g_MaxAllocated(0)
void setWeight(int lx, int ly, int lz, CctwChunkedData::MergeDataType val)
static void resetAllocationLimits(int nmax)
virtual ~CctwDataChunk()
T volume() const
CctwChunkedData::MergeDataType data(int lx, int ly, int lz)
T y() const
Definition: cctwvector3d.h:18
void resetChunkStart()
QVector< int > m_Dependencies
Definition: cctwdatachunk.h:94
void reportDependencies()
CctwIntVector3D m_ChunkSize
Definition: cctwdatachunk.h:88