LibSQL: Use Block::Index everywhere; rename pointer to block_index

No functional changes.
This commit is contained in:
Jelle Raaijmakers 2023-04-23 13:59:56 +02:00 committed by Tim Flynn
parent 6601ff9d65
commit fdac8331cc
Notes: sideshowbarker 2024-07-17 17:38:29 +09:00
19 changed files with 202 additions and 203 deletions

View file

@ -153,7 +153,7 @@ void insert_and_get_to_and_from_btree(int num_keys)
for (auto ix = 0; ix < num_keys; ix++) {
SQL::Key k(btree->descriptor());
k[0] = keys[ix];
k.set_pointer(pointers[ix]);
k.set_block_index(pointers[ix]);
btree->insert(k);
}
#ifdef LIST_TREE
@ -189,7 +189,7 @@ void insert_into_and_scan_btree(int num_keys)
for (auto ix = 0; ix < num_keys; ix++) {
SQL::Key k(btree->descriptor());
k[0] = keys[ix];
k.set_pointer(pointers[ix]);
k.set_block_index(pointers[ix]);
btree->insert(k);
}
@ -213,7 +213,7 @@ void insert_into_and_scan_btree(int num_keys)
auto key_value = key[0].to_int<i32>();
for (auto ix = 0; ix < num_keys; ix++) {
if (keys[ix] == key_value) {
EXPECT_EQ(key.pointer(), pointers[ix]);
EXPECT_EQ(key.block_index(), pointers[ix]);
break;
}
}

View file

