-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlog_allocator.cpp
More file actions
64 lines (51 loc) · 2.2 KB
/
log_allocator.cpp
File metadata and controls
64 lines (51 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "log_allocator.h"
#include <iostream>
LogAllocator::LogAllocator(size_t start, size_t size, size_t error_result) : error_result_(error_result) {
Insert(start, size);
}
size_t LogAllocator::Allocate(size_t size) {
auto iter = segments_size_.lower_bound({size, 0});
if (iter == segments_size_.end()) {
return error_result_;
}
size_t index = iter->second;
if (size < iter->first) {
Insert(index + size, iter->first - size);
}
segments_start_.erase({index, iter->first});
segments_size_.erase(iter);
return index;
}
bool LogAllocator::Free(size_t start, size_t size)
{
auto iter_right = segments_start_.upper_bound({start, 0});
auto iter_left = (iter_right == segments_start_.begin() ? segments_start_.end() : std::prev(iter_right)); // если тот что справа самый первый, то левее уже никого
if ((iter_left != segments_start_.end()) && (iter_left->first + iter_left->second > start)) {
return false; // Освобождаем в отрезке который и так свободен
} else if ((iter_right != segments_start_.end()) && (start + size > iter_right->first)) {
return false; // Освобождаем в отрезке который и так свободен
}
if ((iter_left != segments_start_.end()) && (iter_left->first + iter_left->second == start)) { // Объединяем с левым сегментом
start = iter_left->first;
size += iter_left->second;
segments_size_.erase({iter_left->second, iter_left->first});
segments_start_.erase(iter_left);
}
if ((iter_right != segments_start_.end()) && (start + size == iter_right->first)) { // Объединяем с правым сегментом
size += iter_right->second;
segments_size_.erase({iter_right->second, iter_right->first});
segments_start_.erase(iter_right);
}
Insert(start, size);
return true;
}
void LogAllocator::Insert(size_t start, size_t size) {
segments_start_.insert({start, size});
segments_size_.insert({size, start});
}
const std::set<std::pair<size_t, size_t>>& LogAllocator::DebugSegmentsStart() const {
return segments_start_;
}
const std::set<std::pair<size_t, size_t>>& LogAllocator::DebugSegmentsSize() const {
return segments_size_;
}