Skip to main content

tuwunel_database/
maps.rs

1//! Column family descriptors used by the homeserver database.
2//!
3//! The catalog names every configured map and supplies its RocksDB tuning
4//! profile. Database startup opens these descriptors as one coherent
5//! collection.
6
7use std::{collections::BTreeMap, sync::Arc};
8
9use rocksdb::DBCompressionType as CompressionType;
10use tuwunel_core::Result;
11
12// The descriptor aliases keep this file's other qualified descriptor
13// spellings clean under unused_qualifications.
14use crate::{
15	Engine, Map,
16	engine::descriptor::{
17		self, CacheDisp, DROPPED as LEGACY_AUTH_CHAIN_DESCRIPTOR, Descriptor,
18		RANDOM_SMALL as PRIVATE_READ_SYNC_DESCRIPTOR,
19		RANDOM_SMALL_CACHE as THREEPID_SESSION_DESCRIPTOR,
20	},
21};
22
23/// Indexes opened logical maps by column-family name.
24///
25/// Keys are static names from the descriptor catalog, and values share each
26/// opened [`Map`] through an `Arc`. Dropped or unavailable families are absent.
27pub(super) type Maps = BTreeMap<MapsKey, MapsVal>;
28
29/// Names a column family in the map catalog.
30///
31/// Catalog names have static lifetime because descriptors are process-wide
32/// constants.
33pub(super) type MapsKey = &'static str;
34
35/// Holds a shared logical map opened from a catalog descriptor.
36///
37/// The shared handle keeps the map and its database engine alive for every
38/// service that uses the catalog entry.
39pub(super) type MapsVal = Arc<Map>;
40
41/// Opens every configured map in the built-in catalog.
42///
43/// The returned index contains only descriptors that are live and present in
44/// the opened database. Individual map handles share the supplied engine.
45pub(super) fn open(engine: &Arc<Engine>) -> Result<Maps> { open_list(engine, MAPS) }
46
47/// Opens maps from an explicit descriptor list.
48///
49/// Dropped descriptors and column families missing from the engine are skipped.
50/// Any failure to open a retained map aborts construction of the index.
51#[tracing::instrument(name = "maps", level = "debug", skip_all)]
52pub(super) fn open_list(engine: &Arc<Engine>, maps: &[Descriptor]) -> Result<Maps> {
53	maps.iter()
54		.filter(|desc| !desc.dropped)
55		.filter(|desc| engine.has_cf(desc.name))
56		.map(|desc| Ok((desc.name, Map::open(engine, desc.name)?)))
57		.collect()
58}
59
60/// Defines the built-in column-family catalog and its RocksDB tuning.
61///
62/// Each descriptor names one logical map and inherits a workload preset with
63/// optional per-map overrides. Dropped descriptors remain as migration
64/// tombstones but are not opened for use.
65pub(super) static MAPS: &[Descriptor] = &[
66	Descriptor {
67		name: "alias_roomid",
68		..descriptor::RANDOM_SMALL
69	},
70	Descriptor {
71		name: "alias_userid",
72		..descriptor::RANDOM_SMALL
73	},
74	Descriptor {
75		name: "aliasid_alias",
76		..descriptor::RANDOM_SMALL
77	},
78	Descriptor {
79		name: "authchainkey_authchain",
80		cache_disp: CacheDisp::Unique, // fork-resolve bursts would evict the shared pool
81		compression: CompressionType::None,
82		cache_shards: 32,
83		index_size: 1024,
84		block_size: 4096,
85		key_size_hint: Some(8),
86		val_size_hint: Some(256),
87		limit_size: 1024 * 1024 * 1024 * 4,
88		..descriptor::RANDOM_CACHE
89	},
90	Descriptor {
91		name: "backupid_algorithm",
92		..descriptor::RANDOM_SMALL
93	},
94	Descriptor {
95		name: "backupid_etag",
96		..descriptor::RANDOM_SMALL
97	},
98	Descriptor {
99		name: "backupkeyid_backup",
100		..descriptor::RANDOM_SMALL
101	},
102	Descriptor {
103		name: "bannedroomids",
104		..descriptor::RANDOM_SMALL
105	},
106	Descriptor {
107		name: "disabledroomids",
108		..descriptor::RANDOM_SMALL
109	},
110	Descriptor {
111		name: "email_userid",
112		..descriptor::RANDOM_SMALL
113	},
114	Descriptor {
115		name: "eventid_backoff",
116		cache_disp: CacheDisp::Unique, // hot on every redelivery
117		key_size_hint: Some(64),
118		val_size_hint: Some(16),
119		ttl: 60 * 60 * 24 * 3, // dead after the max fetch-backoff window (24h)
120		..descriptor::RANDOM_SMALL_CACHE
121	},
122	Descriptor {
123		name: "eventid_originalpdu",
124		key_size_hint: Some(48),
125		val_size_hint: Some(1520),
126		block_size: 2048,
127		index_size: 512,
128		..descriptor::RANDOM
129	},
130	Descriptor {
131		name: "eventid_outlierpdu",
132		cache_disp: CacheDisp::SharedWith("pduid_pdu"),
133		key_size_hint: Some(48),
134		val_size_hint: Some(1488),
135		block_size: 1024,
136		index_size: 512,
137		..descriptor::RANDOM
138	},
139	Descriptor {
140		name: "eventid_pduid",
141		cache_disp: CacheDisp::Unique,
142		key_size_hint: Some(48),
143		val_size_hint: Some(16),
144		block_size: 512,
145		index_size: 512,
146		..descriptor::RANDOM
147	},
148	Descriptor {
149		name: "eventid_policysigstate",
150		ttl: 60 * 60 * 24 * 7, // backoff/refusal hint; re-ask fails open
151		..descriptor::RANDOM_SMALL_CACHE
152	},
153	Descriptor {
154		name: "eventid_resolvedstate",
155		ttl: 60 * 60 * 24 * 7, // refetch-avoidance only; safe to evict
156		..descriptor::RANDOM_SMALL_CACHE
157	},
158	Descriptor {
159		name: "eventid_shorteventid",
160		cache_disp: CacheDisp::Unique,
161		key_size_hint: Some(48),
162		val_size_hint: Some(8),
163		block_size: 512,
164		index_size: 512,
165		..descriptor::RANDOM
166	},
167	Descriptor {
168		name: "global",
169		..descriptor::RANDOM_SMALL
170	},
171	Descriptor {
172		name: "id_appserviceregistrations",
173		..descriptor::RANDOM_SMALL
174	},
175	Descriptor {
176		name: "keychangeid_userid",
177		..descriptor::RANDOM
178	},
179	Descriptor {
180		name: "keyid_key",
181		..descriptor::RANDOM_SMALL
182	},
183	Descriptor {
184		name: "lazyloadedids",
185		..descriptor::RANDOM_SMALL
186	},
187	Descriptor {
188		name: "logintoken_expiresatuserid",
189		..descriptor::RANDOM_SMALL
190	},
191	Descriptor {
192		name: "mediaid_file",
193		..descriptor::RANDOM_SMALL
194	},
195	Descriptor {
196		name: "mediaid_lazy",
197		ttl: 60 * 60 * 24 * 30, // must outlive url_preview so live previews resolve
198		..descriptor::RANDOM_SMALL_CACHE
199	},
200	Descriptor {
201		name: "mediaid_lazycontent",
202		cache_disp: CacheDisp::Unique, // 256 KiB rows would evict the shared pool
203		key_size_hint: Some(64),
204		val_size_hint: Some(1024 * 256),
205		file_size: 1024 * 1024 * 64,
206		write_size: 1024 * 1024 * 64,
207		compression: CompressionType::None, // media bytes are pre-compressed
208		ttl: 60 * 60 * 24 * 14,             // staging only: rows die at promotion or here
209		..descriptor::RANDOM_CACHE
210	},
211	Descriptor {
212		name: "mediaid_pending",
213		ttl: 60 * 60 * 24 * 7,
214		..descriptor::RANDOM_SMALL_CACHE
215	},
216	Descriptor {
217		name: "mediaid_user",
218		..descriptor::RANDOM_SMALL
219	},
220	Descriptor {
221		name: "oauthid_session",
222		..descriptor::RANDOM_SMALL
223	},
224	Descriptor {
225		name: "oauthuniqid_oauthid",
226		..descriptor::RANDOM_SMALL
227	},
228	Descriptor {
229		name: "oidc_signingkey",
230		..descriptor::RANDOM_SMALL
231	},
232	Descriptor {
233		name: "oidcclientid_registration",
234		..descriptor::RANDOM_SMALL_CACHE
235	},
236	Descriptor {
237		name: "oidccode_authsession",
238		..descriptor::RANDOM_SMALL
239	},
240	Descriptor {
241		name: "oidcdevice_userdeviceid",
242		..descriptor::RANDOM_SMALL
243	},
244	Descriptor {
245		name: "oidcdevicecode_devicegrant",
246		ttl: 60 * 60 * 24,
247		..descriptor::RANDOM_SMALL_CACHE
248	},
249	Descriptor {
250		name: "oidcusercode_devicecode",
251		ttl: 60 * 60 * 24,
252		..descriptor::RANDOM_SMALL_CACHE
253	},
254	Descriptor {
255		name: "oidccskeybypass_userid",
256		..descriptor::RANDOM_SMALL
257	},
258	Descriptor {
259		name: "oidcreqid_authrequest",
260		..descriptor::RANDOM_SMALL
261	},
262	Descriptor {
263		name: "onetimekeyid_onetimekeys",
264		..descriptor::DROPPED
265	},
266	Descriptor {
267		name: "onetimekeyid4225_otk",
268		..descriptor::RANDOM_SMALL
269	},
270	Descriptor {
271		name: "openidtoken_expiresatuserid",
272		..descriptor::RANDOM_SMALL
273	},
274	Descriptor {
275		name: "pduid_pdu",
276		cache_disp: CacheDisp::SharedWith("eventid_outlierpdu"),
277		key_size_hint: Some(16),
278		val_size_hint: Some(1520),
279		block_size: 2048,
280		index_size: 512,
281		..descriptor::SEQUENTIAL
282	},
283	Descriptor {
284		name: "publicroomids",
285		..descriptor::RANDOM_SMALL
286	},
287	Descriptor {
288		name: "pushkey_deviceid",
289		..descriptor::RANDOM_SMALL
290	},
291	Descriptor {
292		name: "presenceid_presence",
293		..descriptor::SEQUENTIAL_SMALL
294	},
295	Descriptor {
296		name: "readreceiptid_readreceipt",
297		..descriptor::RANDOM
298	},
299	Descriptor {
300		name: "referencedevents",
301		..descriptor::RANDOM
302	},
303	Descriptor {
304		name: "relatesto_typed",
305		key_size_hint: Some(33),
306		val_size_hint: Some(8),
307		..descriptor::RANDOM_SMALL
308	},
309	Descriptor {
310		name: "registrationtoken_info",
311		..descriptor::RANDOM_SMALL
312	},
313	Descriptor {
314		name: "roomid_knockedcount",
315		..descriptor::RANDOM_SMALL
316	},
317	Descriptor {
318		name: "roomid_invitedcount",
319		..descriptor::RANDOM_SMALL
320	},
321	Descriptor {
322		name: "roomid_inviteviaservers",
323		..descriptor::RANDOM_SMALL
324	},
325	Descriptor {
326		name: "roomid_joinedcount",
327		..descriptor::RANDOM_SMALL
328	},
329	Descriptor {
330		name: "roomid_maxremotepowerlevel",
331		..descriptor::RANDOM_SMALL
332	},
333	Descriptor {
334		name: "roomid_pduleaves",
335		..descriptor::RANDOM_SMALL
336	},
337	Descriptor {
338		name: "roomid_shortroomid",
339		val_size_hint: Some(8),
340		..descriptor::RANDOM_SMALL
341	},
342	Descriptor {
343		name: "roomid_shortstatehash",
344		val_size_hint: Some(8),
345		..descriptor::RANDOM_SMALL
346	},
347	Descriptor {
348		name: "roomid_spacehierarchy",
349		limit_size: 1024 * 1024 * 64,
350		ttl: 60 * 60 * 24 * 7, // above spacehierarchy_cache_ttl_max (18h default)
351		..descriptor::RANDOM_SMALL_CACHE
352	},
353	Descriptor {
354		name: "roomid_ts_pducount",
355		..descriptor::DROPPED
356	},
357	Descriptor {
358		name: "roomid_tscount_pducount",
359		val_size_hint: Some(8),
360		..descriptor::RANDOM
361	},
362	Descriptor {
363		name: "roomserverids",
364		..descriptor::RANDOM_SMALL
365	},
366	Descriptor {
367		name: "roomsynctoken_shortstatehash",
368		..descriptor::DROPPED
369	},
370	Descriptor {
371		name: "roomuserdataid_accountdata",
372		..descriptor::RANDOM_SMALL
373	},
374	Descriptor {
375		name: "roomuserid_invitecount",
376		val_size_hint: Some(8),
377		..descriptor::RANDOM_SMALL
378	},
379	Descriptor {
380		name: "roomuserid_joined",
381		..descriptor::RANDOM_SMALL
382	},
383	Descriptor {
384		name: "roomuserid_lastprivatereadupdate",
385		..descriptor::RANDOM_SMALL
386	},
387	Descriptor {
388		name: "roomuserid_lastnotificationread",
389		..descriptor::RANDOM_SMALL
390	},
391	Descriptor {
392		name: "roomuserid_leftcount",
393		val_size_hint: Some(8),
394		..descriptor::RANDOM
395	},
396	Descriptor {
397		name: "roomuserid_knockedcount",
398		val_size_hint: Some(8),
399		..descriptor::RANDOM_SMALL
400	},
401	Descriptor {
402		name: "roomuserid_privateread",
403		..descriptor::RANDOM_SMALL
404	},
405	// Aliased: importing RANDOM_SMALL unaliased makes every qualified sibling
406	// an unused_qualifications error.
407	Descriptor {
408		name: "roomuserid_privatereadsync",
409		..PRIVATE_READ_SYNC_DESCRIPTOR
410	},
411	Descriptor {
412		name: "roomuseroncejoinedids",
413		..descriptor::RANDOM
414	},
415	Descriptor {
416		name: "roomusertype_roomuserdataid",
417		..descriptor::RANDOM_SMALL
418	},
419	Descriptor {
420		name: "senderkey_pusher",
421		..descriptor::RANDOM_SMALL
422	},
423	Descriptor {
424		name: "server_signingkeys",
425		..descriptor::RANDOM
426	},
427	Descriptor {
428		name: "servercurrentevent_data",
429		..descriptor::RANDOM_SMALL
430	},
431	Descriptor {
432		name: "servername_destination",
433		cache_disp: CacheDisp::SharedWith("servername_override"), // one resolve writes both
434		key_size_hint: Some(48),
435		val_size_hint: Some(128),
436		ttl: 60 * 60 * 24 * 7, // dead after CachedDest::default_expire (<=36h)
437		..descriptor::RANDOM_SMALL_CACHE
438	},
439	Descriptor {
440		name: "servername_educount",
441		..descriptor::RANDOM_SMALL
442	},
443	Descriptor {
444		name: "servername_override",
445		cache_disp: CacheDisp::SharedWith("servername_destination"),
446		key_size_hint: Some(48),
447		val_size_hint: Some(128),
448		ttl: 60 * 60 * 24 * 7, // dead after CachedOverride::default_expire (<=12h)
449		..descriptor::RANDOM_SMALL_CACHE
450	},
451	Descriptor {
452		name: "servername_status",
453		cache_disp: CacheDisp::Unique, // read on every outbound attempt
454		key_size_hint: Some(48),
455		val_size_hint: Some(16),
456		ttl: 60 * 60 * 24 * 3, // dead after peer MAX_BACKOFF (24h)
457		..descriptor::RANDOM_SMALL_CACHE
458	},
459	Descriptor {
460		name: "servernameevent_data",
461		cache_disp: CacheDisp::Unique,
462		val_size_hint: Some(128),
463		..descriptor::RANDOM
464	},
465	Descriptor {
466		name: "serverroomids",
467		..descriptor::RANDOM_SMALL
468	},
469	Descriptor {
470		name: "shorteventid_authchain",
471		..LEGACY_AUTH_CHAIN_DESCRIPTOR
472	},
473	Descriptor {
474		name: "shorteventid_eventid",
475		cache_disp: CacheDisp::Unique,
476		key_size_hint: Some(8),
477		val_size_hint: Some(48),
478		..descriptor::SEQUENTIAL_SMALL
479	},
480	Descriptor {
481		name: "shorteventid_shortstatehash",
482		key_size_hint: Some(8),
483		val_size_hint: Some(8),
484		block_size: 512,
485		index_size: 512,
486		..descriptor::SEQUENTIAL
487	},
488	Descriptor {
489		name: "shortstatehash_statediff",
490		key_size_hint: Some(8),
491		..descriptor::SEQUENTIAL_SMALL
492	},
493	Descriptor {
494		name: "shortstatekey_statekey",
495		cache_disp: CacheDisp::Unique,
496		key_size_hint: Some(8),
497		val_size_hint: Some(1016),
498		..descriptor::RANDOM_SMALL
499	},
500	Descriptor {
501		name: "softfailedeventids",
502		key_size_hint: Some(48),
503		..descriptor::RANDOM_SMALL
504	},
505	Descriptor {
506		name: "statehash_shortstatehash",
507		val_size_hint: Some(8),
508		..descriptor::RANDOM
509	},
510	Descriptor {
511		name: "statekey_shortstatekey",
512		cache_disp: CacheDisp::Unique,
513		key_size_hint: Some(1016),
514		val_size_hint: Some(8),
515		..descriptor::RANDOM
516	},
517	Descriptor {
518		name: "threadactivityid_rootid",
519		key_size_hint: Some(16),
520		..descriptor::SEQUENTIAL_SMALL
521	},
522	Descriptor {
523		name: "threadid_userids",
524		..descriptor::SEQUENTIAL_SMALL
525	},
526	Descriptor {
527		name: "threadrootid_latestcount",
528		key_size_hint: Some(16),
529		val_size_hint: Some(8),
530		..descriptor::RANDOM_SMALL
531	},
532	Descriptor {
533		name: "threepidsid_pending",
534		ttl: 60 * 60 * 24, // pending validation session; minutes to complete
535		..THREEPID_SESSION_DESCRIPTOR
536	},
537	Descriptor {
538		name: "timeredacted_eventid",
539		key_size_hint: Some(57),
540		..descriptor::SEQUENTIAL_SMALL
541	},
542	Descriptor {
543		name: "todeviceid_events",
544		..descriptor::RANDOM
545	},
546	Descriptor {
547		name: "tofrom_relation",
548		key_size_hint: Some(8),
549		val_size_hint: Some(8),
550		..descriptor::RANDOM_SMALL
551	},
552	Descriptor {
553		name: "spentrefresh_userdeviceid",
554		..descriptor::RANDOM_SMALL
555	},
556	Descriptor {
557		name: "token_userdeviceid",
558		..descriptor::RANDOM_SMALL
559	},
560	Descriptor {
561		name: "tokenids",
562		block_size: 512,
563		..descriptor::RANDOM
564	},
565	Descriptor {
566		name: "url_preview",
567		ttl: 60 * 60 * 24 * 7, // dead after CachedPreview::EXPIRE (24h)
568		..descriptor::RANDOM_SMALL_CACHE
569	},
570	Descriptor {
571		name: "url_previews",
572		..descriptor::DROPPED
573	},
574	Descriptor {
575		name: "userdeviceid_metadata",
576		..descriptor::RANDOM_SMALL
577	},
578	Descriptor {
579		name: "userdeviceconnid_conn",
580		block_size: 1024 * 16,
581		..descriptor::RANDOM_SMALL
582	},
583	Descriptor {
584		name: "userdeviceid_refresh",
585		..descriptor::RANDOM_SMALL
586	},
587	Descriptor {
588		name: "userdeviceid_spentrefresh",
589		..descriptor::RANDOM_SMALL
590	},
591	Descriptor {
592		name: "userdeviceid_token",
593		..descriptor::RANDOM_SMALL
594	},
595	Descriptor {
596		name: "userdeviceidtoken_index",
597		..descriptor::RANDOM_SMALL
598	},
599	Descriptor {
600		name: "userdeviceidalgorithm_fallback",
601		..descriptor::RANDOM_SMALL
602	},
603	Descriptor {
604		name: "userdevicesessionid_threepid",
605		ttl: 60 * 60 * 24, // interactive-auth session; minutes to complete
606		..THREEPID_SESSION_DESCRIPTOR
607	},
608	Descriptor {
609		name: "userdevicesessionid_uiaainfo",
610		ttl: 60 * 60 * 24, // interactive-auth session; minutes to complete
611		..descriptor::RANDOM_SMALL_CACHE
612	},
613	Descriptor {
614		name: "userdevicetxnid_response",
615		..descriptor::RANDOM_SMALL
616	},
617	Descriptor {
618		name: "userfilterid_filter",
619		..descriptor::RANDOM_SMALL
620	},
621	Descriptor {
622		name: "userid_avatarurl",
623		..descriptor::RANDOM_SMALL
624	},
625	Descriptor {
626		name: "userid_blurhash",
627		..descriptor::RANDOM_SMALL
628	},
629	Descriptor {
630		name: "userid_dehydrateddevice",
631		..descriptor::RANDOM_SMALL
632	},
633	Descriptor {
634		name: "userid_devicelistversion",
635		..descriptor::RANDOM_SMALL
636	},
637	Descriptor {
638		name: "userid_displayname",
639		..descriptor::RANDOM_SMALL
640	},
641	Descriptor {
642		name: "userid_email",
643		..descriptor::RANDOM_SMALL
644	},
645	Descriptor {
646		name: "userid_erased",
647		..descriptor::RANDOM_SMALL
648	},
649	Descriptor {
650		name: "userid_lastonetimekeyupdate",
651		..descriptor::RANDOM_SMALL
652	},
653	Descriptor {
654		name: "userid_locked",
655		..descriptor::RANDOM_SMALL
656	},
657	Descriptor {
658		name: "userid_masterkeyid",
659		..descriptor::RANDOM_SMALL
660	},
661	Descriptor {
662		name: "userid_oauthid",
663		..descriptor::RANDOM_SMALL
664	},
665	Descriptor {
666		name: "userid_origin",
667		..descriptor::RANDOM
668	},
669	Descriptor {
670		name: "userid_password",
671		..descriptor::RANDOM
672	},
673	Descriptor {
674		name: "userid_presenceid",
675		..descriptor::RANDOM_SMALL
676	},
677	Descriptor {
678		name: "userid_selfsigningkeyid",
679		..descriptor::RANDOM_SMALL
680	},
681	Descriptor {
682		name: "userid_suspended",
683		..descriptor::RANDOM_SMALL
684	},
685	Descriptor {
686		name: "userid_usersigningkeyid",
687		..descriptor::RANDOM_SMALL
688	},
689	Descriptor {
690		name: "useridcount_notification",
691		limit_size: 1024 * 1024 * 256,
692		..descriptor::RANDOM_SMALL_CACHE
693	},
694	Descriptor {
695		name: "useridprofilekey_value",
696		..descriptor::RANDOM_SMALL
697	},
698	Descriptor {
699		name: "userroomid_highlightcount",
700		..descriptor::RANDOM
701	},
702	Descriptor {
703		name: "userroomid_invitestate",
704		..descriptor::RANDOM_SMALL
705	},
706	Descriptor {
707		name: "userroomid_joined",
708		..descriptor::RANDOM
709	},
710	Descriptor {
711		name: "userroomid_leftstate",
712		..descriptor::RANDOM
713	},
714	Descriptor {
715		name: "userroomid_knockedstate",
716		..descriptor::RANDOM_SMALL
717	},
718	Descriptor {
719		name: "userroomid_notificationcount",
720		..descriptor::RANDOM
721	},
722];