1+ /*
2+ * Copyright 2021 4Paradigm
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+
17+ #ifndef SRC_BASE_TIME_SERISE_POOL_H_
18+ #define SRC_BASE_TIME_SERISE_POOL_H_
19+
20+ #include < malloc.h>
21+ #include < memory>
22+ #include < map>
23+
24+ namespace openmldb {
25+ namespace base {
26+
27+
28+ class TimeBucket {
29+ public:
30+ TimeBucket (uint32_t block_size) : block_size_(block_size), current_offset_(block_size + 1 ), object_num_(0 ) {
31+ head_ = (Block*)malloc (sizeof (Block*)); // empty block at end
32+ head_->next = NULL ;
33+ }
34+ void Clear ()
35+ {
36+ auto p = head_;
37+ while (p)
38+ {
39+ auto q = p->next ;
40+ free (p);
41+ p = q;
42+ }
43+ }
44+ void * Alloc (uint32_t size) {
45+ object_num_++;
46+ if (current_offset_ + size <= block_size_ - sizeof (Block)) {
47+ void * addr = head_->data + current_offset_;
48+ current_offset_ += size;
49+ return addr;
50+ } else {
51+ auto block = (Block*)malloc (block_size_);
52+ current_offset_ = size;
53+ block->next = head_->next ;
54+ head_ = block;
55+ return head_->data ;
56+ }
57+ }
58+ bool Free () // ret if fully freed
59+ {
60+ if (!--object_num_)
61+ {
62+ Clear ();
63+ return true ;
64+ }
65+ else return false ;
66+ }
67+ private:
68+ uint32_t block_size_;
69+ uint32_t current_offset_;
70+ uint32_t object_num_;
71+ struct Block {
72+ Block* next;
73+ char data[];
74+ } *head_;
75+ };
76+
77+ class TimeSerisePool {
78+ public:
79+ explicit TimeSerisePool (uint32_t block_size) : block_size_(block_size) {
80+
81+ }
82+ void * Alloc (uint32_t size, uint64_t time) {
83+ auto pair = pool_.find (keyof (time));
84+ if (pair == pool_.end ()){
85+ auto bucket = new TimeBucket (block_size_);
86+ pool_.insert (std::pair<uint32_t , std::unique_ptr<TimeBucket>>(keyof (time), std::unique_ptr<TimeBucket>(bucket)));
87+ return bucket->Alloc (size);
88+ }
89+
90+ return pair->second ->Alloc (size);
91+ }
92+ void Free (uint64_t time) {
93+ auto pair = pool_.find (keyof (time));
94+ if (pair->second ->Free ()) {
95+ pool_.erase (pair);
96+ }
97+ }
98+ bool Empty (){
99+ return pool_.empty ();
100+ }
101+ private:
102+ // key is the time / (60 * 60 * 1000)
103+ uint32_t block_size_;
104+ std::map<uint32_t , std::unique_ptr<TimeBucket>> pool_;
105+ inline static uint32_t keyof (uint64_t time) {
106+ return time / (60 * 60 * 1000 );
107+ }
108+ };
109+
110+ }
111+ }
112+
113+ #endif // SRC_BASE_TIME_SERISE_POOL_H_
0 commit comments