···22use crate::db::compaction::DropPrefixFilterFactory;
33use crate::types::{BroadcastEvent, RepoState};
4455-use fjall::config::{BlockSizePolicy, CompressionPolicy};
55+use fjall::config::{BlockSizePolicy, CompressionPolicy, RestartIntervalPolicy};
66use fjall::{
77 CompressionType, Database, Keyspace, KeyspaceCreateOptions, OwnedWriteBatch, PersistMode, Slice,
88};
···152152 .expect_point_read_hits(false)
153153 .max_memtable_size(mb(cfg.db_repos_memtable_size_mb))
154154 // did -> repo state, not gonna be compressable well because dids are random
155155- // and repo state doesnt have repeats really
155155+ // and repo state doesnt have repeats really..
156156+ // these block sizes work fine since we insert into repos constantly anyway
157157+ // whenever we update anything related to a repo, so the repos that arent
158158+ // being updated will be compacted away!
156159 .data_block_size_policy(BlockSizePolicy::new([kb(4), kb(4), kb(8), kb(64)]))
157160 .data_block_compression_policy(CompressionPolicy::new([
158161 CompressionType::None,
159162 CompressionType::None,
160163 compression,
161161- ])),
164164+ ]))
165165+ // did plc are random so the interval wont rlly matter
166166+ .data_block_restart_interval_policy(RestartIntervalPolicy::new([2, 4])),
162167 )?;
163168 let pending = open_ks(
164169 "pending",
···167172 .expect_point_read_hits(true)
168173 .max_memtable_size(mb(8))
169174 // its just index of id (int) -> did, and dids arent compressable (especially with the ids being random)
170170- .data_block_size_policy(BlockSizePolicy::all(kb(1)))
175175+ .data_block_size_policy(BlockSizePolicy::all(kb(8)))
171176 // and we'll transition from pending to synced anyway, no point trying to compress
172172- .data_block_compression_policy(CompressionPolicy::disabled()),
177177+ .data_block_compression_policy(CompressionPolicy::disabled())
178178+ // ids are sequential and share prefix so we can use large interval to save space
179179+ .data_block_restart_interval_policy(RestartIntervalPolicy::all(64)),
173180 )?;
174181 let resync = open_ks(
175182 "resync",
···181188 // did -> error state, so its gonna be basically random, cant compress well
182189 .data_block_size_policy(BlockSizePolicy::all(kb(4)))
183190 // and we arent going to have many of these anyway, no point trying
184184- .data_block_compression_policy(CompressionPolicy::disabled()),
191191+ .data_block_compression_policy(CompressionPolicy::disabled())
192192+ .data_block_restart_interval_policy(RestartIntervalPolicy::all(4)),
185193 )?;
186194 let blocks = open_ks(
187195 "blocks",
···189197 // point reads are used a lot by stream, we know the blocks exist though
190198 .expect_point_read_hits(true)
191199 .max_memtable_size(mb(cfg.db_blocks_memtable_size_mb))
192192- // 16 - 128 kb is probably fine, as the newer blocks will be in the first levels
200200+ // 16 - 128 kb, as the newer blocks will be in the first level
193201 // and any consumers will probably be streaming the newer events...
194194- // and blocks are pretty big-ish like around 5kb usually so this helps i think
202202+ // and blocks are pretty big-ish like around 5kb...
203203+ // replaying will hit later levels so it will be slower but thats honestly
204204+ // an acceptable tradeoff to save more space...
205205+ // todo: we can probably decrease these when we get zstd dict compression?
195206 .data_block_size_policy(BlockSizePolicy::new([kb(16), kb(64), kb(128)]))
196207 // lets not compress first level so the reads for new blocks are faster
197208 // since we will be streaming them to consumers
198209 .data_block_compression_policy(CompressionPolicy::new([
199210 CompressionType::None,
200211 compression,
201201- ])),
212212+ ]))
213213+ .data_block_restart_interval_policy(RestartIntervalPolicy::new([8, 16, 32])),
202214 )?;
203215 let records = open_ks(
204216 "records",
···208220 // and since this keyspace is big, turning off bloom filters will help a lot
209221 .expect_point_read_hits(true)
210222 .max_memtable_size(mb(cfg.db_records_memtable_size_mb))
211211- // its just did|col|rkey -> cid, very small
223223+ // its just did|col|rkey -> cid, very small (84 bytes for bsky post)
212224 .data_block_size_policy(BlockSizePolicy::new([kb(8), kb(16)]))
213225 // cids arent compressable, most rkeys are TIDs so they will get compressed
214226 // by prefix truncation anyway
215215- .data_block_compression_policy(CompressionPolicy::disabled()),
227227+ .data_block_compression_policy(CompressionPolicy::disabled())
228228+ .data_block_restart_interval_policy(RestartIntervalPolicy::all(9)),
216229 )?;
217230 let cursors = open_ks(
218231 "cursors",
···222235 .max_memtable_size(mb(4))
223236 // its just cursors...
224237 .data_block_size_policy(BlockSizePolicy::all(kb(1)))
225225- .data_block_compression_policy(CompressionPolicy::disabled()),
238238+ .data_block_compression_policy(CompressionPolicy::disabled())
239239+ .data_block_restart_interval_policy(RestartIntervalPolicy::all(1)),
226240 )?;
227241 let resync_buffer = open_ks(
228242 "resync_buffer",
···232246 .max_memtable_size(mb(16))
233247 .data_block_size_policy(BlockSizePolicy::all(kb(32)))
234248 // dont have to compress here since resync buffer will be emptied at some point anyway
235235- .data_block_compression_policy(CompressionPolicy::disabled()),
249249+ .data_block_compression_policy(CompressionPolicy::disabled())
250250+ .data_block_restart_interval_policy(RestartIntervalPolicy::all(16)),
236251 )?;
237252 let events = open_ks(
238253 "events",
···249264 .data_block_compression_policy(CompressionPolicy::new([
250265 CompressionType::None,
251266 compression,
252252- ])),
267267+ ]))
268268+ // ids are int, we can prefix truncate a lot
269269+ .data_block_restart_interval_policy(RestartIntervalPolicy::new([64, 128])),
253270 )?;
254271 let counts = open_ks(
255272 "counts",
···258275 .expect_point_read_hits(true)
259276 .max_memtable_size(mb(16))
260277 // the data is very small
261261- // this is at worst did|col -> u64, so its tiny
278278+ // this is at worst did|col -> u64, so its tiny (40 bytes)
262279 .data_block_size_policy(BlockSizePolicy::all(kb(2)))
263263- .data_block_compression_policy(CompressionPolicy::disabled()),
280280+ .data_block_compression_policy(CompressionPolicy::disabled())
281281+ .data_block_restart_interval_policy(RestartIntervalPolicy::all(7)),
264282 )?;
265283266284 // filter handles high-volume point reads (repo excludes) so it needs the bloom filter
···270288 .max_memtable_size(mb(16))
271289 // dids arent compressable so this is fine, and we have nothing as the value
272290 .data_block_size_policy(BlockSizePolicy::all(kb(1)))
273273- .data_block_compression_policy(CompressionPolicy::disabled()),
291291+ .data_block_compression_policy(CompressionPolicy::disabled())
292292+ .data_block_restart_interval_policy(RestartIntervalPolicy::all(2)),
274293 )?;
275294276295 let crawler = open_ks(
···281300 .max_memtable_size(mb(16))
282301 // did -> failed state, not very compressable
283302 .data_block_size_policy(BlockSizePolicy::all(kb(2)))
284284- .data_block_compression_policy(CompressionPolicy::disabled()),
303303+ .data_block_compression_policy(CompressionPolicy::disabled())
304304+ .data_block_restart_interval_policy(RestartIntervalPolicy::all(2)),
285305 )?;
286306287307 // when adding new keyspaces, make sure to add them to the /stats endpoint