diff options
| author | eunhhu <[email protected]> | 2026-09-26 06:34:39 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-26 06:34:39 +0100 |
| commit | e7a2d8a6715ab48f887acfe1d14e32099e0ed7ff (patch) | |
| tree | d57e26614f5ffd4a996955ff24e4dc735f6bd510 /prototypes/connections/store-tree.c | |
| parent | 9408c57e0f2485fd7960135c931aa120dcb3fa8f (diff) | |
| download | pure-e7a2d8a6715ab48f887acfe1d14e32099e0ed7ff.tar.gz pure-e7a2d8a6715ab48f887acfe1d14e32099e0ed7ff.zip | |
Lend stored extents to reads instead of copying them
A read of a stored document now answers with the store mapping's extents
through writev, without copying the document. pure_draft_mapping takes a
reference to the mapping a draft opened through a handle reads from; the
answer keeps it until the last byte is sent, so the version read goes out
intact even if the document changes or a compaction replaces the file
meanwhile. Replies the mapping does not hold are copied as before.
pure-serve's output is now a list of extents (the head first). One thread
serves 2,761 1 MiB reads per second (axum: 1,380) and 128k small ones.
Diffstat (limited to 'prototypes/connections/store-tree.c')
| -rw-r--r-- | prototypes/connections/store-tree.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/prototypes/connections/store-tree.c b/prototypes/connections/store-tree.c index 5e15304..3163265 100644 --- a/prototypes/connections/store-tree.c +++ b/prototypes/connections/store-tree.c @@ -53,8 +53,9 @@ typedef struct { size_t size; /* leaf bytes, child count, or next free slot + 1 */ unsigned height; /* FREE for a reclaimed slot */ } Node; -/* One mapped version of the file, shared by the drafts of a store handle. */ -typedef struct { const unsigned char *map; uint64_t end; unsigned refs; } Mapping; +/* One mapped version of the file, shared by the drafts of a store handle + * and by whoever still sends extents from it. */ +typedef struct PureMapping { const unsigned char *map; uint64_t end; unsigned refs; } Mapping; typedef struct { const unsigned char *map; uint64_t end; @@ -1141,6 +1142,19 @@ void pure_store_close(PureStore *store) { free(store); } +PureMapping *pure_draft_mapping(const PureDraft *draft) { + Mapping *mapping = draft->tree.shared; + if (mapping) ++mapping->refs; + return mapping; +} + +bool pure_mapping_holds(const PureMapping *mapping, PureSpan span) { + uintptr_t base = (uintptr_t)mapping->map, at = (uintptr_t)span.data; + return !span.size || (span.data && at >= base && at - base <= mapping->end && span.size <= mapping->end - (at - base)); +} + +void pure_mapping_release(PureMapping *mapping) { release_mapping(mapping); } + PureResult pure_store_pin(PureStore *store, bool pinned) { store->pinned = false; PureResult result = pinned ? refresh(store) : PURE_OK; |
