aboutsummaryrefslogtreecommitdiffstats
path: root/core/module.h
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-29 06:35:05 +0100
committereunhhu <[email protected]>2026-09-29 06:35:05 +0100
commitc8f0704b6f88f331be24a89df7d7cb6a4bf29164 (patch)
treeeb47503b5dd08e1d993b3c81eb06b37b608166d6 /core/module.h
parentc97e4e1a203d13852d5f7cd4a404f88b44f4064f (diff)
downloadpure-c8f0704b6f88f331be24a89df7d7cb6a4bf29164.tar.gz
pure-c8f0704b6f88f331be24a89df7d7cb6a4bf29164.zip
Keep the outbox as a list: a save logs only the sends and trims it made
The sends not yet trimmed were written whole into the links value at every save, as the numbers heard were: a sender whose receiver is away or slow saved all its waiting sends again with each new one. They are now a runtime list {output (its name), seq, payload}, in the order sent, stored as a list state is (image "0sent" and its changes in the log). A send is a change of the list with its event; a trim lets the sends go at once and a failed save brings them back; the host sees the saved ones (sent_saved). Outputs are named in the items, so a module replaced keeps them without moving anything; one that lacks or changed an output with sends left is refused as before. Links stored before (PLK1, PLK2) move their sends to the list at a start and are stored again without them (PLK3). A list field may now hold any bytes (kind 2), unchecked, besides a number and a UTF-8 text. Saving 5,000 sends of 16 KB one by one took 84.8 s and left a store of 400 MB; now 0.91 s and 144 MB. 20,000 of 61 bytes: 8.4 s, now 2.9 s.
Diffstat (limited to 'core/module.h')
-rw-r--r--core/module.h28
1 files changed, 16 insertions, 12 deletions
diff --git a/core/module.h b/core/module.h
index 8176bea..3431c87 100644
--- a/core/module.h
+++ b/core/module.h
@@ -263,8 +263,9 @@ typedef struct { unsigned char *bytes; size_t used, capacity; } PureArena;
* at once and a host saves a burst with one commit: an event is durable once
* a later save succeeds, and each key's document joins a burst once (a second
* message for it, or one past PURE_APP_PENDING keys, saves the burst first). */
-/* The heard list's place among the stored lists' records (PureApp). */
-enum { PURE_LIST_HEARD = PURE_MODULE_STATES };
+/* The runtime's lists' places among the stored lists' records (PureApp):
+ * the numbers heard, and the outbox. */
+enum { PURE_LIST_HEARD = PURE_MODULE_STATES, PURE_LIST_OUTBOX, PURE_LISTS_STORED };
typedef struct {
const PureModule *module;
PureData data;
@@ -273,13 +274,13 @@ typedef struct {
PureList *lists[PURE_MODULE_STATES];
PureUndo undo; /* list changes of the current event */
PureDraft *list_drafts[PURE_MODULE_STATES]; /* lists the tree kept before images, until emptied */
- /* Stored lists (module-save.c), by state, and the heard list's last
- * (PURE_LIST_HEARD): the save each one's image holds, the first save
+ /* Stored lists (module-save.c), by state, then the runtime's (the heard
+ * list and the outbox): the save each one's image holds, the first save
* logged since that changed it (0: none), and the bytes of its changes
* logged since; the log, the tree's number of its last save, the last
* save's number, and a checkpoint being written. */
- uint64_t image_seq[PURE_MODULE_STATES + 1], logged_since[PURE_MODULE_STATES + 1];
- size_t logged[PURE_MODULE_STATES + 1];
+ uint64_t image_seq[PURE_LISTS_STORED], logged_since[PURE_LISTS_STORED];
+ size_t logged[PURE_LISTS_STORED];
struct PureLog *log;
PureDraft *stored_seq;
uint64_t seq;
@@ -320,12 +321,15 @@ typedef struct {
unsigned char *copied;
int64_t revision;
PureArena arena, view_arena;
- /* Links (runtime-owned, saved with the states): messages sent on outputs
- * and not trimmed, in the order sent (the first sent_durable are saved;
- * a trimmed one goes at the next save), each output's last number (and
- * as saved), and those of outputs a module dropped. */
- struct PureSent { uint32_t output; uint64_t seq; unsigned char *payload; size_t size; bool trimmed; } *sent;
- size_t sent_count, sent_capacity, sent_durable;
+ /* Links (runtime-owned, saved with the states): the outbox, messages sent
+ * on outputs and not trimmed, in the order sent, a list of {output (its
+ * name), seq, payload (bytes)} stored as a list state is (module-save.c)
+ * and changed with the events that send (the first sent_saved are saved:
+ * the host sees only those; a trim lets go at once, and a failed save
+ * takes it back); each output's last number (and as saved), and those of
+ * outputs a module dropped. */
+ PureList *outbox;
+ size_t sent_saved, durable_sent_saved, durable_outbox;
uint64_t last_sent[PURE_MODULE_INPUTS], saved_sent[PURE_MODULE_INPUTS];
struct PureCarried { char name[PURE_MODULE_NAME]; uint64_t last; } *carried;
unsigned carried_count;