aboutsummaryrefslogtreecommitdiffstats
path: root/include/CursorManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/CursorManager.h')
-rw-r--r--include/CursorManager.h85
1 files changed, 38 insertions, 47 deletions
diff --git a/include/CursorManager.h b/include/CursorManager.h
index 78ea24c..5636d8d 100644
--- a/include/CursorManager.h
+++ b/include/CursorManager.h
@@ -2,10 +2,10 @@
#include "Api.h"
#include "HandlerManager.h"
+#include "IStorageBackend.h"
#include "Types.h"
-#include <string>
-#include <unordered_map>
+#include <cstddef>
#include <vector>
/**
@@ -17,55 +17,54 @@ namespace nt
{
/**
* @class CursorManager
- * @brief Orchestrates data pagination from storage backends to the query executor.
+ * @brief Orchestrates paginated data retrieval from a storage backend.
*
- * The cursor manager is the glue between registry objects and the
- * Volcano-style iterator model. It translates high-level plan requests into
- * low-level backend operations such as LMDB or etcd reads.
+ * CursorManager depends only on IStorageBackend. The concrete backend
+ * (SqliteBackend, InMemoryBackend, …) is injected at construction time.
*
- * Responsibilities:
- * - Snapshot anchoring and pins: bind retrieval to a multigroup snapshot.
- * The snapshot object should hold the reference to the tree containing
- * all relations and tuples.
- *
- * - State maintenance: track the current iterator or offset inside a
- * relation to support sequential Next() calls from the algebra engine.
- *
- * - Prefetching and buffering: abstract backend paging. For remote
- * backends like etcd, manage local buffers to hide latency from the
- * executor. Think of this as a database equivalent of an operating-system
- * driver.
- *
- * - Boundary enforcement: ensure scans do not cross commit boundaries or
- * logical branch definitions unless explicitly requested by the plan.
+ * 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.
*/
class NT_API CursorManager
{
public:
- /** @brief Active scan state for a single relation. */
+ static constexpr std::size_t PAGE_SIZE = 1;
+
+ /** @brief Constructs a CursorManager that reads from the given backend. */
+ explicit CursorManager(IStorageBackend& backend);
+
+ /**
+ * @brief Active scan state for a single relation.
+ *
+ * Holds one page of deserialized tuples at a time. When page_position
+ * reaches the end of the page, Next() discards the page and fetches
+ * the next one from the backend.
+ *
+ * The pointer returned by Next() is valid only until the next Next()
+ * or Close() call — a page replacement invalidates all prior pointers.
+ */
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;
+ HandlerManager::handle* handle = nullptr;
+ std::vector<Tuple> page;
+ std::size_t page_position = 0;
+ std::size_t fetch_offset = 0; // next TupleHashes() call starts here
+ bool exhausted = false;
};
/**
* @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.
+ *
+ * Fetches the first page immediately. Returns nullptr if the relation
+ * has no tuples or the handle does not refer to 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.
+ * Fetches the next page from the backend transparently when the
+ * current page is exhausted. Returns nullptr when all pages are done.
*/
Tuple* Next(cursor* cursor);
@@ -75,19 +74,11 @@ namespace nt
*/
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_;
+ 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);
};
}