1 | #include "duckdb/storage/buffer/buffer_list.hpp" |
---|---|
2 | |
3 | #include "duckdb/common/exception.hpp" |
4 | |
5 | using namespace duckdb; |
6 | using namespace std; |
7 | |
8 | unique_ptr<BufferEntry> BufferList::Pop() { |
9 | if (!root) { |
10 | // no root: return nullptr |
11 | return nullptr; |
12 | } |
13 | // fetch root |
14 | auto entry = move(root); |
15 | root = move(entry->next); |
16 | if (root) { |
17 | // new root no longer has prev pointer |
18 | root->prev = nullptr; |
19 | } else { |
20 | last = nullptr; |
21 | } |
22 | count--; |
23 | return entry; |
24 | } |
25 | |
26 | unique_ptr<BufferEntry> BufferList::Erase(BufferEntry *entry) { |
27 | assert(entry->prev || entry == root.get()); |
28 | assert(entry->next || entry == last); |
29 | // first get the entry, either from the previous entry or from the root node |
30 | auto current = entry->prev ? move(entry->prev->next) : move(root); |
31 | auto prev = entry->prev; |
32 | if (entry == last) { |
33 | // entry was last entry: last is now the previous entry |
34 | last = prev; |
35 | } |
36 | // now set up prev/next pointers correctly |
37 | auto next = move(entry->next); |
38 | if (!prev) { |
39 | // no prev: entry was root |
40 | root = move(next); |
41 | if (root) { |
42 | // new root no longer has prev pointer |
43 | root->prev = nullptr; |
44 | } else { |
45 | last = nullptr; |
46 | } |
47 | assert(!root || !root->prev); |
48 | } else if (prev != last) { |
49 | assert(next); |
50 | next->prev = prev; |
51 | prev->next = move(next); |
52 | } |
53 | count--; |
54 | return current; |
55 | } |
56 | |
57 | void BufferList::Append(unique_ptr<BufferEntry> entry) { |
58 | assert(!entry->next); |
59 | if (!last) { |
60 | // empty list: set as root |
61 | entry->prev = nullptr; |
62 | root = move(entry); |
63 | last = root.get(); |
64 | } else { |
65 | // non-empty list: append to last entry and set entry as last |
66 | entry->prev = last; |
67 | last->next = move(entry); |
68 | last = last->next.get(); |
69 | } |
70 | count++; |
71 | } |
72 |