• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef COMMON_COMPONENTS_COMMON_NEW_MARK_STACK_H
17 #define COMMON_COMPONENTS_COMMON_NEW_MARK_STACK_H
18 
19 #include <mutex>
20 #include "common_components/base/time_utils.h"
21 
22 namespace common {
23 template<class T>
24 class MarkStackBuffer {
25 constexpr static size_t MAX = 64;
26 
27 public:
28     MarkStackBuffer<T>* next = nullptr;
29     MarkStackBuffer<T>* pre = nullptr;
full()30     bool full() { return count == MAX; }
31 
empty()32     bool empty() { return count == 0; }
33 
push_back(T t)34     void push_back(T t)
35     {
36         LOGF_CHECK(!full()) << "Mark stack buffer can not be full when push back";
37         stack_[count] = t;
38         count++;
39     }
40 
back()41     T back()
42     {
43         LOGF_CHECK(!empty()) << "Mark stack buffer can not be empty when get back";
44         return stack_[count - 1];
45     }
46 
pop_back()47     void pop_back()
48     {
49         LOGF_CHECK(!empty()) << "Mark stack buffer can not be empty when pop back";
50         count--;
51     }
52     size_t count = 0;
53 
54 private:
55     T stack_[MAX];
56 };
57 
58 template<class T>
59 class MarkStack {
60 public:
61     MarkStack() = default;
62 
MarkStack(MarkStack && stack)63     MarkStack(MarkStack&& stack)
64     {
65         this->h_ = stack.head();
66         this->t_ = stack.tail();
67         this->s_ = stack.size();
68         stack.clean();
69     }
70 
MarkStack(MarkStackBuffer<T> * buf)71     MarkStack(MarkStackBuffer<T>* buf) : h_(buf)
72     {
73         MarkStackBuffer<T>* tmp = buf;
74         while (tmp != nullptr) {
75             if (tmp->next == nullptr) {
76                 this->t_ = tmp;
77             }
78             this->s_++;
79             tmp = tmp->next;
80         }
81     }
82 
~MarkStack()83     ~MarkStack() { clear(); }
84 
head()85     MarkStackBuffer<T>* head() { return this->h_; }
86 
tail()87     MarkStackBuffer<T>* tail() { return this->t_; }
88 
size()89     size_t size() { return this->s_; }
90 
count()91     size_t count()
92     {
93         MarkStackBuffer<T> *current = this->h_;
94         size_t ret = 0;
95         while (current!=nullptr) {
96             ret+=current->count;
97             current = current->next;
98         }
99 
100         return ret;
101     }
102 
empty()103     bool empty()
104     {
105         return this->s_ == 0 && this->h_ == nullptr && this->t_ == nullptr;
106     }
107 
clear()108     void clear()
109     {
110         while (!empty()) {
111             MarkStackBuffer<T>* tmp = this->h_;
112             this->h_ = this->h_->next;
113             if (this->h_ != nullptr) {
114                 this->h_->pre = nullptr;
115             }
116             delete tmp;
117             tmp = nullptr;
118             this->s_--;
119         }
120         this->t_ = nullptr;
121     }
122 
push_back(T value)123     void push_back(T value)
124     {
125         if (this->t_ == nullptr || this->t_->full()) {
126             push(new MarkStackBuffer<T>());
127         }
128         this->t_->push_back(value);
129     }
130 
back()131     T back()
132     {
133         if (this->t_ == nullptr) {
134             return nullptr;
135         }
136         return this->t_->back();
137     }
138 
pop_back()139     void pop_back()
140     {
141         LOGF_CHECK(!empty()) << "Mark stack can not be empty when pop back";
142         this->t_->pop_back();
143         if (this->t_->empty()) {
144             auto tmp = pop();
145             delete tmp;
146             tmp = nullptr;
147         }
148     }
149 
insert(MarkStack<T> & stack)150     void insert(MarkStack<T>& stack)
151     {
152         if (stack.empty()) {
153             return;
154         }
155         if (this->h_ == nullptr) {
156             this->h_ = stack.head();
157             this->t_ = stack.tail();
158             this->s_ = stack.size();
159             stack.clean();
160             return;
161         }
162         this->t_->next = stack.head();
163         stack.head()->pre = this->t_;
164         this->t_ = stack.tail();
165         this->s_ += stack.size();
166         stack.clean();
167     }
168 
split(size_t splitNum)169     MarkStackBuffer<T>* split(size_t splitNum)
170     {
171         if (splitNum == 0 || s_ == 0) {
172             return nullptr;
173         }
174         auto res = this->h_;
175         size_t num = 0;
176         while (num < splitNum) {
177             if (num == splitNum - 1) {
178                 auto tmp = this->h_;
179                 this->h_ = this->h_->next;
180                 if (this->h_ != nullptr) {
181                     this->h_->pre = nullptr;
182                 }
183                 tmp->next = nullptr;
184             } else {
185                 this->h_ = this->h_->next;
186             }
187             num++;
188             this->s_--;
189             if (this->h_ == nullptr) {
190                 this->t_ = nullptr;
191                 return res;
192             }
193         }
194         return res;
195     }
196 private:
push(MarkStackBuffer<T> * buf)197     void push(MarkStackBuffer<T>* buf)
198     {
199         if (empty()) {
200             this->h_ = buf;
201             this->t_ = buf;
202             this->s_++;
203             return;
204         }
205         buf->pre = this->t_;
206         this->t_->next = buf;
207         this->t_ = buf;
208         this->s_++;
209     }
210 
pop()211     MarkStackBuffer<T>* pop()
212     {
213         if (empty()) {
214             return nullptr;
215         }
216         MarkStackBuffer<T>* res = this->t_;
217         this->t_ = this->t_->pre;
218         if (this->t_ != nullptr) {
219             this->t_->next = nullptr;
220         } else {
221             this->h_ = nullptr;
222         }
223         res->pre = nullptr;
224         this->s_--;
225         return res;
226     }
227 
clean()228     void clean()
229     {
230         if (empty()) {
231             return;
232         }
233         this->h_ = nullptr;
234         this->t_ = nullptr;
235         this->s_ = 0;
236     }
237 
238     MarkStackBuffer<T>* h_ = nullptr;
239     MarkStackBuffer<T>* t_ = nullptr;
240     size_t s_ = 0;
241 };
242 }
243 #endif // COMMON_COMPONENTS_COMMON_NEW_MARK_STACK_H
244