Commit Graph

15 Commits

Author SHA1 Message Date
Benjamin Bouvier
d66733052a feat(event cache): add indexes for finding related events 2025-08-26 16:25:56 +02:00
Ivan Enderlin
6f42210d6a feat(sqlite): Improve throughput of load_all_chunks_metadata by 1140%.
This patch changes the query used by
`SqliteEventCacheStore::load_all_chunks_metadata`. It was the cause of
severe slowness. The new query improves the throughput by +1140% and the
time by -91.916%. The benchmark will follow in the next patch.

Metrics for 10'000 events (with 1 gap every 80 events).

- Before:
  - throughput: 20.686 Kelem/s,
  - time: 483.43 ms.
- After:
  - throughput: 253.52 Kelem/s,
  - time: 39.478 ms.

This query will visit all chunks of a linked chunk with ID
`hashed_linked_chunk_id`. For each chunk, it collects its ID
(`ChunkIdentifier`), previous chunk, next chunk, and number of
events (`num_events`). If it's a gap, `num_events` is equal to 0,
otherwise it counts the number of events in `event_chunks` where
`event_chunks.chunk_id = linked_chunks.id`.

Why not using a `(LEFT) JOIN` + `COUNT`? Because for gaps, the entire
`event_chunks` will be traversed every time. It's extremely inefficient.
To speed that up, we could use an `INDEX` but it will consume more
storage space. Finally, traversing an `INDEX` boils down to traverse a
B-tree, which is O(log n), whilst this `CASE` approach is O(1). This
solution is nice trade-off and offers great performance.
2025-07-21 10:31:44 +02:00
Benjamin Bouvier
ebcb74a86d refactor!(event cache): introduce LinkedChunkId in the backends (#5182)
In a "soon" future, threads have their own linked chunk. All our code
has been written with the fact that a linked chunk belong to *a room* in
mind, so it needs some biggish update. Fortunately, most of the changes
are mechanical, so they should be rather easy to review.

Part of #4869, namely #5122.
2025-06-09 13:26:46 +00:00
Benjamin Bouvier
d30dc7177f refactor(sqlite): rename gaps to gap_chunks / events_chunks to event_chunks
And some comments have been tweaked too.
2025-04-02 13:26:15 +02:00
Benjamin Bouvier
45f1dca6a3 refactor(event cache): don't return a position in find_event
Getting the position when reading an event is no longer required:

- the only use case for reading the position out of the event cache was
when we wanted to replace a redacted item into the linked chunk; now
with save_event(), we can replace it without having to know its
position.

As an extra measure of caution, I've also included the room_id in the
`events` table, next to the event_id, so that looking for an event is
still restricted to a single room.
2025-04-02 13:26:15 +02:00
Benjamin Bouvier
03f5d0222e refactor(event cache): store the events' content independently of their position in a chunk 2025-04-02 13:26:15 +02:00
Ivan Enderlin
3d653d3fdc fix(sqlite): Design a new schema to get faster insertions.
This patch is twofold. First off, it provides a new schema allowing to
improve the performance of `SqliteEventCacheStore` for 100_000 events
from 6.7k events/sec to 284k events/sec on my machine.

Second, it now assumes that `EventCacheStore` does NOT store invalid
events. It was already the case, but the SQLite schema was not rejecting
invalid event in case some were handled. It's now explicitely forbidden.
2025-03-05 13:57:08 +01:00
Ivan Enderlin
6c57003d17 feat(sqlite) Add an index on events.event_id and .room_id.
This patch adds an index on `events.event_id` and on `events.room_id`
so that queries on this column are faster. It mostly happens for the
`Deduplicator`, which runs for every backwards pagination or sync.

This patch also updates the query in `filter_duplicated_events` to
sort event by their `chunk_id` and `position` so that the results are
constant, it helps when testing.
2025-02-19 11:50:23 +01:00
Kévin Commaille
df9c355aed Merge branch 'main' into media-retention-policy
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-01-28 15:46:55 +01:00
Kévin Commaille
8ca5983093 feat(sqlite): Implement EventCacheStoreMedia for SqliteEventCacheStore
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-01-28 15:38:18 +01:00
Benjamin Bouvier
3428494468 refactor: rename SyncTimelineEvent to TimelineEvent 2025-01-22 20:24:48 +01:00
Benjamin Bouvier
9ed65bc321 task(event cache): address review points 2024-11-28 11:48:46 +01:00
Benjamin Bouvier
9bea0cff24 feat(event cache): implement the sqlite backend for events 2024-11-28 11:48:46 +01:00
Ivan Enderlin
37304c8cdc refactor: Implement try_take_leased_lock on SqliteEventCacheStore 2024-11-06 15:03:50 +01:00
Kévin Commaille
01e2db1f52 base: Move media cache to new EventCacheStore trait (#3858)
Allows to save media in a different path than the state store.

This adds a "last_access" field to the SQLite implementation, to prepare
for future work on a media retention policy.

This removes the IndexedDB media cache implementation, because as far as
I know it is currently unused, and I have no idea how to implement
efficiently the planned media retention policy with a key-value store.

Closes #1810.

- [x] Public API changes documented in changelogs (optional)

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2024-08-22 10:36:43 +02:00