Files
mlpack/fastlib/u/garryb/superpar/array.h
T

193 lines
3.9 KiB
C++

/**
* Abstractions for arrays of pointerless structs.
*
* These arrays can be transparently distributed and parallel without
* your slighted knowledge.
*/
#ifndef SUPERPAR_ARRAY_H
#define SUPERPAR_ARRAY_H
/**
* Array abstraction for regular in-RAM arrays.
*
* This should not have any overhead over regular arrays.
*/
template<typename TElement>
class ArrayInCore {
FORBID_COPY(ArrayInCore);
public:
/** The element type. */
typedef TElement Element;
private:
/** A plain old in-memory array.
*
* TODO: Use ArrayList
*/
Element *ptr_;
/** The number of elements in the array. */
index_t size_;
#ifdef DEBUG
/** Number of live items. */
index_t live_;
#endif
public:
ArrayInCore() {}
~ArrayInCore() {
delete[] ptr_;
DEBUG_ONLY(ptr_ = BIG_BAD_NUMBER);
DEBUG_SAME_SIZE(live_, 0);
}
void Init(index_t size_in) {
ptr_ = new Element[size_];
size_ = size_in;
DEBUG_ONLY(live_ = 0);
}
index_t size() const {
return size_;
}
/**
* Starts reading a single element.
*
* When done, you must call StopRead.
*/
const Element *StartRead(index_t element_id) {
DEBUG_BOUNDS(element_id, size_);
DEBUG_ONLY(live_++);
return ptr_ + element_id;
}
/**
* Stops reading a single element.
*
* This will free any resources associated with the returned
* pointer (if necessary).
*/
void StopRead(const Element *ptr, index_t element_id) {
DEBUG_ASSERT(ptr - ptr_ == element_id);
DEBUG_ONLY(live_--);
/* nothing necessary */
}
/**
* Starts writing to a segment of the array.
*
* Exclusive access is required. This returns a pointer that acts as
* an array and can be written to. When you are done, you must call
* StopWrite.
*/
Element *StartWrite(index_t element_id) {
DEBUG_BOUNDS(element_id, size_);
DEBUG_ONLY(live_++);
return ptr_ + element_id;
}
/**
* Stops writing from a segment of the array.
*
* If necessary, this flushes back any changes and frees up any
* associated resources.
*/
void StopWrite(Element *ptr, index_t element_id) {
DEBUG_ASSERT(ptr - ptr_ == element_id);
DEBUG_ONLY(live_--);
/* nothing necessary */
}
void DeclareWritebackRange(index_t start, index_t count) {
}
void DeclareTempRange(index_t start, index_t count) {
}
void FlushWritebackRange(index_t start, index_t count) {
}
};
#endif
#ifdef GRAVEYARD
/**
* Starts reading from a segment of the array.
*
* This assumes that nobody else is writing to the same block
* of memory, or that you are fine with unpredictable store/load
* ordering.
*
* When done, you must call StopRead.
*/
const Element *StartRead(index_t begin, index_t count) {
DEBUG_BOUNDS(begin, size_);
DEBUG_BOUNDS(begin + count, size_ + 1);
DEBUG_ONLY(live_++);
return ptr_ + begin;
}
/**
* Stops reading from a segment of the array.
*
* This will free any resources associated with the returned
* pointer (if necessary).
*/
void StopRead(const Element *ptr, index_t begin, index_t count) {
DEBUG_ASSERT(ptr - ptr_ == begin);
DEBUG_ONLY(live_--);
/* nothing necessary */
}
/**
* Starts writing to a segment of the array.
*
* Exclusive access is required. This returns a pointer that acts as
* an array and can be written to. When you are done, you must call
* StopWrite.
*/
Element *StartWrite(index_t begin, index_t count) {
DEBUG_BOUNDS(begin, size_);
DEBUG_BOUNDS(begin + count, size_ + 1);
DEBUG_ONLY(live_++);
return ptr_ + begin;
}
/**
* Stops writing from a segment of the array.
*
* If necessary, this flushes back any changes and frees up any
* associated resources.
*/
void StopWrite(Element *ptr, index_t begin, index_t count) {
DEBUG_ASSERT(ptr - ptr_ == begin);
DEBUG_ONLY(live_--);
/* nothing necessary */
}
#endif