async reload_chunks(chunk_ids) {
        const loaded_chunks_db = await MDStore.instance().find_chunks_by_ids(chunk_ids);
        await Promise.all([
            MDStore.instance().load_parts_objects_for_chunks(loaded_chunks_db),
            MDStore.instance().load_blocks_for_chunks(loaded_chunks_db)
        ]);
        /** @type {nb.Chunk[]} */
        const loaded_chunks = loaded_chunks_db.map(chunk_db => new ChunkDB(chunk_db));
        dbg.log1('MapBuilder.reload_chunks:', loaded_chunks);

        /** @type {nb.Block[]} */
        const blocks_to_delete = [];

        // first look for deleted chunks, and set it's blocks for deletion
        const [deleted_chunks, live_chunks] = _.partition(loaded_chunks, chunk => Boolean(chunk.to_db().deleted));

        // mark all live blocks of deleted chunks for deletion
        for (const chunk of deleted_chunks) {
            for (const frag of chunk.frags) {
                for (const block of frag.blocks) {
                    if (!block.to_db().deleted) {
                        dbg.log0('found unreferenced blocks of a deleted chunk', block);
                        blocks_to_delete.push(block);
                    }
                }
            }
        }

        /** @type {nb.Chunk[] } */
        const chunks_to_delete = [];

        /** @type {nb.Chunk[] } */
        const chunks_to_build = [];

        await P.map(live_chunks, async chunk => {
            try {

                // TODO JACKY handle deleted tier

                // if (!chunk.tier) {
                //     await node_allocator.refresh_tiering_alloc(chunk.bucket.tiering);
                //     const tiering_status = node_allocator.get_tiering_status(chunk.bucket.tiering);
                //     chunk.tier = mapper.select_tier_for_write(chunk.bucket.tiering, tiering_status);
                // }

                if (!chunk.parts || !chunk.parts.length) {
                    const last_hour = this.start_run - (60 * 60 * 1000); // chunks that were created in the last hour will not be deleted
                    dbg.log0('unreferenced chunk to delete', chunk);
                    if (chunk._id.getTimestamp().getTime() > last_hour) return;
                    chunks_to_delete.push(chunk);
                    return;
                }

                chunks_to_build.push(chunk);

            } catch (err) {
                dbg.error(`failed to load chunk ${chunk._id} for builder`, err);
            }
        });

        const chunks_to_delete_uniq = _.uniqBy(chunks_to_delete, chunk => chunk._id.toHexString());

        dbg.log1('MapBuilder.update_db:',
            'chunks_to_build', chunks_to_build.length,
            'chunks_to_delete_uniq', chunks_to_delete_uniq.length,
            'blocks_to_delete', blocks_to_delete.length);

        await Promise.all([
            map_deleter.delete_blocks(blocks_to_delete),
            map_deleter.delete_chunks(chunks_to_delete_uniq),
        ]);

        return chunks_to_build;
    }
/**
     * In order to get the most relevant data regarding the chunks
     * Note that there is always a possibility that the chunks will cease to exist
     * TODO: We can release the unrelevant chunks from the surround_keys
     * This will allow other batches to run if they wait on non existing chunks
     * @param {nb.ID[]} chunk_ids 
     * @returns {Promise<nb.Chunk[]>}
     */
In order to get the most relevant data regarding the chunks
Note that there is always a possibility that the chunks will cease to exist
TODO: We can release the unrelevant chunks from the surround_keys
This will allow other batches to run if they wait on non existing chunks
@param {nb.ID[]} chunk_ids
@returns {Promise}
In order to get the most relevant data regarding the chunks Note that there is always a possibility that the chunks will cease to exist TODO : We can release the unrelevant chunks from the surround_keys This will allow other batches to run if they wait on non existing chunks @param { nb . ID [] } chunk_ids @returns { Promise }
async reload_chunks(chunk_ids) {
        const loaded_chunks_db = await MDStore.instance().find_chunks_by_ids(chunk_ids);
        await Promise.all([
            MDStore.instance().load_parts_objects_for_chunks(loaded_chunks_db),
            MDStore.instance().load_blocks_for_chunks(loaded_chunks_db)
        ]);
        const loaded_chunks = loaded_chunks_db.map(chunk_db => new ChunkDB(chunk_db));
        dbg.log1('MapBuilder.reload_chunks:', loaded_chunks);
        const blocks_to_delete = [];
        const [deleted_chunks, live_chunks] = _.partition(loaded_chunks, chunk => Boolean(chunk.to_db().deleted));
        for (const chunk of deleted_chunks) {
            for (const frag of chunk.frags) {
                for (const block of frag.blocks) {
                    if (!block.to_db().deleted) {
                        dbg.log0('found unreferenced blocks of a deleted chunk', block);
                        blocks_to_delete.push(block);
                    }
                }
            }
        }
        const chunks_to_delete = [];
        const chunks_to_build = [];
        await P.map(live_chunks, async chunk => {
            try {
                if (!chunk.parts || !chunk.parts.length) {
                    const last_hour = this.start_run - (60 * 60 * 1000); 
                    dbg.log0('unreferenced chunk to delete', chunk);
                    if (chunk._id.getTimestamp().getTime() > last_hour) return;
                    chunks_to_delete.push(chunk);
                    return;
                }
                chunks_to_build.push(chunk);
            } catch (err) {
                dbg.error(`failed to load chunk ${chunk._id} for builder`, err);
            }
        });
        const chunks_to_delete_uniq = _.uniqBy(chunks_to_delete, chunk => chunk._id.toHexString());
        dbg.log1('MapBuilder.update_db:',
            'chunks_to_build', chunks_to_build.length,
            'chunks_to_delete_uniq', chunks_to_delete_uniq.length,
            'blocks_to_delete', blocks_to_delete.length);
        await Promise.all([
            map_deleter.delete_blocks(blocks_to_delete),
            map_deleter.delete_chunks(chunks_to_delete_uniq),
        ]);
        return chunks_to_build;
    }
