···
/// this is only meant for tests
151
+
/// do major compaction on startup
153
+
/// default is false. probably a good thing unless it's too slow.
154
+
pub major_compact: bool,
impl StorageWhatever<FjallReader, FjallWriter, FjallBackground, FjallConfig> for FjallStorage {
···
158
-
_config: FjallConfig,
162
+
config: FjallConfig,
) -> StorageResult<(FjallReader, FjallWriter, Option<Cursor>, SketchSecretPrefix)> {
let config = Config::new(path);
···
227
-
for (partition, name) in [
228
-
(&global, "global"),
230
-
(&records, "records"),
231
-
(&rollups, "rollups"),
232
-
(&queues, "queues"),
234
-
let size0 = partition.disk_space();
235
-
log::info!("beggining major compaction for {name} (original size: {size0})");
236
-
let t0 = Instant::now();
237
-
partition.major_compact().expect("compact better work 😬");
238
-
let dt = t0.elapsed();
239
-
let sizef = partition.disk_space();
240
-
let dsize = (sizef as i64) - (size0 as i64);
241
-
log::info!("completed compaction for {name} in {dt:?} (new size: {sizef}, {dsize})");
231
+
if config.major_compact {
232
+
for (partition, name) in [
233
+
(&global, "global"),
235
+
(&records, "records"),
236
+
(&rollups, "rollups"),
237
+
(&queues, "queues"),
239
+
let size0 = partition.disk_space();
240
+
log::info!("beggining major compaction for {name} (original size: {size0})");
241
+
let t0 = Instant::now();
242
+
partition.major_compact().expect("compact better work 😬");
243
+
let dt = t0.elapsed();
244
+
let sizef = partition.disk_space();
245
+
let dsize = (sizef as i64) - (size0 as i64);
247
+
"completed compaction for {name} in {dt:?} (new size: {sizef}, {dsize})"
251
+
log::info!("skipping major compaction on startup");
let reader = FjallReader {
···
Ok((cursors_advanced, dirty_nsids))
1379
+
pub fn records_brute_gc_danger(&self) -> StorageResult<(usize, usize)> {
1380
+
let (mut removed, mut retained) = (0, 0);
1381
+
let mut to_retain = HashSet::<Vec<u8>>::new();
1383
+
// Partition: 'feed'
1385
+
// - Per-collection list of record references ordered by jetstream cursor
1386
+
// - key: nullstr || u64 (collection nsid null-terminated, jetstream cursor)
1387
+
// - val: nullstr || nullstr || nullstr (did, rkey, rev. rev is mostly a sanity-check for now.)
1390
+
// Partition: 'records'
1392
+
// - Actual records by their atproto location
1393
+
// - key: nullstr || nullstr || nullstr (did, collection, rkey)
1394
+
// - val: u64 || bool || nullstr || rawval (js_cursor, is_update, rev, actual record)
1398
+
log::warn!("loading *all* record keys from feed into memory (yikes)");
1399
+
let t0 = Instant::now();
1400
+
for (i, kv) in self.feeds.iter().enumerate() {
1401
+
if i > 0 && (i % 100000 == 0) {
1402
+
log::info!("{i}...");
1404
+
let (key_bytes, val_bytes) = kv?;
1405
+
let key = db_complete::<NsidRecordFeedKey>(&key_bytes)?;
1406
+
let val = db_complete::<NsidRecordFeedVal>(&val_bytes)?;
1407
+
let record_key: RecordLocationKey = (&key, &val).into();
1408
+
to_retain.insert(record_key.to_db_bytes()?);
1411
+
"loaded. wow. took {:?}, found {} keys",
1416
+
log::warn!("warmup OVER, iterating some billions of record keys now");
1417
+
let t0 = Instant::now();
1418
+
for (i, k) in self.records.keys().enumerate() {
1419
+
let key_bytes = k?;
1420
+
if to_retain.contains(&*key_bytes) {
1423
+
self.records.remove(key_bytes)?;
1426
+
if i > 0 && (i % 10_000_000) == 0 {
1427
+
log::info!("{i}: {retained} retained, {removed} removed.");
1430
+
log::warn!("whew! that took {:?}", t0.elapsed());
1432
+
Ok((removed, retained))
impl StoreWriter<FjallBackground> for FjallWriter {
···
tempfile::tempdir().unwrap(),
"offline test (no real jetstream endpoint)".to_string(),
1820
-
FjallConfig { temp: true },
1887
+
..Default::default()