Isis 3 Programmer Reference
|
Encapsulation of Cube I/O with Change Notifications. More...
#include <CubeDataThread.h>
Public Slots | |
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 get this data. More... | |
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 get this data. More... | |
void | DoneWithData (int, const Isis::Brick *) |
When done processing with a brick (reading or writing) this slot needs to be signalled to free locks and memory. More... | |
Signals | |
void | ReadReady (void *requester, int cubeId, const Isis::Brick *data) |
This signal will be emitted when ReadCube has finished processing. More... | |
void | ReadWriteReady (void *requester, int cubeId, Isis::Brick *data) |
This signal will be emitted when ReadWriteCube has finished processing. More... | |
void | BrickChanged (int cubeId, const Isis::Brick *data) |
DO NOT CONNECT TO THIS SIGNAL WITHOUT CALLING AddChangeListener(). More... | |
Public Member Functions | |
CubeDataThread () | |
This constructs a CubeDataThread(). More... | |
virtual | ~CubeDataThread () |
This class is a self-contained thread, so normally it would be bad to simply delete it. More... | |
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 effects exist if this is called during other I/O operations (though I don't recommend it). More... | |
int | AddCube (Cube *cube) |
This method is designed to be callable from any thread before data is requested, though no known side effects exist if this is called during other I/O operations (though I don't recommend it). More... | |
void | RemoveCube (int cubeId) |
Removes a cube from this lock manager. More... | |
void | AddChangeListener () |
You must call this method after connecting to the BrickChanged signal, otherwise you are not guaranteed a good Brick pointer. More... | |
void | RemoveChangeListener () |
You must call this method after disconnecting from the BrickChanged signal, otherwise bricks cannot be freed from memory. More... | |
int | BricksInMemory () |
This is a helper method for both testing/debugging and general information that provides the current number of bricks in memory. More... | |
UniversalGroundMap * | GetUniversalGroundMap (int cubeId) const |
This returns a new Universal Ground Map given a Cube ID. More... | |
const Cube * | GetCube (int cubeId) const |
This returns a constant pointer to a Cube at the given Cube ID. More... | |
int | FindCubeId (const Cube *) const |
Given a Cube pointer, return the cube ID associated with it. More... | |
Private Member Functions | |
CubeDataThread (const CubeDataThread &cdt) | |
Assigning CubeDataThreads to eachother is bad, so this has been intentionally not implemented! More... | |
const CubeDataThread & | operator= (CubeDataThread rhs) |
Assigning CubeDataThreads to eachother is bad, so this has been intentionally not implemented! More... | |
int | OverlapIndex (const Brick *initial, int cubeId, int instanceNum, bool &exact) |
This is a searching method used to identify overlapping data already in memory. More... | |
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. More... | |
void | AcquireLock (QReadWriteLock *lockObject, bool readLock) |
This method is exclusively used to acquire locks. More... | |
bool | FreeBrick (int brickIndex) |
This is used internally to delete bricks when possible. More... | |
Private Attributes | |
QMap< int, QPair< bool, Cube *> > * | p_managedCubes |
This is a list of the opened cubes. More... | |
QMutex * | p_threadSafeMutex |
This locks the member variable p_managedCubes and p_managedData itself. More... | |
QList< QPair< QReadWriteLock *, Brick * > > * | p_managedData |
This is a list of bricks in memory and their locks. More... | |
QList< int > * | p_managedDataSources |
This is the associated cube ID with each brick. More... | |
int | p_numChangeListeners |
This is the number of shaded locks to put on a brick when changes made. More... | |
unsigned int | p_currentId |
This is the unique id counter for cubes. More... | |
bool | p_stopping |
This is set to help the shutdown process when deleted. More... | |
unsigned int | p_currentLocksWaiting |
Number of locks being attempted that re-entered the event loop. More... | |
Encapsulation of Cube I/O with Change Notifications.
The main purpose of this class is to create cube change notifications, ideal for GUI's with changing cubes. This class is designed to encapsulate Cube I/O into a separate thread and serializes each cube I/O. This class also speeds up I/O by reusing bricks instead of always reading from the disk.
This is not a full concurrency control/transaction handler. Consistent states are not guaranteed, though a consistent state for any given brick is, and results from reads do not guaranteed serial equivalence. Deadlocks are possible, if two processes want to R/W to the same sections of data, and it is up to the users of this class to avoid such conditions.
2010-04-12 Eric Hyer - Added check for valid cube ID's for slots ReadCube and ReadWriteCube.
2010-07-29 Eric Hyer - AcquireLock now flushes events for this thread instead of the main eventloop's thread.
2010-08-12 Steven Lambright - Fixed memory leak and simplified acquiring write bricks
2010-08-23 Eric Hyer - Added the FindCubeId method
2010-08-24 Eric Hyer - Added the RemoveCube method
2012-02-27 Jai Rideout and Steven Lambright - Made BricksInMemory() thread-safe. Fixes #733.
2016-06-21 Kris Becker - Properly forward declare QPair as struct not class
Definition at line 53 of file CubeDataThread.h.
Isis::CubeDataThread::CubeDataThread | ( | ) |
This constructs a CubeDataThread().
This will spawn a new thread and move the ownership of this instance to itself (so slots are called in this self-contained thread).
Definition at line 29 of file CubeDataThread.cpp.
References p_currentId, p_currentLocksWaiting, p_managedCubes, p_managedData, p_managedDataSources, p_numChangeListeners, p_stopping, and p_threadSafeMutex.
|
virtual |
This class is a self-contained thread, so normally it would be bad to simply delete it.
However, this destructor will synchronize the shutdown of the thread so you can safely delete an instance of this class without using the deleteLater() method.
Definition at line 60 of file CubeDataThread.cpp.
References p_managedCubes, p_managedData, p_managedDataSources, p_stopping, and p_threadSafeMutex.
|
private |
Assigning CubeDataThreads to eachother is bad, so this has been intentionally not implemented!
cdt | The CubeDataThread that would be used to copy construct this CubeDataThread if this method were implemented (which its not) |
|
private |
This method is exclusively used to acquire locks.
This handles the problem of being unable to receive signals that would free locks while waiting for a lock to be made.
lockObject | Lock object we're trying to acquire a lock on |
readLock | True if we're trying for read lock, false for read/write |
Definition at line 365 of file CubeDataThread.cpp.
References p_currentLocksWaiting, and p_stopping.
Referenced by DoneWithData(), and GetCubeData().
void Isis::CubeDataThread::AddChangeListener | ( | ) |
You must call this method after connecting to the BrickChanged signal, otherwise you are not guaranteed a good Brick pointer.
Definition at line 224 of file CubeDataThread.cpp.
References p_numChangeListeners.
Referenced by Isis::CubeViewport::CubeViewport(), and Isis::CubeDataThreadTester::NotifyChangeTest().
int Isis::CubeDataThread::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 effects exist if this is called during other I/O operations (though I don't recommend it).
If possible, the cube will be opened with R/W permissions, otherwise it will be opened with read-only access
fileName | The cube to open |
mustOpenReadWrite | If true and cube has read-only access then an exception will be thrown |
Definition at line 119 of file CubeDataThread.cpp.
References Isis::FileName::expanded(), Isis::Cube::open(), p_currentId, p_managedCubes, and p_threadSafeMutex.
Referenced by Isis::CubeViewport::CubeViewport().
int Isis::CubeDataThread::AddCube | ( | Cube * | cube | ) |
This method is designed to be callable from any thread before data is requested, though no known side effects exist if this is called during other I/O operations (though I don't recommend it).
Ownership is not taken of this cube
cube | The cube to encapsulate |
Definition at line 162 of file CubeDataThread.cpp.
References p_currentId, p_managedCubes, and p_threadSafeMutex.
|
signal |
DO NOT CONNECT TO THIS SIGNAL WITHOUT CALLING AddChangeListener().
When a write occurs, and change listeners exist, this signal is emitted with the new data.
When done with the data, given you are the requester, you call the DoneWithData slot (via a signal).
Referenced by DoneWithData().
int Isis::CubeDataThread::BricksInMemory | ( | ) |
This is a helper method for both testing/debugging and general information that provides the current number of bricks in memory.
Definition at line 728 of file CubeDataThread.cpp.
References p_managedData, and p_threadSafeMutex.
|
slot |
When done processing with a brick (reading or writing) this slot needs to be signalled to free locks and memory.
cubeId | Cube associated with the brick |
brickDone | Brick pointer given by ReadReady, ReadWriteReady or BrickChanged. An equivalent brick is also acceptable (exact same range, but not same pointer). |
Definition at line 581 of file CubeDataThread.cpp.
References _FILEINFO_, AcquireLock(), BrickChanged(), FreeBrick(), OverlapIndex(), p_managedCubes, p_managedData, p_managedDataSources, p_numChangeListeners, p_threadSafeMutex, and Isis::IException::Programmer.
int Isis::CubeDataThread::FindCubeId | ( | const Cube * | cubeToFind | ) | const |
Given a Cube pointer, return the cube ID associated with it.
Definition at line 345 of file CubeDataThread.cpp.
References _FILEINFO_, p_managedCubes, and Isis::IException::Programmer.
Referenced by Isis::CubeViewport::CubeViewport().
|
private |
This is used internally to delete bricks when possible.
brickIndex | Brick to request deletion |
Definition at line 678 of file CubeDataThread.cpp.
References _FILEINFO_, p_currentLocksWaiting, p_managedData, p_managedDataSources, p_threadSafeMutex, and Isis::IException::Programmer.
Referenced by DoneWithData(), and GetCubeData().
const Cube * Isis::CubeDataThread::GetCube | ( | int | cubeId | ) | const |
This returns a constant pointer to a Cube at the given Cube ID.
Definition at line 761 of file CubeDataThread.cpp.
References _FILEINFO_, p_managedCubes, and Isis::IException::Programmer.
|
private |
This helper method reads in cube data and handles the locking of similar bricks appropriately.
cubeId | Cube ID To Read From |
ss | Starting Sample Position |
sl | Starting Line Position |
es | Ending Sample Position |
el | Ending Line Position |
band | Band Number To Read From (multi-band bricks not supported at this time) |
caller | A pointer to the calling class, used to identify who requested the data when they receive either the ReadReady or the ReadWriteReady signal |
sharedLock | True if read-only, false if read-write |
Definition at line 252 of file CubeDataThread.cpp.
References AcquireLock(), FreeBrick(), OverlapIndex(), p_managedCubes, p_managedData, p_managedDataSources, p_stopping, p_threadSafeMutex, ReadReady(), ReadWriteReady(), and Isis::Brick::SetBasePosition().
Referenced by ReadCube(), and ReadWriteCube().
UniversalGroundMap * Isis::CubeDataThread::GetUniversalGroundMap | ( | int | cubeId | ) | const |
This returns a new Universal Ground Map given a Cube ID.
Ownership is given to the caller.
Definition at line 744 of file CubeDataThread.cpp.
References _FILEINFO_, p_managedCubes, and Isis::IException::Programmer.
|
private |
Assigning CubeDataThreads to eachother is bad, so this has been intentionally not implemented!
rhs | The right hand side CubeDataThread in the assignment operation. |
|
private |
This is a searching method used to identify overlapping data already in memory.
overlapping | Brick to check for overlaps with |
cubeId | Cube ID asssociated with this brick |
instanceNum | Which instance of overlap to return |
exact | This is set to false if the match found is not exactly the overlapping brick. |
Definition at line 483 of file CubeDataThread.cpp.
References Isis::Buffer::Band(), Isis::Buffer::Line(), p_managedData, p_managedDataSources, Isis::Buffer::Sample(), and Isis::Buffer::size().
Referenced by DoneWithData(), and GetCubeData().
|
slot |
This slot should be connected to and upon receiving a signal it will begin the necessary cube I/O to get this data.
When the data is available, a ReadReady signal will be emitted with the parameter caller being equal to the requester pointer in the signal. You should pass "this" for caller, and you must ignore all ReadReady signals which do not have "requester == this" -> otherwise your pointer is not guaranteed.
cubeId | Cube to read from |
startSample | Starting Sample Position |
startLine | Starting Line Position |
endSample | Ending Sample Position |
endLine | Ending Line Position |
band | Band Number To Read From (multi-band bricks not supported at this time) |
caller | A pointer to the calling class, used to identify who requested the data when they receive the ReadReady signal |
Definition at line 421 of file CubeDataThread.cpp.
References _FILEINFO_, GetCubeData(), p_managedCubes, and Isis::IException::Programmer.
|
signal |
This signal will be emitted when ReadCube has finished processing.
When done with the data, given you are the requester, you call the DoneWithData slot (via a signal).
requester | Pointer to the calling class (must ignore all ReadReady signals where this != requester) |
cubeId | Cube ID of the cube the data is from |
data | The data in the cube |
Referenced by GetCubeData().
|
slot |
This slot should be connected to and upon receiving a signal it will begin the necessary cube I/O to get this data.
When the data is available, a ReadWriteReady signal will be emitted with the parameter caller being equal to the requester pointer in the signal. You should pass "this" for caller, and you must ignore all ReadReady signals which do not have "requester == this" -> otherwise your pointer is not guaranteed and you are corrupting the process of the real requester.
cubeId | Cube to read from |
startSample | Starting Sample Position |
startLine | Starting Line Position |
endSample | Ending Sample Position |
endLine | Ending Line Position |
band | Band Number To Read From (multi-band bricks not supported at this time) |
caller | A pointer to the calling class, used to identify who requested the data when they receive the ReadWriteReady signal |
Definition at line 456 of file CubeDataThread.cpp.
References _FILEINFO_, GetCubeData(), p_managedCubes, and Isis::IException::Programmer.
|
signal |
This signal will be emitted when ReadWriteCube has finished processing.
When done with the data, given you are the requester, you call the DoneWithData slot (via a signal).
requester | Pointer to the calling class (must ignore all ReadReady signals where this != requester) |
cubeId | Cube ID of the cube the data is from |
data | The data in the cube, also where you should write changes |
Referenced by GetCubeData().
void Isis::CubeDataThread::RemoveChangeListener | ( | ) |
You must call this method after disconnecting from the BrickChanged signal, otherwise bricks cannot be freed from memory.
Definition at line 232 of file CubeDataThread.cpp.
References p_numChangeListeners.
Referenced by Isis::CubeViewport::~CubeViewport().
void Isis::CubeDataThread::RemoveCube | ( | int | cubeId | ) |
Removes a cube from this lock manager.
cubeId | The cube to be deleted's ID |
Definition at line 186 of file CubeDataThread.cpp.
References _FILEINFO_, p_managedCubes, p_managedDataSources, p_threadSafeMutex, and Isis::IException::Programmer.
|
private |
This is the unique id counter for cubes.
Definition at line 202 of file CubeDataThread.h.
Referenced by AddCube(), and CubeDataThread().
|
private |
Number of locks being attempted that re-entered the event loop.
As long as this isn't zero, no bricks should be removed from p_managedData.
Definition at line 211 of file CubeDataThread.h.
Referenced by AcquireLock(), CubeDataThread(), and FreeBrick().
This is a list of the opened cubes.
Since opening cubes is allowed in other threads (via AddCube(...)) and is accessed with many threads, all operations on this map must be serialized (non-simultaneous). The p_managedCubesMutex enables this. The bool indicates ownership.
Definition at line 165 of file CubeDataThread.h.
Referenced by AddCube(), CubeDataThread(), DoneWithData(), FindCubeId(), GetCube(), GetCubeData(), GetUniversalGroundMap(), ReadCube(), ReadWriteCube(), RemoveCube(), and ~CubeDataThread().
This is a list of bricks in memory and their locks.
The following assumptions are vital or at least important for understanding this data structure: 1) No two bricks have the exact same area. 2) Deletions may only happen in the destructor or in FreeBrick(int) 3) A brick with no locks on it is available for deletion later, but may not be deleted if p_currentLocksWaiting != 0 (something is attempting a lock somewhere else). 4) Bricks may overlap, but locks only pertain to exact matches. 5) If you want to make an exclusive (R/W) lock on a brick, you must first make all overlapping bricks available for deletion (and/or delete) 6) If you wish to make a shared (R) lock on a brick, no overlapping bricks can be write locked. 7) All operations happen in this thread in order to prevent checks happening for access executing simultaneously, at least more than AcquireLock() allows. 8) New bricks must be appended to the end of this list. 8) Searches for conflicts must start at the beginning of this list and proceed to the end. 10) No NULL or invalid pointers may exist in this list.
Definition at line 193 of file CubeDataThread.h.
Referenced by BricksInMemory(), CubeDataThread(), DoneWithData(), FreeBrick(), GetCubeData(), OverlapIndex(), and ~CubeDataThread().
|
private |
This is the associated cube ID with each brick.
Definition at line 196 of file CubeDataThread.h.
Referenced by CubeDataThread(), DoneWithData(), FreeBrick(), GetCubeData(), OverlapIndex(), RemoveCube(), and ~CubeDataThread().
|
private |
This is the number of shaded locks to put on a brick when changes made.
Definition at line 199 of file CubeDataThread.h.
Referenced by AddChangeListener(), CubeDataThread(), DoneWithData(), and RemoveChangeListener().
|
private |
This is set to help the shutdown process when deleted.
Definition at line 205 of file CubeDataThread.h.
Referenced by AcquireLock(), CubeDataThread(), GetCubeData(), and ~CubeDataThread().
|
private |
This locks the member variable p_managedCubes and p_managedData itself.
Definition at line 168 of file CubeDataThread.h.
Referenced by AddCube(), BricksInMemory(), CubeDataThread(), DoneWithData(), FreeBrick(), GetCubeData(), RemoveCube(), and ~CubeDataThread().