@ -127,12 +127,12 @@ NonnullRefPtr<SQL::HashIndex> setup_hash_index(SQL::Serializer& serializer)
tuple_descriptor->append({ "schema", "table", "key_value", SQL::SQLType::Integer, SQL::Order::Ascending });
tuple_descriptor->append({ "schema", "table", "text_value", SQL::SQLType::Text, SQL::Order::Ascending });
auto directory_pointer = serializer.heap().user_value(0);
if (!directory_pointer) {
directory_pointer = serializer.heap().request_new_block_index();
serializer.heap().set_user_value(0, directory_pointer);
auto directory_block_index = serializer.heap().user_value(0);
if (!directory_block_index) {
directory_block_index = serializer.heap().request_new_block_index();
serializer.heap().set_user_value(0, directory_block_index);
}
auto hash_index = SQL::HashIndex::construct(serializer, tuple_descriptor, directory_pointer);
auto hash_index = SQL::HashIndex::construct(serializer, tuple_descriptor, directory_block_index);
return hash_index;
}
@ -149,7 +149,7 @@ void insert_and_get_to_and_from_hash_index(int num_keys)
SQL::Key k(hash_index->descriptor());
k[0] = keys[ix];
k[1] = DeprecatedString::formatted("The key value is {} and the pointer is {}", keys[ix], pointers[ix]);
k.set_pointer(pointers[ix]);
k.set_block_index(pointers[ix]);
hash_index->insert(k);
}
#ifdef LIST_HASH_INDEX
@ -247,7 +247,7 @@ void insert_into_and_scan_hash_index(int num_keys)
SQL::Key k(hash_index->descriptor());
k[0] = keys[ix];
k[1] = DeprecatedString::formatted("The key value is {} and the pointer is {}", keys[ix], pointers[ix]);
k.set_pointer(pointers[ix]);
k.set_block_index(pointers[ix]);
hash_index->insert(k);
}
#ifdef LIST_HASH_INDEX
@ -273,7 +273,7 @@ void insert_into_and_scan_hash_index(int num_keys)
for (auto ix = 0; ix < num_keys; ix++) {
if (keys[ix] == key_value) {
EXPECT_EQ(key.pointer(), pointers[ix]);
EXPECT_EQ(key.block_index(), pointers[ix]);
if (found[ix])
FAIL(DeprecatedString::formatted("Key {}, index {} already found previously", *key_value, ix));
found[ix] = true;

View file

@ -9,14 +9,14 @@
namespace SQL {
BTree::BTree(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, bool unique, u32 pointer)
: Index(serializer, descriptor, unique, pointer)
BTree::BTree(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, bool unique, Block::Index block_index)
: Index(serializer, descriptor, unique, block_index)
, m_root(nullptr)
{
}
BTree::BTree(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, u32 pointer)
: BTree(serializer, descriptor, true, pointer)
BTree::BTree(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, Block::Index block_index)
: BTree(serializer, descriptor, true, block_index)
{
}
@ -35,16 +35,16 @@ BTreeIterator BTree::end()
void BTree::initialize_root()
{
if (pointer()) {
if (serializer().has_block(pointer())) {
serializer().read_storage(pointer());
m_root = serializer().make_and_deserialize<TreeNode>(*this, pointer());
if (block_index()) {
if (serializer().has_block(block_index())) {
serializer().read_storage(block_index());
m_root = serializer().make_and_deserialize<TreeNode>(*this, block_index());
} else {
m_root = make<TreeNode>(*this, nullptr, pointer());
m_root = make<TreeNode>(*this, nullptr, block_index());
}
} else {
set_pointer(request_new_block_index());
m_root = make<TreeNode>(*this, nullptr, pointer());
set_block_index(request_new_block_index());
m_root = make<TreeNode>(*this, nullptr, block_index());
if (on_new_root)
on_new_root();
}
@ -53,8 +53,8 @@ void BTree::initialize_root()
TreeNode* BTree::new_root()
{
set_pointer(request_new_block_index());
m_root = make<TreeNode>(*this, nullptr, m_root.leak_ptr(), pointer());
set_block_index(request_new_block_index());
m_root = make<TreeNode>(*this, nullptr, m_root.leak_ptr(), block_index());
serializer().serialize_and_write(*m_root.ptr());
if (on_new_root)
on_new_root();

View file

@ -32,28 +32,28 @@ namespace SQL {
*/
class DownPointer {
public:
explicit DownPointer(TreeNode*, u32 = 0);
explicit DownPointer(TreeNode*, Block::Index = 0);
DownPointer(TreeNode*, TreeNode*);
DownPointer(DownPointer&&);
DownPointer(TreeNode*, DownPointer&);
~DownPointer() = default;
[[nodiscard]] u32 pointer() const { return m_pointer; }
[[nodiscard]] Block::Index block_index() const { return m_block_index; }
TreeNode* node();
private:
void deserialize(Serializer&);
TreeNode* m_owner;
u32 m_pointer { 0 };
Block::Index m_block_index { 0 };
OwnPtr<TreeNode> m_node { nullptr };
friend TreeNode;
};
class TreeNode : public IndexNode {
public:
TreeNode(BTree&, u32 = 0);
TreeNode(BTree&, TreeNode*, u32 = 0);
TreeNode(BTree&, TreeNode*, TreeNode*, u32 = 0);
TreeNode(BTree&, Block::Index = 0);
TreeNode(BTree&, TreeNode*, Block::Index = 0);
TreeNode(BTree&, TreeNode*, TreeNode*, Block::Index = 0);
~TreeNode() override = default;
[[nodiscard]] BTree& tree() const { return m_tree; }
@ -61,7 +61,7 @@ public:
[[nodiscard]] size_t size() const { return m_entries.size(); }
[[nodiscard]] size_t length() const;
[[nodiscard]] Vector<Key> entries() const { return m_entries; }
[[nodiscard]] u32 down_pointer(size_t) const;
[[nodiscard]] Block::Index down_pointer(size_t) const;
[[nodiscard]] TreeNode* down_node(size_t);
[[nodiscard]] bool is_leaf() const { return m_is_leaf; }
@ -97,7 +97,7 @@ class BTree : public Index {
public:
~BTree() override = default;
u32 root() const { return (m_root) ? m_root->pointer() : 0; }
Block::Index root() const { return m_root ? m_root->block_index() : 0; }
bool insert(Key const&);
bool update_key_pointer(Key const&);
Optional<u32> get(Key&);
@ -109,8 +109,8 @@ public:
Function<void(void)> on_new_root;
private:
BTree(Serializer&, NonnullRefPtr<TupleDescriptor> const&, bool unique, u32 pointer);
BTree(Serializer&, NonnullRefPtr<TupleDescriptor> const&, u32 pointer);
BTree(Serializer&, NonnullRefPtr<TupleDescriptor> const&, bool unique, Block::Index);
BTree(Serializer&, NonnullRefPtr<TupleDescriptor> const&, Block::Index);
void initialize_root();
TreeNode* new_root();
OwnPtr<TreeNode> m_root { nullptr };

View file

@ -107,7 +107,7 @@ BTreeIterator BTreeIterator::next() const
for (size_t i = 0; i < up->size(); i++) {
// One level up, try to find the entry with the current
// node's pointer as the left pointer:
if (up->down_pointer(i) == node->pointer())
if (up->down_pointer(i) == node->block_index())
// Found it. This is the iterator's next value:
return BTreeIterator(up, (int)i);
}
@ -182,7 +182,7 @@ BTreeIterator BTreeIterator::previous() const
for (size_t i = up->size(); i > 0; i--) {
// One level up, try to find the entry with the current
// node's pointer as the right pointer:
if (up->down_pointer(i) == node->pointer()) {
if (up->down_pointer(i) == node->block_index()) {
// Found it. This is the iterator's next value:
node = up;
ix = (int)i - 1;
@ -218,7 +218,7 @@ bool BTreeIterator::update(Key const& new_value)
{
if (is_end())
return false;
if ((cmp(new_value) == 0) && (key().pointer() == new_value.pointer()))
if ((cmp(new_value) == 0) && (key().block_index() == new_value.block_index()))
return true;
auto previous_iter = previous();
auto next_iter = next();

View file

@ -158,7 +158,7 @@ ResultOr<NonnullRefPtr<TableDef>> Database::get_table(DeprecatedString const& sc
auto schema_def = TRY(get_schema(schema));
auto table_def = TableDef::construct(schema_def, name);
table_def->set_pointer((*table_iterator).pointer());
table_def->set_block_index((*table_iterator).block_index());
m_table_cache.set(key.hash(), table_def);
auto table_hash = table_def->hash();
@ -173,8 +173,8 @@ ErrorOr<Vector<Row>> Database::select_all(TableDef& table)
{
VERIFY(m_table_cache.get(table.key().hash()).has_value());
Vector<Row> ret;
for (auto pointer = table.pointer(); pointer; pointer = ret.last().next_pointer())
ret.append(m_serializer.deserialize_block<Row>(pointer, table, pointer));
for (auto block_index = table.block_index(); block_index; block_index = ret.last().next_block_index())
ret.append(m_serializer.deserialize_block<Row>(block_index, table, block_index));
return ret;
}
@ -185,11 +185,11 @@ ErrorOr<Vector<Row>> Database::match(TableDef& table, Key const& key)
// TODO Match key against indexes defined on table. If found,
// use the index instead of scanning the table.
for (auto pointer = table.pointer(); pointer;) {
auto row = m_serializer.deserialize_block<Row>(pointer, table, pointer);
for (auto block_index = table.block_index(); block_index;) {
auto row = m_serializer.deserialize_block<Row>(block_index, table, block_index);
if (row.match(key))
ret.append(row);
pointer = ret.last().next_pointer();
block_index = ret.last().next_block_index();
}
return ret;
}
@ -199,16 +199,16 @@ ErrorOr<void> Database::insert(Row& row)
VERIFY(m_table_cache.get(row.table().key().hash()).has_value());
// TODO: implement table constraints such as unique, foreign key, etc.
row.set_pointer(m_heap->request_new_block_index());
row.set_next_pointer(row.table().pointer());
row.set_block_index(m_heap->request_new_block_index());
row.set_next_block_index(row.table().block_index());
TRY(update(row));
// TODO update indexes defined on table.
auto table_key = row.table().key();
table_key.set_pointer(row.pointer());
table_key.set_block_index(row.block_index());
VERIFY(m_tables->update_key_pointer(table_key));
row.table().set_pointer(row.pointer());
row.table().set_block_index(row.block_index());
return {};
}
@ -217,25 +217,25 @@ ErrorOr<void> Database::remove(Row& row)
auto& table = row.table();
VERIFY(m_table_cache.get(table.key().hash()).has_value());
if (table.pointer() == row.pointer()) {
if (table.block_index() == row.block_index()) {
auto table_key = table.key();
table_key.set_pointer(row.next_pointer());
table_key.set_block_index(row.next_block_index());
m_tables->update_key_pointer(table_key);
table.set_pointer(row.next_pointer());
table.set_block_index(row.next_block_index());
return {};
}
for (auto pointer = table.pointer(); pointer;) {
auto current = m_serializer.deserialize_block<Row>(pointer, table, pointer);
for (auto block_index = table.block_index(); block_index;) {
auto current = m_serializer.deserialize_block<Row>(block_index, table, block_index);
if (current.next_pointer() == row.pointer()) {
current.set_next_pointer(row.next_pointer());
if (current.next_block_index() == row.block_index()) {
current.set_next_block_index(row.next_block_index());
TRY(update(current));
break;
}
pointer = current.next_pointer();
block_index = current.next_block_index();
}
return {};

View file

@ -66,13 +66,13 @@ void HashDirectoryNode::serialize(Serializer& serializer) const
serializer.serialize<u32>(next_node);
for (auto ix = 0u; ix < number_of_pointers(); ix++) {
auto& bucket = m_hash_index.m_buckets[m_offset + ix];
dbgln_if(SQL_DEBUG, "Bucket index #{} pointer {} local depth {} size {}", ix, bucket->pointer(), bucket->local_depth(), bucket->size());
serializer.serialize<u32>(bucket->pointer());
dbgln_if(SQL_DEBUG, "Bucket index #{} block_index {} local depth {} size {}", ix, bucket->block_index(), bucket->local_depth(), bucket->size());
serializer.serialize<u32>(bucket->block_index());
serializer.serialize<u32>(bucket->local_depth());
}
}
HashBucket::HashBucket(HashIndex& hash_index, u32 index, u32 local_depth, u32 pointer)
HashBucket::HashBucket(HashIndex& hash_index, Block::Index index, u32 local_depth, Block::Index pointer)
: IndexNode(pointer)
, m_hash_index(hash_index)
, m_local_depth(local_depth)
@ -82,8 +82,8 @@ HashBucket::HashBucket(HashIndex& hash_index, u32 index, u32 local_depth, u32 po
void HashBucket::serialize(Serializer& serializer) const
{
dbgln_if(SQL_DEBUG, "Serializing bucket: pointer {}, index #{}, local depth {} size {}",
pointer(), index(), local_depth(), size());
dbgln_if(SQL_DEBUG, "Serializing bucket: block_index {}, index #{}, local depth {} size {}",
block_index(), index(), local_depth(), size());
serializer.serialize<u32>(local_depth());
serializer.serialize<u32>(size());
for (auto& key : m_entries)
@ -92,9 +92,9 @@ void HashBucket::serialize(Serializer& serializer) const
void HashBucket::deserialize(Serializer& serializer)
{
if (m_inflated || !pointer())
if (m_inflated || !block_index())
return;
dbgln_if(SQL_DEBUG, "Inflating Hash Bucket {}", pointer());
dbgln_if(SQL_DEBUG, "Inflating Hash Bucket {}", block_index());
m_local_depth = serializer.deserialize<u32>();
dbgln_if(SQL_DEBUG, "Bucket Local Depth {}", m_local_depth);
auto size = serializer.deserialize<u32>();
@ -120,8 +120,8 @@ Optional<u32> HashBucket::get(Key& key)
auto optional_index = find_key_in_bucket(key);
if (optional_index.has_value()) {
auto& k = m_entries[optional_index.value()];
key.set_pointer(k.pointer());
return k.pointer();
key.set_block_index(k.block_index());
return k.block_index();
}
return {};
}
@ -129,7 +129,7 @@ Optional<u32> HashBucket::get(Key& key)
bool HashBucket::insert(Key const& key)
{
if (!m_inflated)
m_hash_index.serializer().deserialize_block_to(pointer(), *this);
m_hash_index.serializer().deserialize_block_to(block_index(), *this);
if (find_key_in_bucket(key).has_value())
return false;
if (length() + key.length() > Block::DATA_SIZE) {
@ -155,7 +155,7 @@ HashBucket const* HashBucket::next_bucket()
{
for (auto ix = m_index + 1; ix < m_hash_index.size(); ix++) {
auto bucket = m_hash_index.get_bucket_by_index(ix);
m_hash_index.serializer().deserialize_block_to<HashBucket>(bucket->pointer(), *bucket);
m_hash_index.serializer().deserialize_block_to<HashBucket>(bucket->block_index(), *bucket);
if (bucket->size())
return bucket;
}
@ -166,7 +166,7 @@ HashBucket const* HashBucket::previous_bucket()
{
for (auto ix = m_index - 1; ix > 0; ix--) {
auto bucket = m_hash_index.get_bucket_by_index(ix);
if (bucket->pointer())
if (bucket->block_index() > 0)
return bucket;
}
return nullptr;
@ -175,14 +175,14 @@ HashBucket const* HashBucket::previous_bucket()
Vector<Key> const& HashBucket::entries()
{
if (!m_inflated)
m_hash_index.serializer().deserialize_block_to(pointer(), *this);
m_hash_index.serializer().deserialize_block_to(block_index(), *this);
return m_entries;
}
Key const& HashBucket::operator[](size_t ix)
{
if (!m_inflated)
m_hash_index.serializer().deserialize_block_to(pointer(), *this);
m_hash_index.serializer().deserialize_block_to(block_index(), *this);
return m_entries[ix];
}
@ -193,28 +193,26 @@ Key const& HashBucket::operator[](size_t ix) const
void HashBucket::list_bucket()
{
warnln("Bucket #{} size {} local depth {} pointer {}{}",
index(), size(), local_depth(), pointer(), (pointer() ? "" : " (VIRTUAL)"));
warnln("Bucket #{} size {} local depth {} block_index {}{}",
index(), size(), local_depth(), block_index(), (block_index() > 0 ? "" : " (VIRTUAL)"));
for (auto& key : entries())
warnln(" {} hash {}", key.to_deprecated_string(), key.hash());
}
HashIndex::HashIndex(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, u32 first_node)
HashIndex::HashIndex(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, Block::Index first_node)
: Index(serializer, descriptor, true, first_node)
, m_nodes()
, m_buckets()
{
if (!first_node)
set_pointer(request_new_block_index());
if (first_node == 0)
set_block_index(request_new_block_index());
if (serializer.has_block(first_node)) {
u32 pointer = first_node;
Block::Index block_index = first_node;
do {
VERIFY(serializer.has_block(pointer));
auto node = serializer.deserialize_block<HashDirectoryNode>(pointer, *this, pointer);
VERIFY(serializer.has_block(block_index));
auto node = serializer.deserialize_block<HashDirectoryNode>(block_index, *this, block_index);
if (node.is_last())
break;
pointer = m_nodes.last(); // FIXME Ugly
} while (pointer);
block_index = m_nodes.last(); // FIXME Ugly
} while (block_index);
} else {
auto bucket = append_bucket(0u, 1u, request_new_block_index());
bucket->m_inflated = true;
@ -231,7 +229,7 @@ HashBucket* HashIndex::get_bucket(u32 index)
{
VERIFY(index < m_buckets.size());
auto divisor = size() / 2;
while (!m_buckets[index]->pointer()) {
while (m_buckets[index]->block_index() == 0) {
VERIFY(divisor > 1);
index = index % divisor;
divisor /= 2;
@ -265,8 +263,8 @@ HashBucket* HashIndex::get_bucket_for_insert(Key const& key)
auto moved = 0;
for (auto entry_index = (int)bucket->m_entries.size() - 1; entry_index >= 0; entry_index--) {
if (bucket->m_entries[entry_index].hash() % size() == ix) {
if (!sub_bucket->pointer())
sub_bucket->set_pointer(request_new_block_index());
if (!sub_bucket->block_index())
sub_bucket->set_block_index(request_new_block_index());
sub_bucket->insert(bucket->m_entries.take(entry_index));
moved++;
}

View file

@ -24,7 +24,7 @@ namespace SQL {
class HashBucket : public IndexNode
, public Weakable<HashBucket> {
public:
HashBucket(HashIndex&, u32 index, u32 local_depth, u32 pointer);
HashBucket(HashIndex&, Block::Index index, u32 local_depth, Block::Index pointer);
~HashBucket() override = default;
Optional<u32> get(Key&);
bool insert(Key const&);
@ -35,7 +35,7 @@ public:
[[nodiscard]] u32 size() { return entries().size(); }
[[nodiscard]] size_t length() const;
[[nodiscard]] u32 size() const { return m_entries.size(); }
[[nodiscard]] u32 index() const { return m_index; }
[[nodiscard]] Block::Index index() const { return m_index; }
void serialize(Serializer&) const;
void deserialize(Serializer&);
[[nodiscard]] HashIndex const& hash_index() const { return m_hash_index; }
@ -45,12 +45,12 @@ public:
private:
Optional<size_t> find_key_in_bucket(Key const&);
void set_index(u32 index) { m_index = index; }
void set_index(Block::Index index) { m_index = index; }
void set_local_depth(u32 depth) { m_local_depth = depth; }
HashIndex& m_hash_index;
u32 m_local_depth { 1 };
u32 m_index { 0 };
Block::Index m_index { 0 };
Vector<Key> m_entries;
bool m_inflated { false };
@ -79,7 +79,7 @@ public:
void list_hash();
private:
HashIndex(Serializer&, NonnullRefPtr<TupleDescriptor> const&, u32);
HashIndex(Serializer&, NonnullRefPtr<TupleDescriptor> const&, Block::Index);
void expand();
void write_directory();

View file

@ -74,25 +74,25 @@ public:
bool has_block(Block::Index) const;
[[nodiscard]] Block::Index request_new_block_index() { return m_next_block++; }
u32 schemas_root() const { return m_schemas_root; }
Block::Index schemas_root() const { return m_schemas_root; }
void set_schemas_root(u32 root)
void set_schemas_root(Block::Index root)
{
m_schemas_root = root;
update_zero_block().release_value_but_fixme_should_propagate_errors();
}
u32 tables_root() const { return m_tables_root; }
Block::Index tables_root() const { return m_tables_root; }
void set_tables_root(u32 root)
void set_tables_root(Block::Index root)
{
m_tables_root = root;
update_zero_block().release_value_but_fixme_should_propagate_errors();
}
u32 table_columns_root() const { return m_table_columns_root; }
Block::Index table_columns_root() const { return m_table_columns_root; }
void set_table_columns_root(u32 root)
void set_table_columns_root(Block::Index root)
{
m_table_columns_root = root;
update_zero_block().release_value_but_fixme_should_propagate_errors();
@ -130,13 +130,13 @@ private:
OwnPtr<Core::BufferedFile> m_file;
Block::Index m_highest_block_written { 0 };
u32 m_next_block { 1 };
u32 m_schemas_root { 0 };
u32 m_tables_root { 0 };
u32 m_table_columns_root { 0 };
Block::Index m_next_block { 1 };
Block::Index m_schemas_root { 0 };
Block::Index m_tables_root { 0 };
Block::Index m_table_columns_root { 0 };
u32 m_version { VERSION };
Array<u32, 16> m_user_values { 0 };
HashMap<u32, ByteBuffer> m_write_ahead_log;
HashMap<Block::Index, ByteBuffer> m_write_ahead_log;
};
}

View file

@ -10,18 +10,18 @@
namespace SQL {
Index::Index(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, bool unique, u32 pointer)
Index::Index(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, bool unique, Block::Index block_index)
: m_serializer(serializer)
, m_descriptor(descriptor)
, m_unique(unique)
, m_pointer(pointer)
, m_block_index(block_index)
{
}
Index::Index(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, u32 pointer)
Index::Index(Serializer& serializer, NonnullRefPtr<TupleDescriptor> const& descriptor, Block::Index block_index)
: m_serializer(serializer)
, m_descriptor(descriptor)
, m_pointer(pointer)
, m_block_index(block_index)
{
}

View file

@ -16,19 +16,19 @@ namespace SQL {
class IndexNode {
public:
virtual ~IndexNode() = default;
[[nodiscard]] u32 pointer() const { return m_pointer; }
[[nodiscard]] Block::Index block_index() const { return m_block_index; }
IndexNode* as_index_node() { return dynamic_cast<IndexNode*>(this); }
protected:
explicit IndexNode(u32 pointer)
: m_pointer(pointer)
explicit IndexNode(Block::Index block_index)
: m_block_index(block_index)
{
}
void set_pointer(u32 pointer) { m_pointer = pointer; }
void set_block_index(Block::Index block_index) { m_block_index = block_index; }
private:
u32 m_pointer;
Block::Index m_block_index;
};
class Index : public Core::Object {
@ -40,21 +40,21 @@ public:
NonnullRefPtr<TupleDescriptor> descriptor() const { return m_descriptor; }
[[nodiscard]] bool duplicates_allowed() const { return !m_unique; }
[[nodiscard]] bool unique() const { return m_unique; }
[[nodiscard]] u32 pointer() const { return m_pointer; }
[[nodiscard]] Block::Index block_index() const { return m_block_index; }
protected:
Index(Serializer&, NonnullRefPtr<TupleDescriptor> const&, bool unique, u32 pointer);
Index(Serializer&, NonnullRefPtr<TupleDescriptor> const&, u32 pointer);
Index(Serializer&, NonnullRefPtr<TupleDescriptor> const&, bool unique, Block::Index block_index);
Index(Serializer&, NonnullRefPtr<TupleDescriptor> const&, Block::Index block_index);
[[nodiscard]] Serializer& serializer() { return m_serializer; }
void set_pointer(u32 pointer) { m_pointer = pointer; }
void set_block_index(Block::Index block_index) { m_block_index = block_index; }
u32 request_new_block_index() { return m_serializer.request_new_block_index(); }
private:
Serializer m_serializer;
NonnullRefPtr<TupleDescriptor> m_descriptor;
bool m_unique { false };
u32 m_pointer { 0 };
Block::Index m_block_index { 0 };
};
}

View file

@ -29,7 +29,7 @@ Key SchemaDef::key() const
{
auto key = Key(index_def()->to_tuple_descriptor());
key["schema_name"] = name();
key.set_pointer(pointer());
key.set_block_index(block_index());
return key;
}
@ -171,7 +171,7 @@ Key TableDef::key() const
auto key = Key(index_def()->to_tuple_descriptor());
key["schema_hash"] = parent_relation()->key().hash();
key["table_name"] = name();
key.set_pointer(pointer());
key.set_block_index(block_index());
return key;
}

View file

@ -12,6 +12,7 @@
#include <AK/Vector.h>
#include <LibCore/Object.h>
#include <LibSQL/Forward.h>
#include <LibSQL/Heap.h>
#include <LibSQL/Type.h>
#include <LibSQL/Value.h>
@ -27,29 +28,29 @@ class Relation : public Core::Object {
public:
u32 hash() const;
u32 pointer() const { return m_pointer; }
void set_pointer(u32 pointer) { m_pointer = pointer; }
Block::Index block_index() const { return m_block_index; }
void set_block_index(Block::Index block_index) { m_block_index = block_index; }
~Relation() override = default;
virtual Key key() const = 0;
Relation const* parent_relation() const { return dynamic_cast<Relation const*>(parent()); }
protected:
Relation(DeprecatedString name, u32 pointer, Relation* parent = nullptr)
Relation(DeprecatedString name, Block::Index block_index, Relation* parent = nullptr)
: Core::Object(parent)
, m_pointer(pointer)
, m_block_index(block_index)
{
set_name(move(name));
}
explicit Relation(DeprecatedString name, Relation* parent = nullptr)
: Core::Object(parent)
, m_pointer(0)
, m_block_index(0)
{
set_name(move(name));
}
private:
u32 m_pointer { 0 };
Block::Index m_block_index { 0 };
};
class SchemaDef : public Relation {

View file

@ -9,23 +9,23 @@
namespace SQL {
Row::Row(NonnullRefPtr<TableDef> table, u32 pointer)
Row::Row(NonnullRefPtr<TableDef> table, Block::Index block_index)
: Tuple(table->to_tuple_descriptor())
, m_table(move(table))
{
set_pointer(pointer);
set_block_index(block_index);
}
void Row::deserialize(Serializer& serializer)
{
Tuple::deserialize(serializer);
m_next_pointer = serializer.deserialize<u32>();
m_next_block_index = serializer.deserialize<Block::Index>();
}
void Row::serialize(Serializer& serializer) const
{
Tuple::serialize(serializer);
serializer.serialize<u32>(next_pointer());
serializer.serialize<Block::Index>(next_block_index());
}
}

View file

@ -25,22 +25,22 @@ namespace SQL {
*/
class Row : public Tuple {
public:
explicit Row(NonnullRefPtr<TableDef>, u32 pointer = 0);
explicit Row(NonnullRefPtr<TableDef>, Block::Index block_index = 0);
virtual ~Row() override = default;
[[nodiscard]] u32 next_pointer() const { return m_next_pointer; }
void set_next_pointer(u32 ptr) { m_next_pointer = ptr; }
[[nodiscard]] Block::Index next_block_index() const { return m_next_block_index; }
void set_next_block_index(Block::Index index) { m_next_block_index = index; }
TableDef const& table() const { return *m_table; }
TableDef& table() { return *m_table; }
[[nodiscard]] virtual size_t length() const override { return Tuple::length() + sizeof(u32); }
[[nodiscard]] virtual size_t length() const override { return Tuple::length() + sizeof(Block::Index); }
virtual void serialize(Serializer&) const override;
virtual void deserialize(Serializer&) override;
private:
NonnullRefPtr<TableDef> m_table;
u32 m_next_pointer { 0 };
Block::Index m_next_block_index { 0 };
};
}

View file

@ -42,16 +42,16 @@ public:
}
template<typename T, typename... Args>
T deserialize_block(u32 pointer, Args&&... args)
T deserialize_block(Block::Index block_index, Args&&... args)
{
read_storage(pointer);
read_storage(block_index);
return deserialize<T>(forward<Args>(args)...);
}
template<typename T>
void deserialize_block_to(u32 pointer, T& t)
void deserialize_block_to(Block::Index block_index, T& t)
{
read_storage(pointer);
read_storage(block_index);
return deserialize_to<T>(t);
}
@ -107,7 +107,7 @@ public:
VERIFY(!m_heap.is_null());
reset();
serialize<T>(t);
m_heap->write_storage(t.pointer(), m_buffer).release_value_but_fixme_should_propagate_errors();
m_heap->write_storage(t.block_index(), m_buffer).release_value_but_fixme_should_propagate_errors();
return true;
}

View file

@ -12,30 +12,30 @@
namespace SQL {
DownPointer::DownPointer(TreeNode* owner, u32 pointer)
DownPointer::DownPointer(TreeNode* owner, Block::Index block_index)
: m_owner(owner)
, m_pointer(pointer)
, m_block_index(block_index)
, m_node(nullptr)
{
}
DownPointer::DownPointer(TreeNode* owner, TreeNode* node)
: m_owner(owner)
, m_pointer((node) ? node->pointer() : 0)
, m_block_index((node) ? node->block_index() : 0)
, m_node(adopt_own_if_nonnull(node))
{
}
DownPointer::DownPointer(TreeNode* owner, DownPointer& down)
: m_owner(owner)
, m_pointer(down.m_pointer)
, m_block_index(down.m_block_index)
, m_node(move(down.m_node))
{
}
DownPointer::DownPointer(DownPointer&& other)
: m_owner(other.m_owner)
, m_pointer(other.pointer())
, m_block_index(other.block_index())
, m_node(other.m_node ? move(other.m_node) : nullptr)
{
}
@ -49,14 +49,14 @@ TreeNode* DownPointer::node()
void DownPointer::deserialize(Serializer& serializer)
{
if (m_node || !m_pointer)
if (m_node || !m_block_index)
return;
serializer.read_storage(m_pointer);
m_node = serializer.make_and_deserialize<TreeNode>(m_owner->tree(), m_owner, m_pointer);
serializer.read_storage(m_block_index);
m_node = serializer.make_and_deserialize<TreeNode>(m_owner->tree(), m_owner, m_block_index);
}
TreeNode::TreeNode(BTree& tree, u32 pointer)
: IndexNode(pointer)
TreeNode::TreeNode(BTree& tree, Block::Index block_index)
: IndexNode(block_index)
, m_tree(tree)
, m_up(nullptr)
, m_entries()
@ -64,8 +64,8 @@ TreeNode::TreeNode(BTree& tree, u32 pointer)
{
}
TreeNode::TreeNode(BTree& tree, TreeNode* up, u32 pointer)
: IndexNode(pointer)
TreeNode::TreeNode(BTree& tree, TreeNode* up, Block::Index block_index)
: IndexNode(block_index)
, m_tree(tree)
, m_up(up)
, m_entries()
@ -75,8 +75,8 @@ TreeNode::TreeNode(BTree& tree, TreeNode* up, u32 pointer)
m_is_leaf = true;
}
TreeNode::TreeNode(BTree& tree, TreeNode* up, DownPointer& left, u32 pointer)
: IndexNode(pointer)
TreeNode::TreeNode(BTree& tree, TreeNode* up, DownPointer& left, Block::Index block_index)
: IndexNode(block_index)
, m_tree(tree)
, m_up(up)
, m_entries()
@ -85,20 +85,20 @@ TreeNode::TreeNode(BTree& tree, TreeNode* up, DownPointer& left, u32 pointer)
if (left.m_node != nullptr)
left.m_node->m_up = this;
m_down.append(DownPointer(this, left));
m_is_leaf = left.pointer() == 0;
if (!pointer)
set_pointer(m_tree.request_new_block_index());
m_is_leaf = left.block_index() == 0;
if (!block_index)
set_block_index(m_tree.request_new_block_index());
}
TreeNode::TreeNode(BTree& tree, TreeNode* up, TreeNode* left, u32 pointer)
: IndexNode(pointer)
TreeNode::TreeNode(BTree& tree, TreeNode* up, TreeNode* left, Block::Index block_index)
: IndexNode(block_index)
, m_tree(tree)
, m_up(up)
, m_entries()
, m_down()
{
m_down.append(DownPointer(this, left));
m_is_leaf = left->pointer() == 0;
m_is_leaf = left->block_index() == 0;
}
void TreeNode::deserialize(Serializer& serializer)
@ -130,12 +130,12 @@ void TreeNode::serialize(Serializer& serializer) const
if (sz > 0) {
for (auto ix = 0u; ix < size(); ix++) {
auto& entry = m_entries[ix];
dbgln_if(SQL_DEBUG, "Serializing Left[{}] = {}", ix, m_down[ix].pointer());
serializer.serialize<u32>(is_leaf() ? 0u : m_down[ix].pointer());
dbgln_if(SQL_DEBUG, "Serializing Left[{}] = {}", ix, m_down[ix].block_index());
serializer.serialize<u32>(is_leaf() ? 0u : m_down[ix].block_index());
serializer.serialize<Key>(entry);
}
dbgln_if(SQL_DEBUG, "Serializing Right = {}", m_down[size()].pointer());
serializer.serialize<u32>(is_leaf() ? 0u : m_down[size()].pointer());
dbgln_if(SQL_DEBUG, "Serializing Right = {}", m_down[size()].block_index());
serializer.serialize<u32>(is_leaf() ? 0u : m_down[size()].block_index());
}
}
@ -151,7 +151,7 @@ size_t TreeNode::length() const
bool TreeNode::insert(Key const& key)
{
dbgln_if(SQL_DEBUG, "[#{}] INSERT({})", pointer(), key.to_deprecated_string());
dbgln_if(SQL_DEBUG, "[#{}] INSERT({})", block_index(), key.to_deprecated_string());
if (!is_leaf())
return node_for(key)->insert_in_leaf(key);
return insert_in_leaf(key);
@ -159,16 +159,16 @@ bool TreeNode::insert(Key const& key)
bool TreeNode::update_key_pointer(Key const& key)
{
dbgln_if(SQL_DEBUG, "[#{}] UPDATE({}, {})", pointer(), key.to_deprecated_string(), key.pointer());
dbgln_if(SQL_DEBUG, "[#{}] UPDATE({}, {})", block_index(), key.to_deprecated_string(), key.block_index());
if (!is_leaf())
return node_for(key)->update_key_pointer(key);
for (auto ix = 0u; ix < size(); ix++) {
if (key == m_entries[ix]) {
dbgln_if(SQL_DEBUG, "[#{}] {} == {}",
pointer(), key.to_deprecated_string(), m_entries[ix].to_deprecated_string());
if (m_entries[ix].pointer() != key.pointer()) {
m_entries[ix].set_pointer(key.pointer());
block_index(), key.to_deprecated_string(), m_entries[ix].to_deprecated_string());
if (m_entries[ix].block_index() != key.block_index()) {
m_entries[ix].set_block_index(key.block_index());
dump_if(SQL_DEBUG, "To WAL");
tree().serializer().serialize_and_write<TreeNode>(*this);
}
@ -184,20 +184,20 @@ bool TreeNode::insert_in_leaf(Key const& key)
if (!m_tree.duplicates_allowed()) {
for (auto& entry : m_entries) {
if (key == entry) {
dbgln_if(SQL_DEBUG, "[#{}] duplicate key {}", pointer(), key.to_deprecated_string());
dbgln_if(SQL_DEBUG, "[#{}] duplicate key {}", block_index(), key.to_deprecated_string());
return false;
}
}
}
dbgln_if(SQL_DEBUG, "[#{}] insert_in_leaf({})", pointer(), key.to_deprecated_string());
dbgln_if(SQL_DEBUG, "[#{}] insert_in_leaf({})", block_index(), key.to_deprecated_string());
just_insert(key, nullptr);
return true;
}
u32 TreeNode::down_pointer(size_t ix) const
Block::Index TreeNode::down_pointer(size_t ix) const
{
return m_down[ix].pointer();
return m_down[ix].block_index();
}
TreeNode* TreeNode::down_node(size_t ix)
@ -213,12 +213,12 @@ TreeNode* TreeNode::node_for(Key const& key)
for (size_t ix = 0; ix < size(); ix++) {
if (key < m_entries[ix]) {
dbgln_if(SQL_DEBUG, "[{}] {} < {} v{}",
pointer(), (DeprecatedString)key, (DeprecatedString)m_entries[ix], m_down[ix].pointer());
block_index(), (DeprecatedString)key, (DeprecatedString)m_entries[ix], m_down[ix].block_index());
return down_node(ix)->node_for(key);
}
}
dbgln_if(SQL_DEBUG, "[#{}] {} >= {} v{}",
pointer(), key.to_deprecated_string(), (DeprecatedString)m_entries[size() - 1], m_down[size()].pointer());
block_index(), key.to_deprecated_string(), (DeprecatedString)m_entries[size() - 1], m_down[size()].block_index());
return down_node(size())->node_for(key);
}
@ -229,42 +229,42 @@ Optional<u32> TreeNode::get(Key& key)
if (key < m_entries[ix]) {
if (is_leaf()) {
dbgln_if(SQL_DEBUG, "[#{}] {} < {} -> 0",
pointer(), key.to_deprecated_string(), (DeprecatedString)m_entries[ix]);
block_index(), key.to_deprecated_string(), (DeprecatedString)m_entries[ix]);
return {};
} else {
dbgln_if(SQL_DEBUG, "[{}] {} < {} ({} -> {})",
pointer(), key.to_deprecated_string(), (DeprecatedString)m_entries[ix],
ix, m_down[ix].pointer());
block_index(), key.to_deprecated_string(), (DeprecatedString)m_entries[ix],
ix, m_down[ix].block_index());
return down_node(ix)->get(key);
}
}
if (key == m_entries[ix]) {
dbgln_if(SQL_DEBUG, "[#{}] {} == {} -> {}",
pointer(), key.to_deprecated_string(), (DeprecatedString)m_entries[ix],
m_entries[ix].pointer());
key.set_pointer(m_entries[ix].pointer());
return m_entries[ix].pointer();
block_index(), key.to_deprecated_string(), (DeprecatedString)m_entries[ix],
m_entries[ix].block_index());
key.set_block_index(m_entries[ix].block_index());
return m_entries[ix].block_index();
}
}
if (m_entries.is_empty()) {
dbgln_if(SQL_DEBUG, "[#{}] {} Empty node??", pointer(), key.to_deprecated_string());
dbgln_if(SQL_DEBUG, "[#{}] {} Empty node??", block_index(), key.to_deprecated_string());
VERIFY_NOT_REACHED();
}
if (is_leaf()) {
dbgln_if(SQL_DEBUG, "[#{}] {} > {} -> 0",
pointer(), key.to_deprecated_string(), (DeprecatedString)m_entries[size() - 1]);
block_index(), key.to_deprecated_string(), (DeprecatedString)m_entries[size() - 1]);
return {};
}
dbgln_if(SQL_DEBUG, "[#{}] {} > {} ({} -> {})",
pointer(), key.to_deprecated_string(), (DeprecatedString)m_entries[size() - 1],
size(), m_down[size()].pointer());
block_index(), key.to_deprecated_string(), (DeprecatedString)m_entries[size() - 1],
size(), m_down[size()].block_index());
return down_node(size())->get(key);
}
void TreeNode::just_insert(Key const& key, TreeNode* right)
{
dbgln_if(SQL_DEBUG, "[#{}] just_insert({}, right = {})",
pointer(), (DeprecatedString)key, (right) ? right->pointer() : 0);
block_index(), (DeprecatedString)key, (right) ? right->block_index() : 0);
dump_if(SQL_DEBUG, "Before");
for (auto ix = 0u; ix < size(); ix++) {
if (key < m_entries[ix]) {
@ -336,25 +336,25 @@ void TreeNode::dump_if(int flag, DeprecatedString&& msg)
if (!flag)
return;
StringBuilder builder;
builder.appendff("[#{}] ", pointer());
builder.appendff("[#{}] ", block_index());
if (!msg.is_empty())
builder.appendff("{}", msg);
builder.append(": "sv);
if (m_up)
builder.appendff("[^{}] -> ", m_up->pointer());
builder.appendff("[^{}] -> ", m_up->block_index());
else
builder.append("* -> "sv);
for (size_t ix = 0; ix < m_entries.size(); ix++) {
if (!is_leaf())
builder.appendff("[v{}] ", m_down[ix].pointer());
builder.appendff("[v{}] ", m_down[ix].block_index());
else
VERIFY(m_down[ix].pointer() == 0);
VERIFY(m_down[ix].block_index() == 0);
builder.appendff("'{}' ", (DeprecatedString)m_entries[ix]);
}
if (!is_leaf())
builder.appendff("[v{}]", m_down[size()].pointer());
builder.appendff("[v{}]", m_down[size()].block_index());
else
VERIFY(m_down[size()].pointer() == 0);
VERIFY(m_down[size()].block_index() == 0);
builder.appendff(" (size {}", (int)size());
if (is_leaf())
builder.append(", leaf"sv);
@ -369,7 +369,7 @@ void TreeNode::list_node(int indent)
warn(" ");
};
do_indent();
warnln("--> #{}", pointer());
warnln("--> #{}", block_index());
for (auto ix = 0u; ix < size(); ix++) {
if (!is_leaf())
down_node(ix)->list_node(indent + 2);

View file

@ -19,10 +19,10 @@ Tuple::Tuple()
{
}
Tuple::Tuple(NonnullRefPtr<TupleDescriptor> const& descriptor, u32 pointer)
Tuple::Tuple(NonnullRefPtr<TupleDescriptor> const& descriptor, Block::Index block_index)
: m_descriptor(descriptor)
, m_data()
, m_pointer(pointer)
, m_block_index(block_index)
{
for (auto& element : *descriptor)
m_data.empend(element.type);
@ -37,8 +37,8 @@ Tuple::Tuple(NonnullRefPtr<TupleDescriptor> const& descriptor, Serializer& seria
void Tuple::deserialize(Serializer& serializer)
{
dbgln_if(SQL_DEBUG, "deserialize tuple at offset {}", serializer.offset());
serializer.deserialize_to<u32>(m_pointer);
dbgln_if(SQL_DEBUG, "pointer: {}", m_pointer);
serializer.deserialize_to<u32>(m_block_index);
dbgln_if(SQL_DEBUG, "block_index: {}", m_block_index);
auto number_of_elements = serializer.deserialize<u32>();
m_data.clear();
m_descriptor->clear();
@ -51,8 +51,8 @@ void Tuple::deserialize(Serializer& serializer)
void Tuple::serialize(Serializer& serializer) const
{
VERIFY(m_descriptor->size() == m_data.size());
dbgln_if(SQL_DEBUG, "Serializing tuple pointer {}", pointer());
serializer.serialize<u32>(pointer());
dbgln_if(SQL_DEBUG, "Serializing tuple with block_index {}", block_index());
serializer.serialize<u32>(block_index());
serializer.serialize<u32>(m_descriptor->size());
for (auto ix = 0u; ix < m_descriptor->size(); ix++) {
serializer.serialize<TupleElementDescriptor>((*m_descriptor)[ix]);
@ -140,8 +140,8 @@ DeprecatedString Tuple::to_deprecated_string() const
builder.append('|');
builder.append(part.to_deprecated_string());
}
if (pointer() != 0)
builder.appendff(":{}", pointer());
if (block_index() != 0)
builder.appendff(":{}", block_index());
return builder.to_deprecated_string();
}
@ -155,7 +155,7 @@ void Tuple::copy_from(Tuple const& other)
m_data.clear();
for (auto& part : other.m_data)
m_data.append(part);
m_pointer = other.pointer();
m_block_index = other.block_index();
}
int Tuple::compare(Tuple const& other) const

View file

@ -27,7 +27,7 @@ namespace SQL {
class Tuple {
public:
Tuple();
explicit Tuple(NonnullRefPtr<TupleDescriptor> const&, u32 pointer = 0);
explicit Tuple(NonnullRefPtr<TupleDescriptor> const&, Block::Index = 0);
Tuple(NonnullRefPtr<TupleDescriptor> const&, Serializer&);
Tuple(Tuple const&);
virtual ~Tuple() = default;
@ -55,8 +55,8 @@ public:
Tuple& operator+=(Value const&);
void extend(Tuple const&);
[[nodiscard]] u32 pointer() const { return m_pointer; }
void set_pointer(u32 ptr) { m_pointer = ptr; }
[[nodiscard]] Block::Index block_index() const { return m_block_index; }
void set_block_index(Block::Index index) { m_block_index = index; }
[[nodiscard]] size_t size() const { return m_data.size(); }
[[nodiscard]] virtual size_t length() const;
@ -77,7 +77,7 @@ protected:
private:
NonnullRefPtr<TupleDescriptor> m_descriptor;
Vector<Value> m_data;
u32 m_pointer { 2 * sizeof(u32) };
Block::Index m_block_index { 0 };
friend Serializer;
};