LSSTApplications  8.0.0.0+107,8.0.0.1+13,9.1+18,9.2,master-g084aeec0a4,master-g0aced2eed8+6,master-g15627eb03c,master-g28afc54ef9,master-g3391ba5ea0,master-g3d0fb8ae5f,master-g4432ae2e89+36,master-g5c3c32f3ec+17,master-g60f1e072bb+1,master-g6a3ac32d1b,master-g76a88a4307+1,master-g7bce1f4e06+57,master-g8ff4092549+31,master-g98e65bf68e,master-ga6b77976b1+53,master-gae20e2b580+3,master-gb584cd3397+53,master-gc5448b162b+1,master-gc54cf9771d,master-gc69578ece6+1,master-gcbf758c456+22,master-gcec1da163f+63,master-gcf15f11bcc,master-gd167108223,master-gf44c96c709
LSSTDataManagementBasePackage
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT > Class Template Reference

A manager for a set of chunks of a single type. More...

#include <ChunkManagerImpl.h>

Inheritance diagram for lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >:

Public Types

typedef SubManager< MutexT,
DataT, TraitsT > 
Manager
 
typedef Manager::Chunk Chunk
 

Public Member Functions

 ChunkManagerImpl ()
 
bool isVisitInFlight (int const visitId)
 
void failVisit (int const visitId)
 
void registerVisit (int const visitId)
 
void startVisit (std::vector< Chunk > &toRead, std::vector< Chunk > &toWaitFor, int const visitId, std::vector< int > const &chunkIds)
 
void waitForOwnership (std::vector< Chunk > &toRead, std::vector< Chunk > &toWaitFor, int const visitId, TimeSpec const &deadline)
 
void getChunks (std::vector< Chunk > &chunks, std::vector< int > const &chunkIds)
 
bool endVisit (int const visitId, bool const rollback)
 
void printVisits (std::ostream &os) const
 
void printChunks (std::ostream &os) const
 
void printVisit (int const visitId, std::ostream &os) const
 
void printChunk (int const chunkId, std::ostream &os) const
 

Static Public Member Functions

static std::size_t size ()
 

Private Member Functions

void rollbackAllExcept (int const visitId)
 

Static Private Member Functions

static std::size_t blocks ()
 Returns the offset of the first data block (relative to its manager). More...
 

Private Attributes

MutexT _mutex
 
Condition< MutexT > _ownerCondition
 
VisitTracker _visits
 
Manager _data
 

Detailed Description

template<typename MutexT, typename DataT, typename TraitsT = DataTraits<DataT>>
class lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >

A manager for a set of chunks of a single type.

Each instance is intended to be a header of (meaning: located in the initial bytes of) a large contiguous memory block M, which it then takes charge of managing. In particular, M will contain all chunk descriptors and data, as well as all data structures required for management tasks (visit tracking, memory allocation, and synchronization). M is initialized by calling the placement new operator with the address of M as a parameter. To avoid any data alignment issues, M should begin at an address that is a multiple of 16 bytes (or some larger power of 2).

Finally, note that instances of this class do not contain a single pointer - when necessary, offsets (relative to some known address, e.g. of the manager instance itself) are stored instead. This, in conjunction with an appropriate choice of mutex type, makes the class suitable for placement into shared memory.

Definition at line 292 of file ChunkManagerImpl.h.

Member Typedef Documentation

template<typename MutexT , typename DataT , typename TraitsT = DataTraits<DataT>>
typedef Manager::Chunk lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::Chunk

Definition at line 295 of file ChunkManagerImpl.h.

template<typename MutexT , typename DataT , typename TraitsT = DataTraits<DataT>>
typedef SubManager<MutexT, DataT, TraitsT> lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::Manager

Definition at line 294 of file ChunkManagerImpl.h.

Constructor & Destructor Documentation

template<typename MutexT , typename DataT , typename TraitsT >
lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::ChunkManagerImpl ( )

Definition at line 702 of file ChunkManagerImpl.cc.

