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.