fn delete_all_in_range_cf_by_ingest(
        &self,
        cf: &str,
        sst_path: String,
        ranges: &[Range],
    ) -> Result<()> {
        let mut ranges = ranges.to_owned();
        ranges.sort_by(|a, b| a.start_key.cmp(b.start_key));
        let max_end_key = ranges
            .iter()
            .fold(ranges[0].end_key, |x, y| std::cmp::max(x, y.end_key));
        let start = KeyBuilder::from_slice(ranges[0].start_key, 0, 0);
        let end = KeyBuilder::from_slice(max_end_key, 0, 0);
        let mut opts = IterOptions::new(Some(start), Some(end), false);
        if self.is_titan() {
            // Cause DeleteFilesInRange may expose old blob index keys, setting key only for Titan
            // to avoid referring to missing blob files.
            opts.set_key_only(true);
        }

        let mut writer_wrapper: Option<RocksSstWriter> = None;
        let mut data: Vec<Vec<u8>> = vec![];
        let mut last_end_key: Option<Vec<u8>> = None;
        for r in ranges {
            // There may be a range overlap with next range
            if last_end_key
                .as_ref()
                .map_or(false, |key| key.as_slice() > r.start_key)
            {
                self.delete_all_in_range_cf_by_key(cf, &r)?;
                continue;
            }
            last_end_key = Some(r.end_key.to_owned());

            let mut it = self.iterator_cf_opt(cf, opts.clone())?;
            let mut it_valid = it.seek(r.start_key.into())?;
            while it_valid {
                if it.key() >= r.end_key {
                    break;
                }
                if let Some(writer) = writer_wrapper.as_mut() {
                    writer.delete(it.key())?;
                } else {
                    data.push(it.key().to_vec());
                }
                if data.len() > MAX_DELETE_COUNT_BY_KEY {
                    let builder = RocksSstWriterBuilder::new().set_db(self).set_cf(cf);
                    let mut writer = builder.build(sst_path.as_str())?;
                    for key in data.iter() {
                        writer.delete(key)?;
                    }
                    data.clear();
                    writer_wrapper = Some(writer);
                }
                it_valid = it.next()?;
            }
        }

        if let Some(writer) = writer_wrapper {
            writer.finish()?;
            self.ingest_external_file_cf(cf, &[sst_path.as_str()])?;
        } else {
            let mut wb = self.write_batch();
            for key in data.iter() {
                wb.delete_cf(cf, key)?;
                if wb.count() >= Self::WRITE_BATCH_MAX_KEYS {
                    wb.write()?;
                    wb.clear();
                }
            }
            if wb.count() > 0 {
                wb.write()?;
            }
        }
        Ok(())
    }
// We store all data which would be deleted in memory at first because the data of region will never be larger than
// max-region-size.
We store all data which would be deleted in memory at first because the data of region will never be larger than
max-region-size.
We store all data which would be deleted in memory at first because the data of region will never be larger than max - region - size .
fn delete_all_in_range_cf_by_ingest(
        &self,
        cf: &str,
        sst_path: String,
        ranges: &[Range],
    ) -> Result<()> {
        let mut ranges = ranges.to_owned();
        ranges.sort_by(|a, b| a.start_key.cmp(b.start_key));
        let max_end_key = ranges
            .iter()
            .fold(ranges[0].end_key, |x, y| std::cmp::max(x, y.end_key));
        let start = KeyBuilder::from_slice(ranges[0].start_key, 0, 0);
        let end = KeyBuilder::from_slice(max_end_key, 0, 0);
        let mut opts = IterOptions::new(Some(start), Some(end), false);
        if self.is_titan() {
            // Cause DeleteFilesInRange may expose old blob index keys, setting key only for Titan
            // to avoid referring to missing blob files.
            opts.set_key_only(true);
        }
        let mut writer_wrapper: Option<RocksSstWriter> = None;
        let mut data: Vec<Vec<u8>> = vec![];
        let mut last_end_key: Option<Vec<u8>> = None;
        for r in ranges {
            // There may be a range overlap with next range
            if last_end_key
                .as_ref()
                .map_or(false, |key| key.as_slice() > r.start_key)
            {
                self.delete_all_in_range_cf_by_key(cf, &r)?;
                continue;
            }
            last_end_key = Some(r.end_key.to_owned());
            let mut it = self.iterator_cf_opt(cf, opts.clone())?;
            let mut it_valid = it.seek(r.start_key.into())?;
            while it_valid {
                if it.key() >= r.end_key {
                    break;
                }
                if let Some(writer) = writer_wrapper.as_mut() {
                    writer.delete(it.key())?;
                } else {
                    data.push(it.key().to_vec());
                }
                if data.len() > MAX_DELETE_COUNT_BY_KEY {
                    let builder = RocksSstWriterBuilder::new().set_db(self).set_cf(cf);
                    let mut writer = builder.build(sst_path.as_str())?;
                    for key in data.iter() {
                        writer.delete(key)?;
                    }
                    data.clear();
                    writer_wrapper = Some(writer);
                }
                it_valid = it.next()?;
            }
        }
        if let Some(writer) = writer_wrapper {
            writer.finish()?;
            self.ingest_external_file_cf(cf, &[sst_path.as_str()])?;
        } else {
            let mut wb = self.write_batch();
            for key in data.iter() {
                wb.delete_cf(cf, key)?;
                if wb.count() >= Self::WRITE_BATCH_MAX_KEYS {
                    wb.write()?;
                    wb.clear();
                }
            }
            if wb.count() > 0 {
                wb.write()?;
            }
        }
        Ok(())
    }
