7#include "CubeDataThread.h"
14#include <QReadWriteLock>
23#include "IException.h"
25#include "UniversalGroundMap.h"
41 p_managedData =
new QList< QPair< QReadWriteLock *, Brick * > > ;
71 while (!isFinished()) {
72 QThread::yieldCurrentThread();
78 delete (*p_managedData)[i].first;
79 delete (*p_managedData)[i].second;
125 bool mustOpenReadWrite) {
129 newCube->open(fileName.
expanded(),
"rw");
132 if (!mustOpenReadWrite) {
133 newCube->open(fileName.
expanded(),
"r");
145 QPair< bool, Cube * > newEntry;
146 newEntry.first =
true;
147 newEntry.second = newCube;
173 QPair< bool, Cube * > newEntry;
174 newEntry.first =
false;
175 newEntry.second = cube;
194 QMap< int, QPair< bool, Cube * > >::iterator i;
199 QString msg =
"CubeDataThread::RemoveCube failed because cube ID [";
200 msg += QString::number(cubeId);
201 msg +=
"] not found";
207 QString msg =
"CubeDataThread::RemoveCube failed cube ID [";
208 msg += QString::number(cubeId);
209 msg +=
"] has requested Bricks";
215 delete i.value().second;
216 i.value().second = NULL;
258 int band,
void *caller,
bool sharedLock) {
260 Brick *requestedBrick = NULL;
264 - ss + 1, el - sl + 1, 1);
265 requestedBrick->SetBasePosition(ss, sl, band);
271 bool exactMatch =
false;
272 int index =
OverlapIndex(requestedBrick, cubeId, instance, exactMatch);
275 while (index != -1) {
282 (*p_managedData)[index].first->unlock();
288 (*p_managedData)[index].first->unlock();
303 index =
OverlapIndex(requestedBrick, cubeId, instance, exactMatch);
308 if (exactIndex == -1) {
313 QPair< QReadWriteLock *, Brick * > managedDataEntry;
315 managedDataEntry.first =
new QReadWriteLock();
319 managedDataEntry.second = requestedBrick;
329 if (el - sl + 1 != (*
p_managedData)[exactIndex].second->LineDimension())
352 while (i.hasNext()) {
354 if (i.value().second == cubeToFind)
358 "Cube does not exist in this CubeDataThread", _FILEINFO_);
377 while (!lockObject->tryLockForRead()) {
382 QThread::yieldCurrentThread();
385 qApp->sendPostedEvents(
this, 0);
392 while (!lockObject->tryLockForWrite()) {
397 QThread::yieldCurrentThread();
400 qApp->sendPostedEvents(
this, 0);
427 int endSample,
int endLine,
int band,
433 msg +=
"] is not a valid cube ID";
437 GetCubeData(cubeId, startSample, startLine, endSample, endLine, band,
462 int startLine,
int endSample,
int endLine,
463 int band,
void *caller) {
467 msg +=
"] is not a valid cube ID";
471 GetCubeData(cubeId, startSample, startLine, endSample, endLine, band,
489 int instanceNum,
bool &exact) {
493 int startSample = overlapping->Sample(0);
494 int endSample = overlapping->Sample(overlapping->size() - 1);
495 int startLine = overlapping->Line(0);
496 int endLine = overlapping->Line(overlapping->size() - 1);
497 int startBand = overlapping->Band(0);
498 int endBand = overlapping->Band(overlapping->size() - 1);
501 for (
int knownBrick = 0; knownBrick <
p_managedData->size(); knownBrick++) {
502 int sourceCube = (*p_managedDataSources)[knownBrick];
505 if (sourceCube != cubeId)
508 QPair< QReadWriteLock *, Brick * > &managedBrick =
509 (*p_managedData)[knownBrick];
511 Brick &brick = *managedBrick.second;
515 int compareSampStart = brick.
Sample(0);
516 int compareSampEnd = brick.Sample(brick.size() - 1);
517 int compareLineStart = brick.Line(0);
518 int compareLineEnd = brick.Line(brick.size() - 1);
519 int compareBandStart = brick.Band(0);
520 int compareBandEnd = brick.Band(brick.size() - 1);
522 bool overlap =
false;
525 if (compareSampStart >= startSample && compareSampStart <= endSample) {
530 if (compareSampEnd >= startSample && compareSampEnd <= endSample) {
535 if (compareLineStart >= startLine && compareLineStart <= endLine) {
540 if (compareLineEnd >= startLine && compareLineEnd <= endLine) {
545 if (compareBandStart >= startBand && compareBandStart <= endBand) {
550 if (compareBandEnd >= startBand && compareBandEnd <= endBand) {
555 if (compareSampStart == startSample && compareSampEnd == endSample
556 && compareLineStart == startLine && compareLineEnd == endLine
557 && compareBandStart == startBand && compareBandEnd == endBand) {
566 if (instanceNum < 0) {
587 bool exactMatch =
false;
588 bool writeLock =
false;
590 int index =
OverlapIndex(brickDone, cubeId, instance, exactMatch);
591 while (index != -1) {
595 index =
OverlapIndex(brickDone, cubeId, instance, exactMatch);
603 IString msg =
"Overlapping data had write locks";
612 IString msg =
"Overlapping data had write locks";
617 (*p_managedData)[index].first->unlock();
624 Brick cpy(*brickDone);
629 (*p_managedData)[index].first->unlock();
656 (*p_managedData)[index].first->unlock();
659 (*p_managedData)[index].first->unlock();
667 index =
OverlapIndex(brickDone, cubeId, instance, exactMatch);
682 if (!(*
p_managedData)[brickIndex].first->tryLockForWrite()) {
684 "CubeDataThread::FreeBrick called on a locked brick",
688 (*p_managedData)[brickIndex].first->unlock();
695 delete (*p_managedData)[brickIndex].first;
696 delete (*p_managedData)[brickIndex].second;
704 delete (*p_managedData)[i].first;
705 delete (*p_managedData)[i].second;
733 return numBricksInMemory;
747 "Invalid Cube ID [" +
IString(cubeId) +
"]",
764 "Invalid Cube ID [" +
IString(cubeId) +
"]",
Buffer for containing a three dimensional section of an image.
int Sample(const int index=0) const
Returns the sample position associated with a shape buffer index.
CubeDataThread()
This constructs a CubeDataThread().
int BricksInMemory()
This is a helper method for both testing/debugging and general information that provides the current ...
int p_numChangeListeners
This is the number of shaded locks to put on a brick when changes made.
void BrickChanged(int cubeId, const Isis::Brick *data)
DO NOT CONNECT TO THIS SIGNAL WITHOUT CALLING AddChangeListener().
void RemoveChangeListener()
You must call this method after disconnecting from the BrickChanged signal, otherwise bricks cannot b...
QMutex * p_threadSafeMutex
This locks the member variable p_managedCubes and p_managedData itself.
UniversalGroundMap * GetUniversalGroundMap(int cubeId) const
This returns a new Universal Ground Map given a Cube ID.
int AddCube(const FileName &fileName, bool mustOpenReadWrite=false)
This method is designed to be callable from any thread before data is requested, though no known side...
unsigned int p_currentId
This is the unique id counter for cubes.
bool p_stopping
This is set to help the shutdown process when deleted.
virtual ~CubeDataThread()
This class is a self-contained thread, so normally it would be bad to simply delete it.
int FindCubeId(const Cube *) const
Given a Cube pointer, return the cube ID associated with it.
int OverlapIndex(const Brick *initial, int cubeId, int instanceNum, bool &exact)
This is a searching method used to identify overlapping data already in memory.
void AddChangeListener()
You must call this method after connecting to the BrickChanged signal, otherwise you are not guarante...
void AcquireLock(QReadWriteLock *lockObject, bool readLock)
This method is exclusively used to acquire locks.
void ReadWriteCube(int cubeId, int startSample, int startLine, int endSample, int endLine, int band, void *caller)
This slot should be connected to and upon receiving a signal it will begin the necessary cube I/O to ...
const Cube * GetCube(int cubeId) const
This returns a constant pointer to a Cube at the given Cube ID.
void ReadCube(int cubeId, int startSample, int startLine, int endSample, int endLine, int band, void *caller)
This slot should be connected to and upon receiving a signal it will begin the necessary cube I/O to ...
void RemoveCube(int cubeId)
Removes a cube from this lock manager.
QMap< int, QPair< bool, Cube * > > * p_managedCubes
This is a list of the opened cubes.
unsigned int p_currentLocksWaiting
Number of locks being attempted that re-entered the event loop.
void ReadReady(void *requester, int cubeId, const Isis::Brick *data)
This signal will be emitted when ReadCube has finished processing.
QList< QPair< QReadWriteLock *, Brick * > > * p_managedData
This is a list of bricks in memory and their locks.
void DoneWithData(int, const Isis::Brick *)
When done processing with a brick (reading or writing) this slot needs to be signalled to free locks ...
QList< int > * p_managedDataSources
This is the associated cube ID with each brick.
bool FreeBrick(int brickIndex)
This is used internally to delete bricks when possible.
void GetCubeData(int cubeId, int ss, int sl, int es, int el, int band, void *caller, bool sharedLock)
This helper method reads in cube data and handles the locking of similar bricks appropriately.
void ReadWriteReady(void *requester, int cubeId, Isis::Brick *data)
This signal will be emitted when ReadWriteCube has finished processing.
IO Handler for Isis Cubes.
File name manipulation and expansion.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
@ Programmer
This error is for when a programmer made an API call that was illegal.
Adds specific functionality to C++ strings.
This is free and unencumbered software released into the public domain.