aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/CursorManager.cpp45
-rw-r--r--src/HandlerManager.cpp35
-rw-r--r--src/LifecycleManager.cpp4
-rw-r--r--src/NT.cpp75
-rw-r--r--src/ObjectManager.cpp26
-rw-r--r--src/VM.cpp15
6 files changed, 181 insertions, 19 deletions
diff --git a/src/CursorManager.cpp b/src/CursorManager.cpp
index 8ae4496..f80ac54 100644
--- a/src/CursorManager.cpp
+++ b/src/CursorManager.cpp
@@ -1,5 +1,50 @@
#include "CursorManager.h"
+#include <numeric>
+
namespace nt
{
+ static std::string JoinPath(const std::vector<std::string>& path)
+ {
+ return std::accumulate(
+ std::next(path.begin()), path.end(), path.front(),
+ [](std::string a, const std::string& b) { return std::move(a) + "/" + b; });
+ }
+
+ CursorManager::cursor* CursorManager::Open(HandlerManager::handle* handle)
+ {
+ if (handle == nullptr || handle->object == nullptr)
+ return nullptr;
+
+ if (handle->object->head->type->label != RELATION)
+ return nullptr;
+
+ const std::string key = JoinPath(handle->object->head->path);
+ auto it = mock_store_.find(key);
+ if (it == mock_store_.end())
+ return nullptr;
+
+ auto* c = new cursor();
+ c->handle = handle;
+ for (const auto& row : it->second)
+ c->tuples.emplace_back(row);
+ return c;
+ }
+
+ Tuple* CursorManager::Next(cursor* cursor)
+ {
+ if (cursor == nullptr || cursor->position >= cursor->tuples.size())
+ return nullptr;
+ return &cursor->tuples[cursor->position++];
+ }
+
+ void CursorManager::Close(cursor* cursor)
+ {
+ delete cursor;
+ }
+
+ void CursorManager::MockInsert(std::vector<std::string> path, std::vector<Attribute> tuple)
+ {
+ mock_store_[JoinPath(path)].push_back(std::move(tuple));
+ }
}
diff --git a/src/HandlerManager.cpp b/src/HandlerManager.cpp
index 7d7015d..8149ff2 100644
--- a/src/HandlerManager.cpp
+++ b/src/HandlerManager.cpp
@@ -11,18 +11,24 @@ namespace nt
delete handle;
}
+ HandlerManager::HandlerManager(ObjectManager& objects,
+ PermissionsManager& permissions,
+ IdentityManager& identities,
+ LifecycleManager& lifecycles)
+ : objects_(objects)
+ , permissions_(permissions)
+ , identities_(identities)
+ , lifecycles_(lifecycles)
+ {}
+
struct HandlerManager::handle* HandlerManager::Open(std::vector<std::string> object_path, void* connection_context)
{
- ObjectManager objects;
- PermissionsManager permissions;
- IdentityManager identities;
- LifecycleManager lifecycles;
- ObjectManager::registry* retrieved_object = objects.Find((const std::vector<std::string>)object_path);
- if (permissions.Access(retrieved_object, (const void*)connection_context)
- && identities.CanOpen(retrieved_object)
- && lifecycles.Contention(retrieved_object)) {
+ ObjectManager::registry* retrieved_object = objects_.Find((const std::vector<std::string>)object_path);
+ if (permissions_.Access(retrieved_object, (const void*)connection_context)
+ && identities_.CanOpen(retrieved_object)
+ && lifecycles_.Contention(retrieved_object)) {
// Starts monitoring this guy
- lifecycles.Monitor(retrieved_object);
+ lifecycles_.Monitor(retrieved_object);
return new handle{ retrieved_object, connection_context }; // Return a successful handle
}
else {
@@ -36,22 +42,19 @@ namespace nt
if (handle == nullptr) {
return false;
}
- PermissionsManager permissions;
- IdentityManager identities;
- LifecycleManager lifecycles;
// Somehow grab the object pointer and connection (maybe drop it...) from the handle
ObjectManager::registry* object = handle->object;
void* connection_context = handle->connection_context;
// Checking for permissions here may be relevant.
// What if we have a handle but no permission? Spooky
- if (permissions.Access(object, connection_context)
- && identities.CanClose(object)
+ if (permissions_.Access(object, connection_context)
+ && identities_.CanClose(object)
// TODO: I think that in this case we do not need to worry about contention.
// But be careful to evaluate this scenario later.
- //&& LifecycleManager::Contention(retrieved_object)
+ //&& lifecycles_.Contention(object)
) {
// Stops monitoring this guy
- lifecycles.Unmonitor(object);
+ lifecycles_.Unmonitor(object);
DeallocateHandle(handle);
return true; // Return a successful handle
}
diff --git a/src/LifecycleManager.cpp b/src/LifecycleManager.cpp
index bcab4b5..a83c9e1 100644
--- a/src/LifecycleManager.cpp
+++ b/src/LifecycleManager.cpp
@@ -4,6 +4,8 @@ namespace nt
{
void LifecycleManager::Monitor(ObjectManager::registry* object)
{
+ if (object != nullptr)
+ ++object->head->handle_count;
}
const bool LifecycleManager::Contention(ObjectManager::registry* object)
@@ -13,5 +15,7 @@ namespace nt
void LifecycleManager::Unmonitor(ObjectManager::registry* object)
{
+ if (object != nullptr && object->head->handle_count > 0)
+ --object->head->handle_count;
}
}
diff --git a/src/NT.cpp b/src/NT.cpp
index 4d391a8..66752ef 100644
--- a/src/NT.cpp
+++ b/src/NT.cpp
@@ -1,6 +1,14 @@
#include "Runtime.h"
#ifdef NT_CONSOLE_APP
+#include "CursorManager.h"
+#include "HandlerManager.h"
+#include "IdentityManager.h"
+#include "LifecycleManager.h"
+#include "ObjectManager.h"
+#include "PermissionsManager.h"
+#include "VM.h"
+
#include <iostream>
#endif
@@ -21,13 +29,76 @@ int main()
{
const nt::NT runtime;
std::cout << "RNT running: " << (runtime.IsRunning() ? "yes" : "no") << '\n';
- const int exit_code = runtime.IsRunning() ? 0 : 1;
+
+ // --- Mock: register RelationX in the object registry ---
+ nt::ObjectManager objects;
+
+ auto type = std::make_unique<nt::ObjectManager::object_type>();
+ type->label = RELATION;
+ type->disposable = false;
+ type->methods = { OPEN, CLOSE };
+
+ objects.Register({ "RelationX" }, std::make_unique<nt::ObjectManager::Relation>(), std::move(type));
+
+ // --- Mock: populate the cursor store with three tuples ---
+ nt::CursorManager cursors;
+ cursors.MockInsert({ "RelationX" }, { { "name", "Alice" }, { "age", "30" } });
+ cursors.MockInsert({ "RelationX" }, { { "name", "Bob" }, { "age", "25" } });
+ cursors.MockInsert({ "RelationX" }, { { "name", "Carol" }, { "age", "35" } });
+
+ // --- Open a handle on RelationX through the full manager pipeline ---
+ nt::PermissionsManager permissions;
+ nt::IdentityManager identities;
+ nt::LifecycleManager lifecycles;
+ nt::HandlerManager handler(objects, permissions, identities, lifecycles);
+
+ int connection = 1; // dummy connection context
+ nt::HandlerManager::handle* handle = handler.Open({ "RelationX" }, &connection);
+ if (handle == nullptr)
+ {
+ std::cout << "Failed to open handle for RelationX\n";
+ return 1;
+ }
+
+ // --- Open a cursor on the relation ---
+ nt::CursorManager::cursor* cursor = cursors.Open(handle);
+ if (cursor == nullptr)
+ {
+ std::cout << "Failed to open cursor for RelationX\n";
+ handler.Close(handle);
+ return 1;
+ }
+
+ // --- Build a SCAN plan and pull all tuples lazily through the FOL VM ---
+ nt::PlanNode plan;
+ plan.op = nt::PlanNode::Op::SCAN;
+ plan.scan_cursor = cursor;
+
+ nt::VM vm(cursors);
+ std::cout << "Tuples in RelationX:\n";
+ while (nt::Tuple* t = vm.Next(&plan))
+ {
+ std::cout << " ";
+ const nt::Attribute* attr = t->Next();
+ while (attr != nullptr)
+ {
+ std::cout << attr->name << "=" << attr->value;
+ attr = t->Next();
+ if (attr != nullptr)
+ std::cout << ", ";
+ }
+ std::cout << '\n';
+ }
+
+ // --- Cleanup ---
+ cursors.Close(cursor);
+ handler.Close(handle);
#ifdef NT_WAIT_ON_EXIT
std::cout << "Press Enter to exit...";
std::cin.get();
#endif
- return exit_code;
+ return runtime.IsRunning() ? 0 : 1;
}
#endif
diff --git a/src/ObjectManager.cpp b/src/ObjectManager.cpp
index ff85af2..19f862d 100644
--- a/src/ObjectManager.cpp
+++ b/src/ObjectManager.cpp
@@ -2,8 +2,32 @@
namespace nt
{
- struct ObjectManager::registry* ObjectManager::Find(const std::vector<std::string> object_path)
+ void ObjectManager::Register(std::vector<std::string> path,
+ std::unique_ptr<IObject> object,
+ std::unique_ptr<object_type> type)
{
+ auto head = std::make_unique<registry_head>();
+ head->reference_count = 0;
+ head->handle_count = 0;
+ head->path = std::move(path);
+ head->type = std::move(type);
+
+ auto entry = std::make_unique<registry>();
+ entry->head = std::move(head);
+ entry->object = std::move(object);
+ entry->next = std::move(entries);
+ entries = std::move(entry);
+ }
+
+ ObjectManager::registry* ObjectManager::Find(const std::vector<std::string> object_path)
+ {
+ registry* current = entries.get();
+ while (current != nullptr)
+ {
+ if (current->head->path == object_path)
+ return current;
+ current = current->next.get();
+ }
return nullptr;
}
}
diff --git a/src/VM.cpp b/src/VM.cpp
index 4e69b8e..b5824d0 100644
--- a/src/VM.cpp
+++ b/src/VM.cpp
@@ -2,4 +2,19 @@
namespace nt
{
+ VM::VM(CursorManager& cursors) : cursors_(cursors) {}
+
+ Tuple* VM::Next(PlanNode* node)
+ {
+ if (node == nullptr)
+ return nullptr;
+
+ switch (node->op)
+ {
+ case PlanNode::Op::SCAN:
+ return cursors_.Next(node->scan_cursor);
+ }
+
+ return nullptr;
+ }
}