fn delete_all_in_range_cf_by_ingest ( & self , cf : & str , sst_path : String , ranges : & [ Range ] , ) -> Result < ( ) > { let mut ranges = ranges . to_owned ( ) ; ranges . sort_by ( | a , b | a . start_key . cmp ( b . start_key ) ) ; let max_end_key = ranges . iter ( ) . fold ( ranges [ 0 ] . end_key , | x , y | std :: cmp :: max ( x , y . end_key ) ) ; let start = KeyBuilder :: from_slice ( ranges [ 0 ] . start_key , 0 , 0 ) ; let end = KeyBuilder :: from_slice ( max_end_key , 0 , 0 ) ; let mut opts = IterOptions :: new ( Some ( start ) , Some ( end ) , false ) ; if self . is_titan ( ) { // Cause DeleteFilesInRange may expose old blob index keys, setting key only for Titan // to avoid referring to missing blob files. opts . set_key_only ( true ) ; } let mut writer_wrapper : Option < RocksSstWriter > = None ; let mut data : Vec < Vec < u8 > > = vec ! [ ] ; let mut last_end_key : Option < Vec < u8 > > = None ; for r in ranges { // There may be a range overlap with next range if last_end_key . as_ref ( ) . map_or ( false , | key | key . as_slice ( ) > r . start_key ) { self . delete_all_in_range_cf_by_key ( cf , & r ) ? ; continue ; } last_end_key = Some ( r . end_key . to_owned ( ) ) ; let mut it = self . iterator_cf_opt ( cf , opts . clone ( ) ) ? ; let mut it_valid = it . seek ( r . start_key . into ( ) ) ? ; while it_valid { if it . key ( ) >= r . end_key { break ; } if let Some ( writer ) = writer_wrapper . as_mut ( ) { writer . delete ( it . key ( ) ) ? ; } else { data . push ( it . key ( ) . to_vec ( ) ) ; } if data . len ( ) > MAX_DELETE_COUNT_BY_KEY { let builder = RocksSstWriterBuilder :: new ( ) . set_db ( self ) . set_cf ( cf ) ; let mut writer = builder . build ( sst_path . as_str ( ) ) ? ; for key in data . iter ( ) { writer . delete ( key ) ? ; } data . clear ( ) ; writer_wrapper = Some ( writer ) ; } it_valid = it . next ( ) ? ; } } if let Some ( writer ) = writer_wrapper { writer . finish ( ) ? ; self . ingest_external_file_cf ( cf , & [ sst_path . as_str ( ) ] ) ? ; } else { let mut wb = self . write_batch ( ) ; for key in data . iter ( ) { wb . delete_cf ( cf , key ) ? ; if wb . count ( ) >= Self :: WRITE_BATCH_MAX_KEYS { wb . write ( ) ? ; wb . clear ( ) ; } } if wb . count ( ) > 0 { wb . write ( ) ? ; } } Ok ( ( ) ) }
We store all data which would be deleted in memory at first because the data of region will never be larger than
max-region-size.
We store all data which would be deleted in memory at first because the data of region will never be larger than max - region - size .
&self
cf
&str
sst_path
String
ranges
&[Range]