Phase 2d (0.6.1-beta): route manifest + blob ops through file_holders
Switch ALL propagation-decision reads to the flat holder set. push_manifest_to_downstream now targets file_holders instead of blob_downstream. ManifestPush receive-side relay likewise — known holders fan out to up to 5 most-recent peers instead of a directional tree. Blob delete notices: single flat fan-out to file_holders; the legacy upstream_node tree-healing field is emitted as None (wire-stable via serde default) and ignored on receive — the post-0.6 flat model doesn't need sender-role distinction. send_blob_delete_notices keeps its Option<&Upstream> parameter as an unused placeholder for signature stability with the call sites in this commit. Other reads migrated: - blob fetch cascade: step 2 now tries "known holders" (up to 5) instead of a single upstream - manifest refresh: downstream_count reported from file_holder_count - web/http post holder enumeration - Worm search post/blob holder fallback (both connection.rs paths) - DeleteRecord fan-out rewires to file_holders - Under-replication replication check: < 2 holders Storage additions: - get_file_holder_count(file_id) - remove_file_holder(file_id, peer_id) Legacy upstream/downstream writes are still happening from Phase 2b; those + the tables themselves go in 2e. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3a0d2e93ab
commit
60463d1817
6 changed files with 103 additions and 128 deletions
|
|
@ -4470,6 +4470,14 @@ impl Storage {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Count file holders (bounded at 5 by touch_file_holder's LRU cap).
|
||||
pub fn get_file_holder_count(&self, file_id: &[u8; 32]) -> anyhow::Result<u32> {
|
||||
let count: i64 = self.conn.prepare(
|
||||
"SELECT COUNT(*) FROM file_holders WHERE file_id = ?1",
|
||||
)?.query_row(params![file_id.as_slice()], |row| row.get(0))?;
|
||||
Ok(count as u32)
|
||||
}
|
||||
|
||||
/// Return the up-to-5 most recently interacted holders of a file.
|
||||
pub fn get_file_holders(&self, file_id: &[u8; 32]) -> anyhow::Result<Vec<(NodeId, Vec<String>)>> {
|
||||
let mut stmt = self.conn.prepare(
|
||||
|
|
@ -4504,6 +4512,15 @@ impl Storage {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove a single peer's holder entry for a file.
|
||||
pub fn remove_file_holder(&self, file_id: &[u8; 32], peer_id: &NodeId) -> anyhow::Result<()> {
|
||||
self.conn.execute(
|
||||
"DELETE FROM file_holders WHERE file_id = ?1 AND peer_id = ?2",
|
||||
params![file_id.as_slice(), peer_id.as_slice()],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// One-time migration: seed file_holders from the legacy upstream/downstream
|
||||
/// tables so a user upgrading from pre-0.6.1 doesn't start with empty holder
|
||||
/// sets. Idempotent — inserts use ON CONFLICT DO NOTHING semantics via the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue