1#include "duckdb/storage/buffer/buffer_list.hpp"
2
3#include "duckdb/common/exception.hpp"
4
5using namespace duckdb;
6using namespace std;
7
8unique_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
26unique_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
57void 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