26 #ifndef MXNET_COMMON_LAZY_ALLOC_ARRAY_H_ 27 #define MXNET_COMMON_LAZY_ALLOC_ARRAY_H_ 29 #include <dmlc/logging.h> 39 template<
typename TElem>
49 template<
typename FCreate>
50 inline std::shared_ptr<TElem>
Get(
int index, FCreate creator);
55 template<
typename FVisit>
56 inline void ForEach(FVisit fvisit);
61 template<
typename SyncObject>
64 explicit unique_unlock(std::unique_lock<SyncObject> *lock)
76 std::unique_lock<SyncObject> *lock_;
80 static constexpr std::size_t kInitSize = 16;
82 std::mutex create_mutex_;
84 std::array<std::shared_ptr<TElem>, kInitSize> head_;
86 std::vector<std::shared_ptr<TElem> > more_;
88 std::atomic<bool> is_clearing_;
91 template<
typename TElem>
93 : is_clearing_(false) {
97 template<
typename TElem>
98 template<
typename FCreate>
101 size_t idx =
static_cast<size_t>(index);
102 if (idx < kInitSize) {
103 std::shared_ptr<TElem> ptr = head_[idx];
107 std::lock_guard<std::mutex> lock(create_mutex_);
108 if (!is_clearing_.load()) {
109 std::shared_ptr<TElem> ptr = head_[idx];
113 ptr = head_[idx] = std::shared_ptr<TElem>(creator());
118 std::lock_guard<std::mutex> lock(create_mutex_);
119 if (!is_clearing_.load()) {
121 if (more_.size() <= idx) {
122 more_.reserve(idx + 1);
123 while (more_.size() <= idx) {
124 more_.push_back(std::shared_ptr<TElem>(
nullptr));
127 std::shared_ptr<TElem> ptr = more_[idx];
131 ptr = more_[idx] = std::shared_ptr<TElem>(creator());
138 template<
typename TElem>
140 std::unique_lock<std::mutex> lock(create_mutex_);
141 is_clearing_.store(
true);
145 for (
size_t i = 0; i < head_.size(); ++i) {
146 std::shared_ptr<TElem> p = head_[i];
147 head_[i] = std::shared_ptr<TElem>(
nullptr);
148 unique_unlock<std::mutex> unlocker(&lock);
149 p = std::shared_ptr<TElem>(
nullptr);
151 for (
size_t i = 0; i < more_.size(); ++i) {
152 std::shared_ptr<TElem> p = more_[i];
153 more_[i] = std::shared_ptr<TElem>(
nullptr);
154 unique_unlock<std::mutex> unlocker(&lock);
155 p = std::shared_ptr<TElem>(
nullptr);
158 is_clearing_.store(
false);
161 template<
typename TElem>
162 template<
typename FVisit>
164 std::lock_guard<std::mutex> lock(create_mutex_);
165 for (
size_t i = 0; i < head_.size(); ++i) {
166 if (head_[i].
get() !=
nullptr) {
167 fvisit(i, head_[i].
get());
170 for (
size_t i = 0; i < more_.size(); ++i) {
171 if (more_[i].
get() !=
nullptr) {
172 fvisit(i + kInitSize, more_[i].
get());
179 #endif // MXNET_COMMON_LAZY_ALLOC_ARRAY_H_ std::shared_ptr< TElem > Get(int index, FCreate creator)
Get element of corresponding index, if it is not created create by creator.
Definition: lazy_alloc_array.h:99
namespace of mxnet
Definition: base.h:89
void Clear()
clear all the allocated elements in array
Definition: lazy_alloc_array.h:139
void ForEach(FVisit fvisit)
for each not null element of the array, call fvisit
Definition: lazy_alloc_array.h:163
Definition: lazy_alloc_array.h:40
LazyAllocArray()
Definition: lazy_alloc_array.h:92