Apollo  6.0
Open source self driving car software
light_object_pool.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2018 The Apollo Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *****************************************************************************/
16 #pragma once
17 
18 #include <deque>
19 #include <list>
20 #include <map>
21 #include <memory>
22 #include <queue>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 
29 
30 namespace apollo {
31 namespace perception {
32 namespace base {
33 
34 // @brief a simplified light object pool from concurrent object pool, can be
35 // specialized for different sensors
36 template <class ObjectType, size_t N = kPoolDefaultSize,
37  class Initializer = ObjectPoolDefaultInitializer<ObjectType>,
39 class LightObjectPool : public BaseObjectPool<ObjectType> {
40  public:
42 
43  // @brief Only allow accessing from global instance
45  const std::string& sensor_name = "velodyne64") {
46  typedef std::shared_ptr<LightObjectPool> LightObjectPoolPtr;
47  static std::map<std::string, LightObjectPoolPtr> object_pool;
48  auto itr = object_pool.find(sensor_name);
49  if (itr == object_pool.end()) {
50  auto ret = object_pool.insert(std::pair<std::string, LightObjectPoolPtr>(
51  sensor_name, LightObjectPoolPtr(new LightObjectPool(N))));
52  return *(ret.first->second);
53  }
54  return *(itr->second);
55  }
56 
57  // @brief overrided function to get object smart pointer
58  std::shared_ptr<ObjectType> Get() override {
59  ObjectType* ptr = nullptr;
60  if (queue_.empty()) {
61  Add(1 + kPoolDefaultExtendNum);
62  }
63  ptr = queue_.front();
64  queue_.pop();
65  kInitializer(ptr);
66  return std::shared_ptr<ObjectType>(
67  ptr, [&](ObjectType* obj_ptr) { queue_.push(obj_ptr); });
68  }
69 
70  // @brief overrided function to get batch of smart pointers
71  // @params[IN] num: batch number
72  // @params[OUT] data: vector container to store the pointers
73  void BatchGet(size_t num,
74  std::vector<std::shared_ptr<ObjectType>>* data) override {
75  if (queue_.size() < num) {
76  Add(num - queue_.size() + kPoolDefaultExtendNum);
77  }
78  ObjectType* ptr = nullptr;
79  for (size_t i = 0; i < num; ++i) {
80  ptr = queue_.front();
81  queue_.pop();
82  kInitializer(ptr);
83  data->emplace_back(std::shared_ptr<ObjectType>(
84  ptr, [&](ObjectType* obj_ptr) { queue_.push(obj_ptr); }));
85  }
86  }
87 
88  // @brief overrided function to get batch of smart pointers
89  // @params[IN] num: batch number
90  // @params[IN] is_front: indicating insert to front or back of the list
91  // @params[OUT] data: list container to store the pointers
92  void BatchGet(size_t num, bool is_front,
93  std::list<std::shared_ptr<ObjectType>>* data) override {
94  std::vector<ObjectType*> buffer(num, nullptr);
95  if (queue_.size() < num) {
96  Add(num - queue_.size() + kPoolDefaultExtendNum);
97  }
98  for (size_t i = 0; i < num; ++i) {
99  buffer[i] = queue_.front();
100  queue_.pop();
101  }
102  for (size_t i = 0; i < num; ++i) {
103  kInitializer(buffer[i]);
104  is_front
105  ? data->emplace_front(std::shared_ptr<ObjectType>(
106  buffer[i], [&](ObjectType* obj_ptr) { queue_.push(obj_ptr); }))
107  : data->emplace_back(std::shared_ptr<ObjectType>(
108  buffer[i], [&](ObjectType* obj_ptr) { queue_.push(obj_ptr); }));
109  }
110  }
111 
112  // @brief overrided function to get batch of smart pointers
113  // @params[IN] num: batch number
114  // @params[IN] is_front: indicating insert to front or back of the deque
115  // @params[OUT] data: deque container to store the pointers
116  void BatchGet(size_t num, bool is_front,
117  std::deque<std::shared_ptr<ObjectType>>* data) override {
118  std::vector<ObjectType*> buffer(num, nullptr);
119  if (queue_.size() < num) {
120  Add(num - queue_.size() + kPoolDefaultExtendNum);
121  }
122  for (size_t i = 0; i < num; ++i) {
123  buffer[i] = queue_.front();
124  queue_.pop();
125  }
126  for (size_t i = 0; i < num; ++i) {
127  kInitializer(buffer[i]);
128  is_front
129  ? data->emplace_front(std::shared_ptr<ObjectType>(
130  buffer[i], [&](ObjectType* obj_ptr) { queue_.push(obj_ptr); }))
131  : data->emplace_back(std::shared_ptr<ObjectType>(
132  buffer[i], [&](ObjectType* obj_ptr) { queue_.push(obj_ptr); }));
133  }
134  }
135 
136  // @brief overrided function to set capacity
137  void set_capacity(size_t capacity) override {
138  if (capacity_ < capacity) {
139  Add(capacity - capacity_);
140  }
141  }
142 
143  // @brief get remained object number
144  size_t RemainedNum() override { return queue_.size(); }
145  // @brief destructor to release the cached memory
146  ~LightObjectPool() override {
147  if (cache_) {
148  delete[] cache_;
149  cache_ = nullptr;
150  }
151  for (auto& ptr : extended_cache_) {
152  delete ptr;
153  }
154  extended_cache_.clear();
155  }
156 
157  protected:
158  // @brief add num objects, should add lock before invoke this function
159  void Add(size_t num) {
160  for (size_t i = 0; i < num; ++i) {
161  ObjectType* ptr = new ObjectType;
162  extended_cache_.push_back(ptr);
163  queue_.push(ptr);
164  }
166  }
167 
168  // @brief default constructor
169  explicit LightObjectPool(const size_t default_size)
170  : kDefaultCacheSize(default_size) {
172  for (size_t i = 0; i < kDefaultCacheSize; ++i) {
173  queue_.push(&cache_[i]);
174  }
176  }
177 
178  std::queue<ObjectType*> queue_;
179  // @brief point to a continuous memory of default pool size
180  ObjectType* cache_ = nullptr;
181  const size_t kDefaultCacheSize;
182  // @brief list to store extended memory, not as efficient
183  std::list<ObjectType*> extended_cache_;
184  // TODO(All): Fix lint issue with static const
185  Initializer kInitializer;
186  // Initializer kInitializer;
187 };
188 
189 } // namespace base
190 } // namespace perception
191 } // namespace apollo
void BatchGet(size_t num, bool is_front, std::list< std::shared_ptr< ObjectType >> *data) override
Definition: light_object_pool.h:92
Definition: light_object_pool.h:39
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
ObjectType * cache_
Definition: light_object_pool.h:180
void set_capacity(size_t capacity) override
Definition: light_object_pool.h:137
const size_t kDefaultCacheSize
Definition: light_object_pool.h:181
Initializer kInitializer
Definition: light_object_pool.h:185
LightObjectPool(const size_t default_size)
Definition: light_object_pool.h:169
static LightObjectPool & Instance(const std::string &sensor_name="velodyne64")
Definition: light_object_pool.h:44
size_t capacity_
Definition: object_pool.h:66
void Add(size_t num)
Definition: light_object_pool.h:159
void BatchGet(size_t num, bool is_front, std::deque< std::shared_ptr< ObjectType >> *data) override
Definition: light_object_pool.h:116
Definition: object_pool.h:28
std::shared_ptr< ObjectType > Get() override
Definition: light_object_pool.h:58
~LightObjectPool() override
Definition: light_object_pool.h:146
SensorType
Sensor types are set in the order of lidar, radar, camera, ultrasonic Please make sure SensorType has...
Definition: sensor_meta.h:29
ObjectType
Definition: object_types.h:26
void BatchGet(size_t num, std::vector< std::shared_ptr< ObjectType >> *data) override
Definition: light_object_pool.h:73
std::list< ObjectType * > extended_cache_
Definition: light_object_pool.h:183
size_t RemainedNum() override
Definition: light_object_pool.h:144
std::queue< ObjectType * > queue_
Definition: light_object_pool.h:178