async reload_chunks ( chunk_ids ) { const loaded_chunks_db = await MDStore . instance ( ) . find_chunks_by_ids ( chunk_ids ) ; await Promise . all ( [ MDStore . instance ( ) . load_parts_objects_for_chunks ( loaded_chunks_db ) , MDStore . instance ( ) . load_blocks_for_chunks ( loaded_chunks_db ) ] ) ; const loaded_chunks = loaded_chunks_db . map ( chunk_db => new ChunkDB ( chunk_db ) ) ; dbg . log1 ( 'MapBuilder.reload_chunks:' , loaded_chunks ) ; const blocks_to_delete = [ ] ; const [ deleted_chunks , live_chunks ] = _ . partition ( loaded_chunks , chunk => Boolean ( chunk . to_db ( ) . deleted ) ) ; for ( const chunk of deleted_chunks ) { for ( const frag of chunk . frags ) { for ( const block of frag . blocks ) { if ( ! block . to_db ( ) . deleted ) { dbg . log0 ( 'found unreferenced blocks of a deleted chunk' , block ) ; blocks_to_delete . push ( block ) ; } } } } const chunks_to_delete = [ ] ; const chunks_to_build = [ ] ; await P . map ( live_chunks , async chunk => { try { if ( ! chunk . parts || ! chunk . parts . length ) { const last_hour = this . start_run - ( 60 * 60 * 1000 ) ; dbg . log0 ( 'unreferenced chunk to delete' , chunk ) ; if ( chunk . _id . getTimestamp ( ) . getTime ( ) > last_hour ) return ; chunks_to_delete . push ( chunk ) ; return ; } chunks_to_build . push ( chunk ) ; } catch ( err ) { dbg . error ( ` ${ chunk . _id } ` , err ) ; } } ) ; const chunks_to_delete_uniq = _ . uniqBy ( chunks_to_delete , chunk => chunk . _id . toHexString ( ) ) ; dbg . log1 ( 'MapBuilder.update_db:' , 'chunks_to_build' , chunks_to_build . length , 'chunks_to_delete_uniq' , chunks_to_delete_uniq . length , 'blocks_to_delete' , blocks_to_delete . length ) ; await Promise . all ( [ map_deleter . delete_blocks ( blocks_to_delete ) , map_deleter . delete_chunks ( chunks_to_delete_uniq ) , ] ) ; return chunks_to_build ; }
In order to get the most relevant data regarding the chunks
 Note that there is always a possibility that the chunks will cease to exist
 TODO: We can release the unrelevant chunks from the surround_keys
 This will allow other batches to run if they wait on non existing chunks
 @param {nb.ID[]} chunk_ids
 @returns {Promise<nb.Chunk[]>}
In order to get the most relevant data regarding the chunks Note that there is always a possibility that the chunks will cease to exist TODO : We can release the unrelevant chunks from the surround_keys This will allow other batches to run if they wait on non existing chunks @param { nb . ID [] } chunk_ids @returns { Promise<nb . Chunk [] > }
/** @type {nb.Chunk[]} */ /** @type {nb.Block[]} */ // first look for deleted chunks, and set it's blocks for deletion // mark all live blocks of deleted chunks for deletion /** @type {nb.Chunk[] } */ /** @type {nb.Chunk[] } */ // TODO JACKY handle deleted tier // if (!chunk.tier) { //     await node_allocator.refresh_tiering_alloc(chunk.bucket.tiering); //     const tiering_status = node_allocator.get_tiering_status(chunk.bucket.tiering); //     chunk.tier = mapper.select_tier_for_write(chunk.bucket.tiering, tiering_status); // } // chunks that were created in the last hour will not be deleted