@@ -33,89 +33,80 @@ template <typename T,
3333class ResourceObjectPool {
3434public:
3535 using ConstructFuncType = std::function<std::shared_ptr<T>()>;
36+ static constexpr uint64_t kSubPoolCount = 16 ;
3637
3738public:
3839 template <typename ... Args>
3940 explicit ResourceObjectPool (uint64_t init_size, Allocator* allocator, Args... args)
40- : allocator_(allocator), pool_size_ (init_size) {
41+ : allocator_(allocator), init_size_ (init_size) {
4142 this ->constructor_ = [=]() -> std::shared_ptr<T> { return std::make_shared<T>(args...); };
4243 if (allocator_ == nullptr ) {
4344 this ->owned_allocator_ = SafeAllocator::FactoryDefaultAllocator ();
4445 this ->allocator_ = owned_allocator_.get ();
4546 }
46- this ->pool_ = std::make_unique<Deque<std::shared_ptr<T>>>(this ->allocator_ );
47- this ->resize (pool_size_);
47+ for (int i = 0 ; i < kSubPoolCount ; ++i) {
48+ pool_[i] = std::make_unique<Deque<std::shared_ptr<T>>>(this ->allocator_ );
49+ }
50+ this ->fill (init_size_);
4851 }
4952
5053 ~ResourceObjectPool () {
5154 if (owned_allocator_ != nullptr ) {
52- this ->pool_ .reset ();
53- }
54- }
55-
56- void
57- SetConstructor (ConstructFuncType func) {
58- this ->constructor_ = func;
59- {
60- std::lock_guard<std::mutex> lock (mutex_);
61- while (not pool_->empty ()) {
62- pool_->pop_front ();
55+ for (int i = 0 ; i < kSubPoolCount ; ++i) {
56+ pool_[i].reset ();
6357 }
6458 }
65- this ->resize (pool_size_);
6659 }
6760
6861 std::shared_ptr<T>
6962 TakeOne () {
70- std::unique_lock<std::mutex> lock (mutex_);
71- if (pool_->empty ()) {
72- lock.unlock ();
73- return this ->constructor_ ();
63+ while (true ) {
64+ for (int i = 0 ; i < kSubPoolCount ; ++i) {
65+ if (sub_pool_mutexes_[i].try_lock ()) {
66+ if (pool_[i]->empty ()) {
67+ sub_pool_mutexes_[i].unlock ();
68+ return this ->constructor_ ();
69+ }
70+ std::shared_ptr<T> obj = pool_[i]->front ();
71+ pool_[i]->pop_front ();
72+ sub_pool_mutexes_[i].unlock ();
73+ obj->Reset ();
74+ return obj;
75+ }
76+ }
7477 }
75- std::shared_ptr<T> obj = pool_->front ();
76- pool_->pop_front ();
77- pool_size_--;
78- lock.unlock ();
79- obj->Reset ();
80- return obj;
8178 }
8279
8380 void
8481 ReturnOne (std::shared_ptr<T>& obj) {
85- std::lock_guard<std::mutex> lock (mutex_);
86- pool_->emplace_back (obj);
87- pool_size_++;
88- }
89-
90- [[nodiscard]] inline uint64_t
91- GetSize () const {
92- return this ->pool_size_ ;
82+ while (true ) {
83+ for (int i = 0 ; i < kSubPoolCount ; ++i) {
84+ if (sub_pool_mutexes_[i].try_lock ()) {
85+ pool_[i]->emplace_back (obj);
86+ sub_pool_mutexes_[i].unlock ();
87+ return ;
88+ }
89+ }
90+ }
9391 }
9492
9593private:
9694 inline void
97- resize (uint64_t size) {
98- std::lock_guard<std::mutex> lock (mutex_);
99- int count = size - pool_->size ();
100- while (count > 0 ) {
101- pool_->emplace_back (this ->constructor_ ());
102- --count;
103- }
104- while (count < 0 ) {
105- pool_->pop_front ();
106- ++count;
95+ fill (uint64_t size) {
96+ for (uint64_t i = 0 ; i < size; ++i) {
97+ auto sub_pool_idx = i % kSubPoolCount ;
98+ pool_[sub_pool_idx]->emplace_back (this ->constructor_ ());
10799 }
108100 }
109101
110- std::unique_ptr<Deque<std::shared_ptr<T>>> pool_{nullptr };
111- std::atomic<uint64_t > pool_size_;
102+ private:
103+ std::unique_ptr<Deque<std::shared_ptr<T>>> pool_[kSubPoolCount ];
104+ std::mutex sub_pool_mutexes_[kSubPoolCount ];
105+ uint64_t init_size_{0 };
112106
113107 ConstructFuncType constructor_{nullptr };
114- std::mutex mutex_;
115108 Allocator* allocator_{nullptr };
116109
117- private:
118110 std::shared_ptr<Allocator> owned_allocator_{nullptr };
119111};
120-
121112} // namespace vsag
0 commit comments