Skip to content

Commit f241f6b

Browse files
author
Julian
committed
feat(snapshot): add container hash map
store a container hash map in side the snapshot to map offsets in an migartion attemp BREAKING CHANGE: issue #112
1 parent 08d6f03 commit f241f6b

File tree

5 files changed

+47
-26
lines changed

5 files changed

+47
-26
lines changed

inkcpp/include/snapshot.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace ink::runtime
2626
class snapshot
2727
{
2828
public:
29-
virtual ~snapshot(){};
29+
virtual ~snapshot() {};
3030

3131
/** Construct snapshot from blob.
3232
* Memory must be kept valid until the snapshot is deconstructed.
@@ -39,13 +39,13 @@ class snapshot
3939
static snapshot* from_binary(const unsigned char* data, size_t length, bool freeOnDestroy = true);
4040

4141
/** access blob inside snapshot */
42-
virtual const unsigned char* get_data() const = 0;
42+
virtual const unsigned char* get_data() const = 0;
4343
/** size of blob inside snapshot */
44-
virtual size_t get_data_len() const = 0;
44+
virtual size_t get_data_len() const = 0;
4545
/** number of runners which are stored inside this snapshot */
46-
virtual size_t num_runners() const = 0;
46+
virtual size_t num_runners() const = 0;
4747
/** hash of story to check for story changes on load. */
48-
virtual hash_t get_story_hash() const = 0;
48+
virtual hash_t get_story_hash() const = 0;
4949

5050
#ifdef INK_ENABLE_STL
5151
/** deserialize snapshot from file.

inkcpp/snapshot_impl.cpp

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@ void snapshot::write_to_file(const char* filename) const
5454

5555
namespace ink::runtime::internal
5656
{
57-
size_t snapshot_impl::file_size(size_t serialization_length, size_t runner_cnt)
57+
size_t
58+
snapshot_impl::file_size(size_t serialization_length, size_t runner_cnt, size_t num_container)
5859
{
59-
return serialization_length + sizeof(header) + (runner_cnt + 1) * sizeof(size_t);
60+
return serialization_length + sizeof(header) + (runner_cnt + 1 + 1) * sizeof(uint32_t)
61+
+ num_container * sizeof(uint32_t) * 3;
6062
}
6163

6264
const unsigned char* snapshot_impl::get_data() const { return _file; }
@@ -67,7 +69,8 @@ snapshot_impl::snapshot_impl(const globals_impl& globals)
6769
: _managed{true}
6870
{
6971
snapshot_interface::snapper snapper{globals.strings(), globals._owner->string(0)};
70-
_length = globals.snap(nullptr, snapper);
72+
_length = 0;
73+
_length += globals.snap(nullptr, snapper);
7174
size_t runner_cnt = 0;
7275
for (auto node = globals._runners_start; node; node = node->next) {
7376
_length += node->object->snap(nullptr, snapper);
@@ -77,19 +80,24 @@ snapshot_impl::snapshot_impl(const globals_impl& globals)
7780
runner_cnt > 0,
7881
"No runner assoziated with global you want to snap. This will just store the initial state."
7982
);
80-
_length = file_size(_length, runner_cnt);
81-
_header.story_hash = globals._runners_start->object->_story->get_hash();
82-
_header.length = _length;
83-
_header.num_runners = runner_cnt;
84-
unsigned char* data = new unsigned char[_length];
85-
_file = data;
86-
unsigned char* ptr = data;
83+
const story_impl* story = globals._runners_start->object->_story;
84+
_header.num_container = (story->_container_hash_end - story->_container_hash_start) / 2;
85+
_length = file_size(_length, runner_cnt, _header.num_container);
86+
_header.story_hash = story->get_hash();
87+
_header.length = _length;
88+
_header.num_runners = runner_cnt;
89+
unsigned char* data = new unsigned char[_length];
90+
_file = data;
91+
unsigned char* ptr = data;
8792
// write header
8893
memcpy(ptr, &_header, sizeof(_header));
8994
// write lookup table
9095
ptr += sizeof(header);
9196
{
92-
size_t offset = (ptr - data) + (_header.num_runners + 1) * sizeof(size_t);
97+
uint32_t offset = (ptr - data) + (_header.num_runners + 1 + 1) * sizeof(uint32_t);
98+
memcpy(ptr, &offset, sizeof(offset));
99+
ptr += sizeof(offset);
100+
offset += _header.num_container * sizeof(uint32_t) * 3;
93101
memcpy(ptr, &offset, sizeof(offset));
94102
ptr += sizeof(offset);
95103
offset += globals.snap(nullptr, snapper);
@@ -100,6 +108,21 @@ snapshot_impl::snapshot_impl(const globals_impl& globals)
100108
}
101109
}
102110

111+
uint32_t container_value;
112+
for (size_t i = 0; i < _header.num_container; ++i) {
113+
container_value = story->_container_hash_start[i * 2];
114+
memcpy(ptr, &container_value, sizeof(container_value));
115+
ptr += sizeof(container_value);
116+
container_value = story->_container_hash_start[i * 2 + 1];
117+
memcpy(ptr, &container_value, sizeof(container_value));
118+
ptr += sizeof(container_value);
119+
if (!story->get_container_id(story->_container_hash_start[i * 2 + 1] + story->instructions(), container_value)) {
120+
container_value = ~0;
121+
}
122+
memcpy(ptr, &container_value, sizeof(container_value));
123+
ptr += sizeof(container_value);
124+
}
125+
103126
ptr += globals.snap(ptr, snapper);
104127
for (auto node = globals._runners_start; node; node = node->next) {
105128
ptr += node->object->snap(ptr, snapper);

inkcpp/snapshot_impl.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,20 +104,22 @@ class snapshot_impl : public snapshot
104104
const unsigned char* _file;
105105
size_t _length;
106106
bool _managed;
107-
static size_t file_size(size_t, size_t);
107+
static size_t file_size(size_t, size_t, size_t);
108108

109109
struct header {
110110
const char* magic_sequence = "INKCPP_SNAP";
111111
const char version[3] = {config::version[0], config::version[1], config::version[2]};
112112
hash_t story_hash;
113-
size_t num_runners;
114-
size_t length;
113+
uint32_t num_runners;
114+
uint32_t num_container;
115+
uint32_t length;
115116
} _header;
116117

117118
size_t get_offset(size_t idx) const
118119
{
120+
// 0 - container hashes, 1 - globals, 2 + runner
119121
inkAssert(idx <= _header.num_runners, "Out of Bound access for runner in snapshot.");
120-
return reinterpret_cast<const size_t*>(_file + sizeof(header))[idx];
122+
return reinterpret_cast<const uint32_t*>(_file + sizeof(header))[idx + 1];
121123
}
122124
};
123125
} // namespace ink::runtime::internal

inkcpp/story_impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace ink::runtime::internal
1919
// Ink story. Constant once constructed. Can be shared safely between multiple runner instances
2020
class story_impl : public story
2121
{
22+
friend snapshot_impl;
2223
public:
2324
#ifdef INK_ENABLE_STL
2425
story_impl(const char* filename);
@@ -83,7 +84,7 @@ class story_impl : public story
8384
uint32_t _container_list_size;
8485
uint32_t _num_containers;
8586

86-
// container hashes
87+
// container hashes (hash,offset)
8788
hash_t* _container_hash_start;
8889
hash_t* _container_hash_end;
8990

inkcpp_compiler/binary_emitter.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@
1212

1313
#include <vector>
1414
#include <map>
15-
#include <fstream>
16-
17-
#ifndef WIN32
18-
# include <cstring>
19-
#endif
2015

2116
namespace ink::compiler::internal
2217
{

0 commit comments

Comments
 (0)