aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-05-09 23:03:00 -0300
committerMarcos Magueta <maguetamarcos@gmail.com>2026-05-09 23:03:00 -0300
commitc375b1c69665ae7c16ffa3f17264386dfc257d8e (patch)
treec0a45b370512ae6d4b4a9500c244419567a357ef /include
parent921de259fa441fb562aec701f0c8c14310f126e4 (diff)
downloadRNT-c375b1c69665ae7c16ffa3f17264386dfc257d8e.tar.gz
RNT-c375b1c69665ae7c16ffa3f17264386dfc257d8e.zip
FOL VM with cursor mocked storage
Diffstat (limited to '')
-rw-r--r--include/CursorManager.h54
-rw-r--r--include/HandlerManager.h22
-rw-r--r--include/ObjectManager.h55
-rw-r--r--include/Types.h43
-rw-r--r--include/VM.h45
5 files changed, 193 insertions, 26 deletions
diff --git a/include/CursorManager.h b/include/CursorManager.h
index 7e1ebe0..78ea24c 100644
--- a/include/CursorManager.h
+++ b/include/CursorManager.h
@@ -1,6 +1,12 @@
#pragma once
#include "Api.h"
+#include "HandlerManager.h"
+#include "Types.h"
+
+#include <string>
+#include <unordered_map>
+#include <vector>
/**
* @file CursorManager.h
@@ -35,5 +41,53 @@ namespace nt
*/
class NT_API CursorManager
{
+ public:
+ /** @brief Active scan state for a single relation. */
+ struct cursor {
+ /** Handle that authorized this cursor. */
+ HandlerManager::handle* handle;
+ // TODO: Replace with a lazy iterator into the physical storage backend.
+ // Pre-loading all tuples on Open() is a mock simplification.
+ std::vector<Tuple> tuples;
+ size_t position = 0;
+ };
+
+ /**
+ * @brief Opens a cursor on the relation referenced by the handle.
+ * @param handle Authorized handle to a RELATION object.
+ * @return A new cursor, or nullptr if the object is not a RELATION.
+ */
+ cursor* Open(HandlerManager::handle* handle);
+
+ /**
+ * @brief Pulls the next tuple from the cursor.
+ *
+ * The returned pointer is valid until the next Next() or Close() call.
+ *
+ * @param cursor Active cursor.
+ * @return Pointer to the next tuple, or nullptr when exhausted.
+ */
+ Tuple* Next(cursor* cursor);
+
+ /**
+ * @brief Closes the cursor and releases its resources.
+ * @param cursor Cursor to close.
+ */
+ void Close(cursor* cursor);
+
+ /**
+ * @brief Inserts one tuple into the mock store for a given relation path.
+ *
+ * TODO: Replace with physical storage writes when the backend is wired up.
+ *
+ * @param path Logical path of the relation.
+ * @param tuple Attribute values for the tuple to insert.
+ */
+ void MockInsert(std::vector<std::string> path, std::vector<Attribute> tuple);
+
+ private:
+ // TODO: Replace with physical storage backend access.
+ // Keyed by the relation path joined as "seg/seg/...".
+ std::unordered_map<std::string, std::vector<std::vector<Attribute>>> mock_store_;
};
}
diff --git a/include/HandlerManager.h b/include/HandlerManager.h
index 185cc55..4f63f17 100644
--- a/include/HandlerManager.h
+++ b/include/HandlerManager.h
@@ -13,11 +13,27 @@
namespace nt
{
+ class IdentityManager;
+ class LifecycleManager;
+ class PermissionsManager;
+
/** @brief Opens and closes authorized handles to registry objects. */
class NT_API HandlerManager
{
public:
/**
+ * @brief Constructs a HandlerManager with shared runtime dependencies.
+ *
+ * All managers are injected so that state (registry entries, lifecycle
+ * counters, permission policy) persists across calls rather than being
+ * rebuilt per open/close.
+ */
+ HandlerManager(ObjectManager& objects,
+ PermissionsManager& permissions,
+ IdentityManager& identities,
+ LifecycleManager& lifecycles);
+
+ /**
* @brief Represents authorized access to an object in the registry.
*
* This increases the handle count in the object manager. We should
@@ -51,5 +67,11 @@ namespace nt
* @return True when the handle was closed successfully.
*/
bool Close(struct handle* handle);
+
+ private:
+ ObjectManager& objects_;
+ PermissionsManager& permissions_;
+ IdentityManager& identities_;
+ LifecycleManager& lifecycles_;
};
}
diff --git a/include/ObjectManager.h b/include/ObjectManager.h
index 52ba602..aab3a6f 100644
--- a/include/ObjectManager.h
+++ b/include/ObjectManager.h
@@ -4,6 +4,7 @@
#include "Types.h"
#include <cstdint>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -31,14 +32,12 @@ namespace nt
virtual ~IObject() = default;
};
- /** @brief Object representing a multigroup. */
- class Multigroup : IObject {};
- /** @brief Object representing a relation. */
- class Relation : IObject {};
- /** @brief Object representing a tuple. */
- class Tuple : IObject {};
- /** @brief Object representing a transaction. */
- class Transaction : IObject {};
+ /** @brief Abstract registry object representing a multigroup. */
+ class Multigroup : public IObject {};
+ /** @brief Abstract registry object representing a relation. */
+ class Relation : public IObject {};
+ /** @brief Abstract registry object representing a transaction. */
+ class Transaction : public IObject {};
/** @brief Describes the behavior and capabilities of an object category. */
struct object_type {
@@ -52,12 +51,14 @@ namespace nt
/** @brief Shared metadata stored at the head of a registry entry. */
struct registry_head {
- /** Number of object-to-object references. */
- uint32_t reference_count;
- /** Number of open handles. */
- uint32_t handle_count;
- /** Object type metadata. */
- struct object_type* type;
+ // TODO: Increment reference_count when one registry object depends on another
+ // (e.g. an ephemeral view that references base relations). Decrement when the
+ // dependency is removed. Used to block cleanup of objects still referenced by others.
+ uint32_t reference_count = 0;
+ /** Number of open handles. Maintained by LifecycleManager::Monitor/Unmonitor. */
+ uint32_t handle_count = 0;
+ /** Object type metadata. Owned by this head. */
+ std::unique_ptr<object_type> type;
/** Logical object path inside the namespace. */
std::vector<std::string> path;
/** security_descriptor to be added later, maybe also a set of labels */
@@ -66,21 +67,31 @@ namespace nt
/** @brief Node in the object registry. */
struct registry {
/** Shared metadata for this object. */
- struct registry_head* head;
- /** Stored object payload. */
- IObject object;
+ std::unique_ptr<registry_head> head;
+ /** Abstract object payload. Owned by this entry. */
+ std::unique_ptr<IObject> object;
/** TODO: Treat as a list for now, but ideally it is a tree. */
- struct registry* next;
+ std::unique_ptr<registry> next;
};
- /** Root registry entries. */
- struct registry** entries;
+ /** @brief Head of the registry linked list. Owned by this manager. */
+ std::unique_ptr<registry> entries;
+
+ /**
+ * @brief Registers an object under the given path, taking ownership of it.
+ * @param path Logical object path.
+ * @param object Object payload. Ownership is transferred to the registry.
+ * @param type Object type descriptor. Ownership is transferred to the registry.
+ */
+ void Register(std::vector<std::string> path,
+ std::unique_ptr<IObject> object,
+ std::unique_ptr<object_type> type);
/**
* @brief Looks into this registry and attempts to retrieve an entry.
* @param object_path Logical path to search for.
- * @return Matching registry entry, or nullptr when no object is found.
+ * @return Borrowed pointer to the matching entry, or nullptr when not found.
*/
- struct registry* Find(const std::vector<std::string> object_path);
+ registry* Find(const std::vector<std::string> object_path);
};
}
diff --git a/include/Types.h b/include/Types.h
index 9d55765..c6f4b9f 100644
--- a/include/Types.h
+++ b/include/Types.h
@@ -1,8 +1,11 @@
#pragma once
+#include <string>
+#include <vector>
+
/**
* @file Types.h
- * @brief Shared enum types used by the runtime managers.
+ * @brief Shared enum types and core data types used by the runtime.
*/
/** @brief Runtime object categories known by the object manager. */
@@ -11,9 +14,7 @@ enum OBJECT_TYPE {
MULTIGROUP,
/** A relation object. */
RELATION,
- /** A tuple object. */
- TUPLE,
- /** An attribute object. */
+ /** An attribute object (schema metadata). */
ATTRIBUTE,
/** A transaction object. */
TRANSACTION
@@ -46,3 +47,37 @@ enum AUTH_METHOD {
/** Plain-text authentication. */
PLAIN_TEXT
};
+
+namespace nt
+{
+ /** @brief A single named value in a tuple, produced by the cursor layer. */
+ struct Attribute {
+ std::string name;
+ std::string value;
+ };
+
+ /**
+ * @brief A single row of data streamed lazily from the cursor layer.
+ *
+ * Follows the Volcano pull model: callers repeatedly call Next() to consume
+ * one attribute at a time. Returns nullptr when all attributes are exhausted.
+ */
+ class Tuple {
+ public:
+ explicit Tuple(std::vector<Attribute> attributes)
+ : attributes_(std::move(attributes)) {}
+
+ /** @brief Returns the next attribute, or nullptr when exhausted. */
+ const Attribute* Next() {
+ if (position_ < attributes_.size())
+ return &attributes_[position_++];
+ return nullptr;
+ }
+
+ void Reset() { position_ = 0; }
+
+ private:
+ std::vector<Attribute> attributes_;
+ size_t position_ = 0;
+ };
+}
diff --git a/include/VM.h b/include/VM.h
index 2defe79..d6402b3 100644
--- a/include/VM.h
+++ b/include/VM.h
@@ -1,6 +1,8 @@
#pragma once
#include "Api.h"
+#include "CursorManager.h"
+#include "Types.h"
/**
* @file VM.h
@@ -45,7 +47,50 @@ namespace nt
* snapshots pinned through LifecycleManager::Monitor only for the minimum
* time required.
*/
+ /**
+ * @brief A node in the Volcano operator tree executed by the Tarski (FOL) runtime.
+ *
+ * Each node represents one relational algebra operator. The tree is demand-driven:
+ * VM::Next() propagates pull requests from root to leaves.
+ *
+ * TODO: Add FILTER, PROJECT, and JOIN operators as the query layer grows.
+ */
+ struct NT_API PlanNode
+ {
+ enum class Op { SCAN };
+
+ Op op;
+ PlanNode* left = nullptr; /**< Left child (binary operators). */
+ PlanNode* right = nullptr; /**< Right child (binary operators). */
+
+ /** Cursor to scan. Set when op == SCAN. */
+ CursorManager::cursor* scan_cursor = nullptr;
+ };
+
class NT_API VM
{
+ public:
+ // TODO: CursorManager should be injected as a shared runtime instance,
+ // matching the pattern flagged for HandlerManager and LifecycleManager.
+ //
+ // A single CursorManager instance supports multiple simultaneous cursors —
+ // all iteration state lives in each cursor struct, not in the manager.
+ // A JOIN plan, for example, holds two independent cursors (one per SCAN leaf)
+ // and both are driven through the same CursorManager reference.
+ explicit VM(CursorManager& cursors);
+
+ /**
+ * @brief Pulls the next tuple from the plan tree (Tarski/FOL core).
+ *
+ * Propagates a Next() call down the operator tree. The call chain
+ * terminates at a SCAN node, which delegates to CursorManager.
+ *
+ * @param node Root of the plan subtree to evaluate.
+ * @return Next matching tuple, or nullptr when the plan is exhausted.
+ */
+ Tuple* Next(PlanNode* node);
+
+ private:
+ CursorManager& cursors_;
};
}