702  :
703  _data(reinterpret_cast<unsigned char *>(this), blocks())
704 {}
static std::size_t blocks()
Returns the offset of the first data block (relative to its manager).

Member Function Documentation

template<typename MutexT , typename DataT , typename TraitsT = DataTraits<DataT>>
static std::size_t lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::blocks ( )
inlinestaticprivate

Returns the offset of the first data block (relative to its manager).

Definition at line 299 of file ChunkManagerImpl.h.

299  {
300  return (sizeof(ChunkManagerImpl) + 511) & ~static_cast<size_t>(511);
301  }
template<typename MutexT , typename DataT , typename TraitsT >
bool lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::endVisit ( int const  visitId,
bool const  rollback 
)

Relinquishes ownership of any chunks owned by the given visit (each chunk is passed on to its first interested party that is still in flight) and removes the given visit from the list of in-flight visits.

Parameters
[in]visitIdThe visit to remove from the set of in-flight visits being tracked
[in]rollbackFlag indicating whether chunks should be rolled back (to the state they were in before being acquired by the given visit), or whether changes should be marked as committed.
Returns
true if the visit existed, was not marked as a failure and was committed, false otherwise.

Definition at line 879 of file ChunkManagerImpl.cc.

882  {
883  ScopedLock<MutexT> lock(_mutex);
884  bool roll = rollback || !_visits.isValid(visitId);
885  if (!_visits.erase(visitId)) {
886  return false;
887  }
888  // relinquish chunk ownership: if any chunks change hands, notify all threads
889  // waiting on chunk ownership to check whether they can proceed
890  if (_data.relinquishOwnership(visitId, roll, _visits)) {
891  _ownerCondition.notifyAll();
892  }
893  return !roll;
894 }
bool relinquishOwnership(int const visitId, bool const rollback, VisitTracker const &tracker)
bool isValid(int const visitId) const
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::failVisit ( int const  visitId)

Marks the given visit a failure. If the given visit has not been previously registered, or has already been marked as failed, then the call has no effect.

Definition at line 720 of file ChunkManagerImpl.cc.

720  {
721  ScopedLock<MutexT> lock(_mutex);
722  Visit * v = _visits.find(visitId);
723  if (v != 0) {
724  v->setFailed();
725  }
726 }
EntryT * find(int const id)
Returns a pointer to the entry with the given identifier, or null if there is no such entry...
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::getChunks ( std::vector< Chunk > &  chunks,
std::vector< int > const &  chunkIds 
)

Returns a chunk for each identifier in the given list that corresponds to a managed chunk.

Parameters
[out]chunksThe list to store chunks in.
[in]chunkIdsThe list of identifiers for which corresponding chunks are desired.

Definition at line 856 of file ChunkManagerImpl.cc.

859  {
860  ScopedLock<MutexT> lock(_mutex);
861  _data.getChunks(chunks, chunkIds);
862 }
void getChunks(std::vector< Chunk > &chunks, std::vector< int > const &chunkIds)
template<typename MutexT , typename DataT , typename TraitsT >
bool lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::isVisitInFlight ( int const  visitId)

Returns true if the given visit is in-flight and has not been marked as failed.

Definition at line 709 of file ChunkManagerImpl.cc.

709  {
710  ScopedLock<MutexT> lock(_mutex);
711  return _visits.isValid(visitId);
712 }
bool isValid(int const visitId) const
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::printChunk ( int const  chunkId,
std::ostream &  os 
) const

Definition at line 939 of file ChunkManagerImpl.cc.

939  {
940  ScopedLock<MutexT> lock(_mutex);
941  _data.print(chunkId, os);
942 }
void print(std::ostream &os) const
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::printChunks ( std::ostream &  os) const

Definition at line 924 of file ChunkManagerImpl.cc.

924  {
925  ScopedLock<MutexT> lock(_mutex);
926  _data.print(os);
927 }
void print(std::ostream &os) const
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::printVisit ( int const  visitId,
std::ostream &  os 
) const

