aboutsummaryrefslogtreecommitdiffstats
path: root/include/CursorManager.h
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-05-13 01:59:22 -0300
committerGitHub <noreply@github.com>2026-05-13 01:59:22 -0300
commitaf6073dedffd1a16aff7a283ded50545dc40b179 (patch)
treea4b8fbfb4842f5ac27bf7fa641555de3fac6b7f3 /include/CursorManager.h
parentc1b70cfe745d935bded3053fba8c1f9573aa07aa (diff)
downloadRNT-af6073dedffd1a16aff7a283ded50545dc40b179.tar.gz
RNT-af6073dedffd1a16aff7a283ded50545dc40b179.zip
Extern handles for embedded runtime
Diffstat (limited to 'include/CursorManager.h')
-rw-r--r--include/CursorManager.h40
1 files changed, 33 insertions, 7 deletions
diff --git a/include/CursorManager.h b/include/CursorManager.h
index 092229c..839bf5e 100644
--- a/include/CursorManager.h
+++ b/include/CursorManager.h
@@ -6,6 +6,7 @@
#include "Types.h"
#include <cstddef>
+#include <string>
#include <vector>
/**
@@ -25,6 +26,11 @@ namespace nt
* Tuples are never loaded all at once. Open() fetches the first page;
* each subsequent Next() call transparently fetches the next page from
* the backend once the current page is exhausted.
+ *
+ * Pagination is driven by the Merkle B-tree: each cursor carries the hex
+ * hash of the relation's Merkle root at open time, and LoadPage calls
+ * Merkle::Page(backend, merkle_root, fetch_offset, PAGE_SIZE) to retrieve
+ * the next page of tuple hashes without loading sibling subtrees.
*/
class NT_API CursorManager
{
@@ -43,10 +49,19 @@ namespace nt
*
* The pointer returned by Next() is valid only until the next Next()
* or Close() call — a page replacement invalidates all prior pointers.
+ *
+ * merkle_root is seeded from ObjectManager::Relation::merkle_root at
+ * open time and does not change during iteration; the cursor reads the
+ * snapshot captured when it was opened.
*/
struct cursor {
HandlerManager::handle* handle = nullptr;
/**
+ * Hex hash of the relation's Merkle B-tree root node.
+ * Empty string means the relation contains no tuples.
+ */
+ std::string merkle_root;
+ /**
* Bound argument values for EPHEMERAL_RELATION cursors.
* Written by the JOIN operator before each probe; ignored for
* stored RELATION cursors.
@@ -54,17 +69,24 @@ namespace nt
std::vector<std::string> args;
std::vector<Tuple> page;
std::size_t page_position = 0;
- std::size_t fetch_offset = 0; // next TupleHashes() call starts here
+ std::size_t fetch_offset = 0; // next Merkle::Page() call starts here
bool exhausted = false;
};
/**
* @brief Opens a cursor on the relation referenced by the handle.
*
- * Fetches the first page immediately. Returns nullptr if the relation
- * has no tuples or the handle does not refer to a RELATION.
+ * Fetches the first page immediately for non-empty relations. Returns
+ * a valid exhausted cursor when @p merkle_root is empty (empty relation).
+ * Returns nullptr when the handle does not refer to a RELATION or
+ * EPHEMERAL_RELATION.
+ *
+ * @param handle Open RELATION or EPHEMERAL_RELATION handle.
+ * @param merkle_root Hex hash of the relation's Merkle root at open
+ * time. Ignored for EPHEMERAL_RELATION handles.
*/
- cursor* Open(HandlerManager::handle* handle);
+ cursor* Open(HandlerManager::handle* handle,
+ const std::string& merkle_root = "");
/**
* @brief Pulls the next tuple from the cursor.
@@ -83,8 +105,12 @@ namespace nt
private:
IStorageBackend& backend_;
- /** Fetches a page of hashes, resolves each from the KV store, and
- * deserializes them into cursor->page. Clears the existing page. */
- void LoadPage(cursor* c, const std::vector<std::string>& path);
+ /**
+ * Fetches a page of hashes via Merkle::Page, resolves each from the
+ * KV store, and deserializes them into cursor->page. Clears the
+ * existing page. Advances fetch_offset by the number of hashes
+ * returned; sets exhausted when fewer than PAGE_SIZE hashes come back.
+ */
+ void LoadPage(cursor* c);
};
}