@@ -558,7 +558,7 @@ impl<D: Distance> Writer<D> {
558558 // Remove deleted links from lmdb AFTER build; in DiskANN we use a deleted item's
559559 // neighbours when filling in the "gaps" left in the graph from deletions. See
560560 // [`HnswBuilder::maybe_patch_old_links`] for more details.
561- self . delete_links_from_db ( & to_delete, wtxn) ?;
561+ self . delete_links_from_db ( & to_delete, wtxn, options ) ?;
562562
563563 debug ! ( "write the metadata..." ) ;
564564 options. progress . update ( HannoyBuild :: WriteTheMetadata ) ;
@@ -585,6 +585,10 @@ impl<D: Distance> Writer<D> {
585585 }
586586
587587 /// Kinda like clear and create, but only for links
588+ ///
589+ /// You must ensure that no items were inserted that are not
590+ /// part of the metadata. Which means that a build must have
591+ /// been performed or you'll see item leaking.
588592 fn force_rebuild < R , P , const M : usize , const M0 : usize > (
589593 & self ,
590594 wtxn : & mut RwTxn ,
@@ -601,15 +605,21 @@ impl<D: Distance> Writer<D> {
601605 "forcing relinking of all items requires the relink_all_items option to be set to true"
602606 ) ;
603607
604- // 2. delete metadata
608+ // 2. Fetch the list of items from the metadata
609+ let Metadata { items : item_ids, .. } = self
610+ . database
611+ . remap_data_type :: < MetadataCodec > ( )
612+ . get ( wtxn, & Key :: metadata ( self . index ) ) ?
613+ . expect ( "The metadata must be there" ) ;
614+
615+ // 3. delete metadata
605616 self . database . delete ( wtxn, & Key :: metadata ( self . index ) ) ?;
606617
607- // 3 . delete version
618+ // 4 . delete version
608619 self . database . delete ( wtxn, & Key :: version ( self . index ) ) ?;
609620
610- // 4. delete all links
611- let item_ids = self . item_indices ( wtxn, options) ?;
612- self . delete_links_from_db ( & item_ids, wtxn) ?;
621+ // 5. delete all links
622+ self . delete_links_from_db ( & item_ids, wtxn, options) ?;
613623
614624 // 5. trigger build
615625 self . build :: < R , P , M , M0 > ( wtxn, rng, options)
@@ -682,7 +692,18 @@ impl<D: Distance> Writer<D> {
682692
683693 // Iterates over links in lmdb and deletes those in `to_delete`. There can be several links
684694 // with the same NodeId.item, each differing by their layer
685- fn delete_links_from_db ( & self , to_delete : & RoaringBitmap , wtxn : & mut RwTxn ) -> Result < ( ) > {
695+ fn delete_links_from_db < P > (
696+ & self ,
697+ to_delete : & RoaringBitmap ,
698+ wtxn : & mut RwTxn ,
699+ options : & BuildOption < P > ,
700+ ) -> Result < ( ) >
701+ where
702+ P : steppe:: Progress ,
703+ {
704+ debug ! ( "started deleting the links..." ) ;
705+ options. progress . update ( HannoyBuild :: DeletingTheLinks ) ;
706+
686707 let mut cursor = self
687708 . database
688709 . remap_key_type :: < PrefixCodec > ( )
0 commit comments