Skip to content

Commit aa66bef

Browse files
committed
feat: add time serise pool
1 parent 535b395 commit aa66bef

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed

src/base/time_serise_pool.h

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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_

src/base/time_serise_pool_test.cc

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
18+
#include "base/time_serise_pool.h"
19+
20+
#include "gtest/gtest.h"
21+
22+
#include <vector>
23+
24+
namespace openmldb {
25+
namespace base {
26+
27+
class TimeSerisePoolTest : public ::testing::Test {
28+
public:
29+
TimeSerisePoolTest() {}
30+
~TimeSerisePoolTest() {}
31+
};
32+
33+
TEST_F(TimeSerisePoolTest, FreeToEmpty) {
34+
TimeSerisePool pool(1024);
35+
std::vector<uint64_t> times;
36+
const int datasize = 1024/2;
37+
char data[datasize];
38+
for (int i = 0; i < datasize; ++i) data[i] = i * i * i;
39+
for (int i = 0; i < 1000; ++i){
40+
auto time = (i * i % 7) * (60 * 60 * 1000);
41+
auto ptr = pool.Alloc(datasize, time);
42+
memcpy(ptr, data, datasize);
43+
times.push_back(time);
44+
}
45+
46+
for (auto time : times) pool.Free(time);
47+
48+
ASSERT_TRUE(pool.Empty());
49+
}
50+
51+
} // namespace base
52+
} // namespace openmldb
53+
54+
int main(int argc, char** argv) {
55+
::testing::InitGoogleTest(&argc, argv);
56+
return RUN_ALL_TESTS();
57+
}

0 commit comments

Comments
 (0)