-
Notifications
You must be signed in to change notification settings - Fork 0
Scratch
Orbit scratch provides a group of abstract data types. It is the built-in APIs to send and apply updates, operations, or send arbitrary data in orbit. A scratch is typically backed by an orbit pool as underlying storage, and then be transferred by transferring the pool pages containing that scratch.
On the other hand, users can also choose not to use orbit scratch, and write their own data representations to be sent through orbit pool.
A scratch works like vector<variant<update_t, operation_t, any_t>>
.
Currently scratch requires using orbit pool as the storage back end. Thus, before creating a scratch, user need to first set the pool to use for scratch creation. The pool mode typically use ORBIT_MOVE
. In this mode, the sent scratch will no longer be accessible in the orbit.
int orbit_scratch_set_pool(struct orbit_pool *pool);
int orbit_scratch_create(struct orbit_scratch *s);
TODO: When the pool is used up, how to request for more space for scratch. We used to have auto mmap, but now scratch require explicitly setting pool to use.
Scratch allows encoding a sequence of updates, operations, and arbitrary data in one scratch.
A struct to represent an update with dynamically-sized data
. It contains a pointer to the data to be updated, the length of the data and the data to update to. Before calling this API, user is expected to update the state pointed by the ptr
. The API will then copy the data from the ptr
in orbit.
struct orbit_update {
void *ptr;
size_t length;
char data[];
};
int orbit_scratch_push_update(struct orbit_scratch *s, void *ptr, size_t length);
A struct to represent a function call with dynamic-sized argv
. It contains a function pointer and a list of arguments to the function call.
TODO: Currently each argument must be unsigned long. Probably using entry_func
style argument struct wrapper would be better.
typedef unsigned long(*orbit_operation_func)(size_t, unsigned long[]);
struct orbit_operation {
orbit_operation_func func;
size_t argc;
unsigned long argv[]; /* `void*` type argument */
};
int orbit_scratch_push_operation(struct orbit_scratch *s,
orbit_operation_func func, size_t argc, unsigned long argv[]);
A dynamically-sized struct to represent arbitrary data. User can use this record for any purpose. For example, it can be used to store some information that can be later used for stale checks.
The API accepts a pointer and length, and it will copy the data pointed by the pointer to an orbit_any
record in scratch.
struct orbit_any {
unsigned long length;
char data[];
};
int orbit_scratch_push_any(struct orbit_scratch *s, void *ptr, size_t length);
In some cases, the data in orbit_any
could be complex structured data with lots of pointers. It would become very complicated to use linear data copy API push_any
to create such data structure in orbit_any
. In such cases, user can use the allocator APIs to directly change the location of the data at creation. See allocator documentation.
Orbit scratch provides several APIs to apply or iterate through each records.
TBA
struct orbit_repr {
enum orbit_type type;
/* Maybe consider type safety of this union? */
union {
struct orbit_update update;
struct orbit_operation operation;
struct orbit_any any;
};
};
enum orbit_type orbit_apply(struct orbit_scratch *s, bool yield);
enum orbit_type orbit_apply_one(struct orbit_scratch *s, bool yield);
enum orbit_type orbit_skip(struct orbit_scratch *s, bool yield);
enum orbit_type orbit_skip_one(struct orbit_scratch *s, bool yield);
struct orbit_repr *orbit_scratch_first(struct orbit_scratch *s);
struct orbit_repr *orbit_scratch_next(struct orbit_scratch *s);