59 |
* automatically detect whether an ID became invalid, using such an ID is thus |
* automatically detect whether an ID became invalid, using such an ID is thus |
60 |
* safer than storing an Iterator or even a raw pointer in use case scenarios of |
* safer than storing an Iterator or even a raw pointer in use case scenarios of |
61 |
* storing long term references to Pool elements. |
* storing long term references to Pool elements. |
62 |
* |
* |
63 |
* This ID type is currently set (constrained) to 32-bit because the current |
* This ID type must be exactly equal to type vmint, because the latter is used |
64 |
* real-time instrument script infrastructure implementation, which heavily |
* by the real-time instrument script infrastructure implementation, which in |
65 |
* relies on element IDs, is currently using 32-bit for its integer script |
* turn heavily relies on element IDs, and it is using 64-bit for its integer |
66 |
* variable type. |
* script variable type. |
67 |
*/ |
*/ |
68 |
typedef uint32_t pool_element_id_t; |
typedef uint64_t pool_element_id_t; |
69 |
|
|
70 |
// just symbol prototyping |
// just symbol prototyping |
71 |
template<typename T> class Pool; |
template<typename T> class Pool; |
76 |
protected: |
protected: |
77 |
template<typename T1> |
template<typename T1> |
78 |
struct _Node { |
struct _Node { |
79 |
|
typedef uint64_t reincarnation_t; |
80 |
|
|
81 |
_Node<T1>* next; |
_Node<T1>* next; |
82 |
_Node<T1>* prev; |
_Node<T1>* prev; |
83 |
T1* data; |
T1* data; |
84 |
#if CONFIG_DEVMODE |
#if CONFIG_DEVMODE |
85 |
RTListBase<T1>* list; // list to which this node currently belongs to |
RTListBase<T1>* list; // list to which this node currently belongs to |
86 |
#endif // CONFIG_DEVMODE |
#endif // CONFIG_DEVMODE |
87 |
uint reincarnation; // just for Pool::fromID() |
reincarnation_t reincarnation; // just for Pool::fromID() |
88 |
|
|
89 |
_Node() { |
_Node() { |
90 |
next = NULL; |
next = NULL; |
684 |
Node* nodes; |
Node* nodes; |
685 |
T* data; |
T* data; |
686 |
RTListBase<T> freelist; // not yet allocated elements |
RTListBase<T> freelist; // not yet allocated elements |
687 |
uint poolsize; |
size_t poolsize; |
688 |
// following 3 used for element ID generation (and vice versa) |
// following 3 used for element ID generation (and vice versa) |
689 |
uint poolsizebits; ///< Amount of bits required to index all elements of this pool (according to current pool size). |
uint poolsizebits; ///< Amount of bits required to index all elements of this pool (according to current pool size). |
690 |
uint reservedbits; ///< 3rd party reserved bits on the left side of id (default: 0). |
uint reservedbits; ///< 3rd party reserved bits on the left side of id (default: 0). |
716 |
* |
* |
717 |
* @see poolIsEmpty() |
* @see poolIsEmpty() |
718 |
*/ |
*/ |
719 |
bool poolHasFreeElements(int elements) { |
bool poolHasFreeElements(ssize_t elements) { |
720 |
for (Iterator it = freelist.first(); it != freelist.end() && elements >= 0; ++it) |
for (Iterator it = freelist.first(); it != freelist.end() && elements >= 0; ++it) |
721 |
--elements; |
--elements; |
722 |
return elements <= 0; |
return elements <= 0; |
723 |
} |
} |
724 |
|
|
725 |
int countFreeElements() { |
ssize_t countFreeElements() { |
726 |
return freelist.count(); |
return freelist.count(); |
727 |
} |
} |
728 |
|
|
734 |
* |
* |
735 |
* @see resizePool() |
* @see resizePool() |
736 |
*/ |
*/ |
737 |
uint poolSize() const { |
size_t poolSize() const { |
738 |
return poolsize; |
return poolsize; |
739 |
} |
} |
740 |
|
|
750 |
* |
* |
751 |
* @see poolSize() |
* @see poolSize() |
752 |
*/ |
*/ |
753 |
void resizePool(int Elements) { |
void resizePool(ssize_t Elements) { |
754 |
if (freelist.count() != poolsize) { |
if (freelist.count() != poolsize) { |
755 |
#if CONFIG_DEVMODE |
#if CONFIG_DEVMODE |
756 |
throw std::runtime_error(__err_msg_resize_while_in_use); |
throw std::runtime_error(__err_msg_resize_while_in_use); |
812 |
*/ |
*/ |
813 |
pool_element_id_t getID(const T* obj) const { |
pool_element_id_t getID(const T* obj) const { |
814 |
if (!poolsize) return 0; |
if (!poolsize) return 0; |
815 |
int index = int( obj - &data[0] ); |
ssize_t index = ssize_t( obj - &data[0] ); |
816 |
if (index < 0 || index >= poolsize) return 0; |
if (index < 0 || index >= poolsize) return 0; |
817 |
return ((nodes[index].reincarnation << poolsizebits) | index) + 1; |
return ((nodes[index].reincarnation << poolsizebits) | index) + 1; |
818 |
} |
} |
850 |
if (id == 0 || id == -1) return Iterator(); // invalid iterator |
if (id == 0 || id == -1) return Iterator(); // invalid iterator |
851 |
id--; |
id--; |
852 |
const uint bits = poolsizebits; |
const uint bits = poolsizebits; |
853 |
uint index = id & ((1 << bits) - 1); |
size_t index = id & ((1 << bits) - 1); |
854 |
if (index >= poolsize) return Iterator(); // invalid iterator |
if (index >= poolsize) return Iterator(); // invalid iterator |
855 |
Node* node = &nodes[index]; |
Node* node = &nodes[index]; |
856 |
uint reincarnation = id >> bits; |
typename Node::reincarnation_t reincarnation = id >> bits; |
857 |
if (reincarnation != node->reincarnation) return Iterator(); // invalid iterator |
if (reincarnation != node->reincarnation) return Iterator(); // invalid iterator |
858 |
return Iterator(node); |
return Iterator(node); |
859 |
} |
} |
870 |
*/ |
*/ |
871 |
Iterator fromPtr(const T* obj) const { |
Iterator fromPtr(const T* obj) const { |
872 |
if (!poolsize) return Iterator(); // invalid iterator |
if (!poolsize) return Iterator(); // invalid iterator |
873 |
int index = int( obj - &data[0] ); |
ssize_t index = ssize_t( obj - &data[0] ); |
874 |
if (index < 0 || index >= poolsize) return Iterator(); // invalid iterator |
if (index < 0 || index >= poolsize) return Iterator(); // invalid iterator |
875 |
return Iterator(&nodes[index]); |
return Iterator(&nodes[index]); |
876 |
} |
} |
899 |
friend class RTList<T>; |
friend class RTList<T>; |
900 |
|
|
901 |
private: |
private: |
902 |
void _init(int Elements) { |
void _init(ssize_t Elements) { |
903 |
data = new T[Elements]; |
data = new T[Elements]; |
904 |
nodes = new Node[Elements]; |
nodes = new Node[Elements]; |
905 |
for (int i = 0; i < Elements; i++) { |
for (ssize_t i = 0; i < Elements; i++) { |
906 |
nodes[i].data = &data[i]; |
nodes[i].data = &data[i]; |
907 |
freelist.append(&nodes[i]); |
freelist.append(&nodes[i]); |
908 |
} |
} |
915 |
reincarnationbits = sizeof(pool_element_id_t) * 8 - poolsizebits - reservedbits; |
reincarnationbits = sizeof(pool_element_id_t) * 8 - poolsizebits - reservedbits; |
916 |
} |
} |
917 |
|
|
918 |
inline static int bitsForSize(int size) { |
inline static int bitsForSize(ssize_t size) { |
919 |
if (!size) return 0; |
if (!size) return 0; |
920 |
size--; |
size--; |
921 |
int bits = 0; |
int bits = 0; |
922 |
for (; size > 1; bits += 2, size >>= 2); |
for (; size > 1; bits += 2, size >>= 2); |
923 |
return bits + size; |
return int(bits + size); |
924 |
} |
} |
925 |
}; |
}; |
926 |
|
|