Definition at line 931 of file ChunkManagerImpl.cc.

931  {
932  ScopedLock<MutexT> lock(_mutex);
933  _visits.print(visitId, os);
934  _data.printVisit(visitId, os);
935 }
void printVisit(int const visitId, std::ostream &os) const
void print(std::ostream &os) const
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::printVisits ( std::ostream &  os) const

Definition at line 917 of file ChunkManagerImpl.cc.

917  {
918  ScopedLock<MutexT> lock(_mutex);
919  _visits.print(os);
920 }
void print(std::ostream &os) const
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::registerVisit ( int const  visitId)

Registers the given visit as in-flight without performing any further action.

Exceptions
lsst::pex::exceptions::InvalidParameterErrorThrown if the given visit is already in-flight.
lsst::pex::exceptions::LengthErrorThrown if too-many visits are currently in-flight.

Definition at line 738 of file ChunkManagerImpl.cc.

738  {
739  ScopedLock<MutexT> lock(_mutex);
740  if (_visits.find(visitId) != 0) {
741  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
742  (boost::format("Cannot start processing visit %1%: visit is already in flight") % visitId).str());
743  }
744  if (_visits.space() == 0) {
745  throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
746  (boost::format("Cannot register visit %1%: too many visits in-flight") % visitId).str());
747  }
748  Visit * v = _visits.insert(visitId);
749  assert(v != 0);
750 }
EntryT * find(int const id)
Returns a pointer to the entry with the given identifier, or null if there is no such entry...
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
EntryT * insert(int const id)
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::rollbackAllExcept ( int const  visitId)
private

Definition at line 905 of file ChunkManagerImpl.cc.

905  {
906  for (Visit const * v = _visits.begin(); v != _visits.end(); ++v) {
907  int id = v->getId();
908  if (id >= 0 && id != visitId) {
909  _visits.erase(id);
910  _data.relinquishOwnership(id, true, _visits);
911  }
912  }
913 }
bool relinquishOwnership(int const visitId, bool const rollback, VisitTracker const &tracker)
template<typename MutexT , typename DataT , typename TraitsT = DataTraits<DataT>>
static std::size_t lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::size ( )
inlinestatic

Returns the total number of bytes required for a ChunkManagerImpl instance and it's associated pool of memory blocks.

Definition at line 308 of file ChunkManagerImpl.h.

308  {
309  return blocks() + Chunk::BLOCK_SIZE * TraitsT::NUM_BLOCKS;
310  }
static std::size_t blocks()
Returns the offset of the first data block (relative to its manager).
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::startVisit ( std::vector< Chunk > &  toRead,
std::vector< Chunk > &  toWaitFor,
int const  visitId,
std::vector< int > const &  chunkIds 
)

Begins visit processing by registering the given visit as an interested party of each chunk with identifier in the given list. If any identifier in the list does not have a corresponding chunk, a new chunk (owned by the specified visit) is created.

Note that the toWaitFor and toRead output vectors are cleared immediately on entry to the function. Under the assumption that these vectors are empty to begin with, strong exception safety is guaranteed.

Parameters
[out]toReadSet to the list of newly created chunks that must be read from disk.
[out]toWaitForSet to the list of chunks that are already in memory and must be waited on.
[in]visitIdThe visit to begin.
[in]chunkIdsIdentifiers for chunks to register an interest in or create.
Exceptions
lsst::pex::exceptions::InvalidParameterErrorThrown if the given visit is not currently in-flight.
lsst::pex::exceptions::LengthErrorThrown if the chunk manager does not have space to track all the chunks for the visit.

Definition at line 773 of file ChunkManagerImpl.cc.

