The Pedigree Project 0.1
MappingList.h
1/* Copyright (c) 2026, Pedigree Developers. */
2#ifndef VFS_MAPPING_LIST_H
3#define VFS_MAPPING_LIST_H
4
5#include "pedigree/kernel/utilities/List.h"
6#include "pedigree/kernel/utilities/Tree.h"
7
11template <class Object>
13 public:
14 using Iterator = typename List<Object*>::Iterator;
15 using ReverseIterator = typename List<Object*>::ReverseIterator;
16
17 MappingList() = default;
18
19 size_t count() const {
20 return m_Objects.count();
21 }
22 Iterator begin() {
23 return m_Objects.begin();
24 }
25 Iterator end() {
26 return m_Objects.end();
27 }
28 ReverseIterator rbegin() {
29 return m_Objects.rbegin();
30 }
31 ReverseIterator rend() {
32 return m_Objects.rend();
33 }
34
35 bool tryPushBack(Object* object) {
36 assert(object && !m_HasReservation);
37 if (!reserveBack(object->address()))
38 return false;
39 publishBack(object);
40 return true;
41 }
42
44 bool reserveBack(uintptr_t address) {
45 assert(!m_HasReservation);
46 if (m_Index.contains(address) || !m_Index.tryInsert(address, nullptr))
47 return false;
48 if (!m_Objects.tryPushBack(nullptr)) {
49 m_Index.remove(address);
50 return false;
51 }
52 m_ReservedAddress = address;
53 m_HasReservation = true;
54 return true;
55 }
56
57 void publishBack(Object* object) {
58 assert(m_HasReservation && object && object->address() == m_ReservedAddress);
59 Object** slot = m_Index.find(m_ReservedAddress);
60 assert(slot && !*slot);
61 *slot = object;
62 *m_Objects.rbegin() = object;
63 m_HasReservation = false;
64 }
65
66 Object* popBack() {
67 Object* object = m_Objects.popBack();
68 if (m_HasReservation) {
69 assert(!object);
70 m_Index.remove(m_ReservedAddress);
71 m_HasReservation = false;
72 } else if (object) {
73 m_Index.remove(object->address());
74 }
75 return object;
76 }
77
78 Iterator erase(Iterator& it) {
79 assert(!m_HasReservation && *it);
80 m_Index.remove((*it)->address());
81 return m_Objects.erase(it);
82 }
83 ReverseIterator erase(ReverseIterator& it) {
84 assert(!m_HasReservation && *it);
85 m_Index.remove((*it)->address());
86 return m_Objects.erase(it);
87 }
88
89 Object* find(uintptr_t address, size_t* objectVisits = nullptr) const {
90 if (objectVisits)
91 *objectVisits = 0;
92 uintptr_t start;
93 Object* object;
94 if (!m_Index.floorBound(address, start, object))
95 return nullptr;
96 // A split can reenter before publishing its reserved suffix. The source
97 // still owns that range until the split changes its length.
98 if (!object && (!start || !m_Index.floorBound(start - 1, start, object)))
99 return nullptr;
100 if (!object)
101 return nullptr;
102 if (objectVisits)
103 *objectVisits = 1;
104 return object->matches(address) ? object : nullptr;
105 }
106
107 private:
108 NOT_COPYABLE_OR_ASSIGNABLE(MappingList);
109
110 List<Object*> m_Objects;
112 uintptr_t m_ReservedAddress = 0;
113 bool m_HasReservation = false;
114};
115
116#endif
An iterator applicable for many data structures.
Definition Iterator.h:41
Definition List.h:61
Iterator begin()
Definition List.h:122
ReverseIterator rend()
Definition List.h:152
ReverseIterator rbegin()
Definition List.h:142
::Iterator< T, node_t > Iterator
Definition List.h:67
Iterator end()
Definition List.h:132
bool reserveBack(uintptr_t address)
Definition MappingList.h:44
A key/value dictionary.
Definition Tree.h:33
E * find(const K &key)
Definition Tree.h:208
bool tryInsert(const K &key, const E &value)
Definition Tree.h:169
void remove(const K &key)
Definition Tree.h:301
bool contains(const K &key) const
Definition Tree.h:287
bool floorBound(const K &key, K &foundKey, E &foundValue) const
Definition Tree.h:263
Iterator erase(Iterator &Iter)
Definition List.h:352
bool tryPushBack(const T &value)
Definition List.h:246
size_t count() const
Definition List.h:212
T popBack()
Definition List.h:278