blob: 91a0183f41dd15e3e8f99e04cecca2d0091d2042 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include "CursorManager.h"
#include "ObjectManager.h"
#include "TupleCodec.h"
namespace nt
{
CursorManager::CursorManager(IStorageBackend& backend)
: backend_(backend)
{}
void CursorManager::LoadPage(cursor* c, const std::vector<std::string>& path)
{
auto hashes = backend_.TupleHashes(path, c->fetch_offset, PAGE_SIZE);
c->page.clear();
c->page_position = 0;
for (const auto& hash : hashes)
{
auto bytes = backend_.Get(hash);
if (!bytes) continue;
c->page.emplace_back(TupleCodec::Deserialize(*bytes));
}
c->fetch_offset += hashes.size();
if (hashes.size() < PAGE_SIZE)
c->exhausted = true;
}
CursorManager::cursor* CursorManager::Open(HandlerManager::handle* handle)
{
if (handle == nullptr || handle->object == nullptr)
return nullptr;
const auto label = handle->object->head->type->label;
if (label == EPHEMERAL_RELATION)
{
// Cursor is created exhausted — the JOIN operator writes args and
// resets the state before the first probe.
auto* c = new cursor();
c->handle = handle;
c->exhausted = true;
return c;
}
if (label != RELATION)
return nullptr;
auto* c = new cursor();
c->handle = handle;
LoadPage(c, handle->object->head->path);
if (c->page.empty())
{
delete c;
return nullptr;
}
return c;
}
Tuple* CursorManager::Next(cursor* c)
{
if (c == nullptr) return nullptr;
if (c->page_position < c->page.size())
return &c->page[c->page_position++];
if (c->exhausted) return nullptr;
if (c->handle->object->head->type->label == EPHEMERAL_RELATION)
{
auto* etype = static_cast<ObjectManager::ephemeral_object_type*>(
c->handle->object->head->type.get());
c->page = etype->generator(c->args, c->fetch_offset, PAGE_SIZE);
c->page_position = 0;
c->fetch_offset += c->page.size();
if (c->page.size() < PAGE_SIZE)
c->exhausted = true;
if (c->page.empty()) return nullptr;
return &c->page[c->page_position++];
}
LoadPage(c, c->handle->object->head->path);
if (c->page.empty()) return nullptr;
return &c->page[c->page_position++];
}
void CursorManager::Close(cursor* c)
{
delete c;
}
}
|