778  {
779  toRead.clear();
780  toWaitFor.clear();
781 
782  // ensure external resources necessary for success are available
783  toRead.reserve(chunkIds.size());
784  toWaitFor.reserve(chunkIds.size());
785 
786  ScopedLock<MutexT> lock(_mutex);
787  // ensure internal resources necessary for success are available
788  if (_data.space() < static_cast<int>(chunkIds.size())) {
789  throw LSST_EXCEPT(lsst::pex::exceptions::LengthError,
790  "requested additional chunks exceed chunk manager capacity");
791  }
792  if (!_visits.isValid(visitId)) {
793  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
794  (boost::format("Cannot start processing for visit %1%: visit is not in-flight") % visitId).str());
795  }
796  // having pre-allocated/checked that there is space for everything,
797  // manager state can be modified without throwing
798  _data.createOrRegisterInterest(toRead, toWaitFor, visitId, chunkIds);
799 }
void createOrRegisterInterest(std::vector< Chunk > &toRead, std::vector< Chunk > &toWaitFor, int const visitId, std::vector< int > const &chunkIds)
bool isValid(int const visitId) const
int space() const
Returns the number of additional chunks that could be handled by this manager.
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
template<typename MutexT , typename DataT , typename TraitsT >
void lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::waitForOwnership ( std::vector< Chunk > &  toRead,
std::vector< Chunk > &  toWaitFor,
int const  visitId,
TimeSpec const &  deadline 
)

Blocks the calling thread until the given visit owns every one of the given chunks.

Note that the vector toRead passed into the method is assumed to be empty - it is immediately cleared upon entry to the function.

Parameters
[out]toReadSet to the list of chunks acquired by the given visit, but which must be re-read from disk.
[in,out]toWaitForThe list of chunks that must be owned by the given visit before returning - acquired chunks are removed from the list, so that the list is empty on successfull return.
[in]visitIdThe visit that must wait for chunk ownership.
[in]deadlineThe point in time after which chunk acquisition should be abandoned.
Exceptions
lsst::pex::exceptions::TimeoutErrorThrown if the visit deadline expired while waiting to acquire chunks.

Definition at line 820 of file ChunkManagerImpl.cc.

825  {
826  toRead.clear();
827  toRead.reserve(toWaitFor.size());
828 
829  ScopedLock<MutexT> lock(_mutex);
830  while (true) {
831  if (_data.checkForOwnership(toRead, toWaitFor, visitId)) {
832  break; // all chunks belong to the visit - ok to proceed
833  }
834  // wait for ownership
835  if (!_ownerCondition.wait(lock, deadline)) {
836  // TODO: this is a short-term DC3a hack, necessary because there is no way for
837  // the pipeline framework to communicate exceptions arising outside of the implementation
838  // of AP (e.g. in an IOStage) back to the pipeline itself. This results in visits that
839  // fail, but never relinquish ownership of their chunks. For now, take the draconian measure
840  // of rolling back all visits except the current one. This needs to be re-thought for DC3b!
841  rollbackAllExcept(visitId);
842  throw LSST_EXCEPT(lsst::pex::exceptions::TimeoutError,
843  (boost::format("Deadline for visit %1% expired") % visitId).str());
844  }
845  }
846 }
void rollbackAllExcept(int const visitId)
bool checkForOwnership(std::vector< Chunk > &toRead, std::vector< Chunk > &toWaitFor, int const visitId)
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46

Member Data Documentation

template<typename MutexT , typename DataT , typename TraitsT = DataTraits<DataT>>
Manager lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::_data
private

Definition at line 350 of file ChunkManagerImpl.h.

template<typename MutexT , typename DataT , typename TraitsT = DataTraits<DataT>>
MutexT lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::_mutex
mutableprivate

Definition at line 347 of file ChunkManagerImpl.h.

template<typename MutexT , typename DataT , typename TraitsT = DataTraits<DataT>>
Condition<MutexT> lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::_ownerCondition
private

Definition at line 348 of file ChunkManagerImpl.h.

template<typename MutexT , typename DataT , typename TraitsT = DataTraits<DataT>>
VisitTracker lsst::ap::detail::ChunkManagerImpl< MutexT, DataT, TraitsT >::_visits
private

Definition at line 349 of file ChunkManagerImpl.h.


The documentation for this class was generated from the following files: