Skip to content

Commit e65bd07

Browse files
committed
Get rid of BaoFileHandleInner and all that indirection
1 parent 3d603b0 commit e65bd07

File tree

2 files changed

+39
-75
lines changed

2 files changed

+39
-75
lines changed

src/store/fs.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ impl entity_manager::Params for EmParams {
226226
// have exact control over where it happens.
227227
if let Some(mut handle) = state.state.0.lock().await.take() {
228228
trace!("shutting down hash: {}, cause: {cause:?}", state.id);
229-
handle.persist(&state.global.options);
229+
handle.persist(&state.id, &state.global.options);
230230
}
231231
}
232232
}
@@ -319,7 +319,7 @@ impl HashContext {
319319
let res = self.db().get(hash).await.map_err(io::Error::other)?;
320320
let res = match res {
321321
Some(state) => open_bao_file(&hash, state, &self.global).await,
322-
None => Ok(BaoFileHandle::new_partial_mem(hash)),
322+
None => Ok(BaoFileHandle::new_partial_mem()),
323323
};
324324
Ok((res?, ()))
325325
})
@@ -366,7 +366,7 @@ async fn open_bao_file(
366366
MemOrFile::File(file)
367367
}
368368
};
369-
BaoFileHandle::new_complete(*hash, data, outboard)
369+
BaoFileHandle::new_complete(data, outboard)
370370
}
371371
EntryState::Partial { .. } => BaoFileHandle::new_partial_file(*hash, ctx).await?,
372372
})
@@ -622,7 +622,7 @@ impl Actor {
622622
options: options.clone(),
623623
db: meta::Db::new(db_send),
624624
internal_cmd_tx: fs_commands_tx,
625-
empty: BaoFileHandle::new_complete(Hash::EMPTY, MemOrFile::empty(), MemOrFile::empty()),
625+
empty: BaoFileHandle::new_complete(MemOrFile::empty(), MemOrFile::empty()),
626626
protect,
627627
});
628628
rt.spawn(db_actor.run());
@@ -926,7 +926,7 @@ async fn import_bao_impl(
926926
) -> api::Result<()> {
927927
trace!(
928928
"importing bao: {} {} bytes",
929-
handle.hash().fmt_short(),
929+
ctx.id.fmt_short(),
930930
size
931931
);
932932
let mut batch = Vec::<BaoContentItem>::new();
@@ -935,7 +935,7 @@ async fn import_bao_impl(
935935
// if the batch is not empty, the last item is a leaf and the current item is a parent, write the batch
936936
if !batch.is_empty() && batch[batch.len() - 1].is_leaf() && item.is_parent() {
937937
let bitfield = Bitfield::new_unchecked(ranges, size.into());
938-
handle.write_batch(&batch, &bitfield, &ctx.global).await?;
938+
handle.write_batch(&batch, &bitfield, &ctx).await?;
939939
batch.clear();
940940
ranges = ChunkRanges::empty();
941941
}
@@ -951,7 +951,7 @@ async fn import_bao_impl(
951951
}
952952
if !batch.is_empty() {
953953
let bitfield = Bitfield::new_unchecked(ranges, size.into());
954-
handle.write_batch(&batch, &bitfield, &ctx.global).await?;
954+
handle.write_batch(&batch, &bitfield, &ctx).await?;
955955
}
956956
Ok(())
957957
}
@@ -991,7 +991,6 @@ async fn export_ranges_impl(
991991
"exporting ranges: {hash} {ranges:?} size={}",
992992
handle.current_size()?
993993
);
994-
debug_assert!(handle.hash() == hash, "hash mismatch");
995994
let bitfield = handle.bitfield()?;
996995
let data = handle.data_reader();
997996
let size = bitfield.size();
@@ -1052,8 +1051,7 @@ async fn export_bao_impl(
10521051
handle: BaoFileHandle,
10531052
) -> anyhow::Result<()> {
10541053
let ExportBaoRequest { ranges, hash, .. } = cmd;
1055-
debug_assert!(handle.hash() == hash, "hash mismatch");
1056-
let outboard = handle.outboard()?;
1054+
let outboard = handle.outboard(&hash)?;
10571055
let size = outboard.tree.size();
10581056
if size == 0 && hash != Hash::EMPTY {
10591057
// we have no data whatsoever, so we stop here

src/store/fs/bao_file.rs

Lines changed: 31 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use super::{
3131
use crate::{
3232
api::blobs::Bitfield,
3333
store::{
34-
fs::{meta::raw_outboard_size, TaskContext},
34+
fs::{meta::raw_outboard_size, HashContext, TaskContext},
3535
util::{
3636
read_checksummed_and_truncate, write_checksummed, FixedSize, MemOrFile,
3737
PartialMemStorage, DD,
@@ -401,21 +401,20 @@ impl BaoFileStorage {
401401
self,
402402
batch: &[BaoContentItem],
403403
bitfield: &Bitfield,
404-
ctx: &TaskContext,
405-
hash: &Hash,
404+
ctx: &HashContext,
406405
) -> io::Result<(Self, Option<EntryState<bytes::Bytes>>)> {
407406
Ok(match self {
408407
BaoFileStorage::PartialMem(mut ms) => {
409408
// check if we need to switch to file mode, otherwise write to memory
410-
if max_offset(batch) <= ctx.options.inline.max_data_inlined {
409+
if max_offset(batch) <= ctx.global.options.inline.max_data_inlined {
411410
ms.write_batch(bitfield.size(), batch)?;
412411
let changes = ms.bitfield.update(bitfield);
413412
let new = changes.new_state();
414413
if new.complete {
415-
let (cs, update) = ms.into_complete(hash, ctx)?;
414+
let (cs, update) = ms.into_complete(&ctx.id, &ctx.global)?;
416415
(cs.into(), Some(update))
417416
} else {
418-
let fs = ms.persist(ctx, hash)?;
417+
let fs = ms.persist(&ctx.global, &ctx.id)?;
419418
let update = EntryState::Partial {
420419
size: new.validated_size,
421420
};
@@ -428,13 +427,13 @@ impl BaoFileStorage {
428427
// a write at the end of a very large file.
429428
//
430429
// opt: we should check if we become complete to avoid going from mem to partial to complete
431-
let mut fs = ms.persist(ctx, hash)?;
430+
let mut fs = ms.persist(&ctx.global, &ctx.id)?;
432431
fs.write_batch(bitfield.size(), batch)?;
433432
let changes = fs.bitfield.update(bitfield);
434433
let new = changes.new_state();
435434
if new.complete {
436435
let size = new.validated_size.unwrap();
437-
let (cs, update) = fs.into_complete(size, &ctx.options)?;
436+
let (cs, update) = fs.into_complete(size, &ctx.global.options)?;
438437
(cs.into(), Some(update))
439438
} else {
440439
let update = EntryState::Partial {
@@ -450,7 +449,7 @@ impl BaoFileStorage {
450449
let new = changes.new_state();
451450
if new.complete {
452451
let size = new.validated_size.unwrap();
453-
let (cs, update) = fs.into_complete(size, &ctx.options)?;
452+
let (cs, update) = fs.into_complete(size, &ctx.global.options)?;
454453
(cs.into(), Some(update))
455454
} else if changes.was_validated() {
456455
// we are still partial, but now we know the size
@@ -503,46 +502,29 @@ impl BaoFileStorage {
503502
}
504503
}
505504

506-
/// The inner part of a bao file handle.
507-
pub struct BaoFileHandleInner {
508-
pub(crate) storage: watch::Sender<BaoFileStorage>,
509-
hash: Hash,
510-
}
511-
512-
impl fmt::Debug for BaoFileHandleInner {
513-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
514-
let guard = self.storage.borrow();
515-
let storage = guard.deref();
516-
f.debug_struct("BaoFileHandleInner")
517-
.field("hash", &DD(self.hash))
518-
.field("storage", &storage)
519-
.finish_non_exhaustive()
520-
}
521-
}
522-
523505
/// A cheaply cloneable handle to a bao file, including the hash and the configuration.
524506
#[derive(Debug, Clone, derive_more::Deref)]
525-
pub struct BaoFileHandle(Arc<BaoFileHandleInner>);
507+
pub(crate) struct BaoFileHandle(Arc<watch::Sender<BaoFileStorage>>);
526508

527509
impl BaoFileHandle {
528-
pub fn persist(&mut self, options: &Options) {
529-
self.0.storage.send_if_modified(|guard| {
510+
pub fn persist(&mut self, hash: &Hash, options: &Options) {
511+
self.send_if_modified(|guard| {
530512
if Arc::strong_count(&self.0) > 1 {
531513
return false;
532514
}
533515
let BaoFileStorage::Partial(fs) = guard.take() else {
534516
return false;
535517
};
536-
let path = options.path.bitfield_path(&self.hash);
518+
let path = options.path.bitfield_path(hash);
537519
trace!(
538520
"writing bitfield for hash {} to {}",
539-
self.hash,
521+
hash,
540522
path.display()
541523
);
542524
if let Err(cause) = fs.sync_all(&path) {
543525
error!(
544526
"failed to write bitfield for {} at {}: {:?}",
545-
self.hash,
527+
hash,
546528
path.display(),
547529
cause
548530
);
@@ -558,7 +540,7 @@ pub struct DataReader(BaoFileHandle);
558540

559541
impl ReadBytesAt for DataReader {
560542
fn read_bytes_at(&self, offset: u64, size: usize) -> std::io::Result<Bytes> {
561-
let guard = self.0.storage.borrow();
543+
let guard = self.0.borrow();
562544
match guard.deref() {
563545
BaoFileStorage::PartialMem(x) => x.data.read_bytes_at(offset, size),
564546
BaoFileStorage::Partial(x) => x.data.read_bytes_at(offset, size),
@@ -574,7 +556,7 @@ pub struct OutboardReader(BaoFileHandle);
574556

575557
impl ReadAt for OutboardReader {
576558
fn read_at(&self, offset: u64, buf: &mut [u8]) -> io::Result<usize> {
577-
let guard = self.0.storage.borrow();
559+
let guard = self.0.borrow();
578560
match guard.deref() {
579561
BaoFileStorage::Complete(x) => x.outboard.read_at(offset, buf),
580562
BaoFileStorage::PartialMem(x) => x.outboard.read_at(offset, buf),
@@ -593,12 +575,9 @@ impl BaoFileHandle {
593575
/// Create a new bao file handle.
594576
///
595577
/// This will create a new file handle with an empty memory storage.
596-
pub fn new_partial_mem(hash: Hash) -> Self {
578+
pub fn new_partial_mem() -> Self {
597579
let storage = BaoFileStorage::partial_mem();
598-
Self(Arc::new(BaoFileHandleInner {
599-
storage: watch::Sender::new(storage),
600-
hash,
601-
}))
580+
Self(Arc::new(watch::Sender::new(storage)))
602581
}
603582

604583
/// Create a new bao file handle with a partial file.
@@ -614,23 +593,16 @@ impl BaoFileHandle {
614593
} else {
615594
storage.into()
616595
};
617-
Ok(Self(Arc::new(BaoFileHandleInner {
618-
storage: watch::Sender::new(storage),
619-
hash,
620-
})))
596+
Ok(Self(Arc::new(watch::Sender::new(storage))))
621597
}
622598

623599
/// Create a new complete bao file handle.
624600
pub fn new_complete(
625-
hash: Hash,
626601
data: MemOrFile<Bytes, FixedSize<File>>,
627602
outboard: MemOrFile<Bytes, File>,
628603
) -> Self {
629604
let storage = CompleteStorage { data, outboard }.into();
630-
Self(Arc::new(BaoFileHandleInner {
631-
storage: watch::Sender::new(storage),
632-
hash,
633-
}))
605+
Self(Arc::new(watch::Sender::new(storage)))
634606
}
635607

636608
/// Complete the handle
@@ -639,7 +611,7 @@ impl BaoFileHandle {
639611
data: MemOrFile<Bytes, FixedSize<File>>,
640612
outboard: MemOrFile<Bytes, File>,
641613
) {
642-
self.storage.send_if_modified(|guard| {
614+
self.send_if_modified(|guard| {
643615
let res = match guard {
644616
BaoFileStorage::Complete(_) => None,
645617
BaoFileStorage::PartialMem(entry) => Some(&mut entry.bitfield),
@@ -657,13 +629,13 @@ impl BaoFileHandle {
657629
}
658630

659631
pub fn subscribe(&self) -> BaoFileStorageSubscriber {
660-
BaoFileStorageSubscriber::new(self.0.storage.subscribe())
632+
BaoFileStorageSubscriber::new(self.0.subscribe())
661633
}
662634

663635
/// True if the file is complete.
664636
#[allow(dead_code)]
665637
pub fn is_complete(&self) -> bool {
666-
matches!(self.storage.borrow().deref(), BaoFileStorage::Complete(_))
638+
matches!(self.borrow().deref(), BaoFileStorage::Complete(_))
667639
}
668640

669641
/// An AsyncSliceReader for the data file.
@@ -684,7 +656,7 @@ impl BaoFileHandle {
684656

685657
/// The most precise known total size of the data file.
686658
pub fn current_size(&self) -> io::Result<u64> {
687-
match self.storage.borrow().deref() {
659+
match self.borrow().deref() {
688660
BaoFileStorage::Complete(mem) => Ok(mem.size()),
689661
BaoFileStorage::PartialMem(mem) => Ok(mem.current_size()),
690662
BaoFileStorage::Partial(file) => file.current_size(),
@@ -694,7 +666,7 @@ impl BaoFileHandle {
694666

695667
/// The most precise known total size of the data file.
696668
pub fn bitfield(&self) -> io::Result<Bitfield> {
697-
match self.storage.borrow().deref() {
669+
match self.borrow().deref() {
698670
BaoFileStorage::Complete(mem) => Ok(mem.bitfield()),
699671
BaoFileStorage::PartialMem(mem) => Ok(mem.bitfield().clone()),
700672
BaoFileStorage::Partial(file) => Ok(file.bitfield().clone()),
@@ -703,33 +675,27 @@ impl BaoFileHandle {
703675
}
704676

705677
/// The outboard for the file.
706-
pub fn outboard(&self) -> io::Result<PreOrderOutboard<OutboardReader>> {
707-
let root = self.hash.into();
678+
pub fn outboard(&self, hash: &Hash) -> io::Result<PreOrderOutboard<OutboardReader>> {
708679
let tree = BaoTree::new(self.current_size()?, IROH_BLOCK_SIZE);
709680
let outboard = self.outboard_reader();
710681
Ok(PreOrderOutboard {
711-
root,
682+
root: blake3::Hash::from(*hash),
712683
tree,
713684
data: outboard,
714685
})
715686
}
716687

717-
/// The hash of the file.
718-
pub fn hash(&self) -> Hash {
719-
self.hash
720-
}
721-
722688
/// Write a batch and notify the db
723689
pub(super) async fn write_batch(
724690
&self,
725691
batch: &[BaoContentItem],
726692
bitfield: &Bitfield,
727-
ctx: &TaskContext,
693+
ctx: &HashContext,
728694
) -> io::Result<()> {
729695
trace!("write_batch bitfield={:?} batch={}", bitfield, batch.len());
730696
let mut res = Ok(None);
731-
self.storage.send_if_modified(|state| {
732-
let Ok((state1, update)) = state.take().write_batch(batch, bitfield, ctx, &self.hash)
697+
self.send_if_modified(|state| {
698+
let Ok((state1, update)) = state.take().write_batch(batch, bitfield, ctx)
733699
else {
734700
res = Err(io::Error::other("write batch failed"));
735701
return false;
@@ -739,7 +705,7 @@ impl BaoFileHandle {
739705
true
740706
});
741707
if let Some(update) = res? {
742-
ctx.db.update(self.hash, update).await?;
708+
ctx.global.db.update(ctx.id, update).await?;
743709
}
744710
Ok(())
745711
}

0 commit comments

Comments
 (0)