Repository: qdrant/qdrant
File: lib/gridstore/src/gridstore.rs (Rust)

Code before:
    /// not allow further usage. Use [`clear`](Self::clear) instead to clear and reuse the storage.
    pub fn wipe(self) -> Result<()> {
        let base_path = self.base_path.clone();

        // Wait for all background flush operations to finish, abort pending flushes
        self.is_alive_flush_lock.blocking_mark_dead();

        // Make sure strong references are dropped, to avoid starting another flush
        drop(self);

        // deleted base directory
        fs::remove_dir_all(base_path).map_err(|err| {
            GridstoreError::service_error(format!(
                "Failed to remove gridstore storage directory: {err}"
            ))
        })
    }

    /// Iterate over all the values in the storage
    ///
    /// Stops when the callback returns Ok(false)
    pub fn iter<F, E>(
        &self,
        mut callback: F,
        hw_counter: HwMetricRefCounter,
    ) -> std::result::Result<(), Either<E, GridstoreError>>
    where
        F: FnMut(PointOffset, V) -> std::result::Result<bool, E>,
    {
        const BUFFER_SIZE: usize = 128;
        let max_point_offset = self.max_point_offset();

        let mut from = 0;
        let mut buffer = Vec::with_capacity(min(BUFFER_SIZE, max_point_offset as usize));

        loop {
            // Collect pointers into a buffer while holding the lock
            buffer.clear();
            buffer.extend(
                self.tracker
                    .read()
                    .iter_pointers(from)
                    .filter_map(|(point_offset, opt_pointer)| {
                        opt_pointer.map(|pointer| (point_offset, pointer))
                    })
                    .take(BUFFER_SIZE),
            );

            // If no more pointers, we're done
            if buffer.is_empty() {
                break;

Review comment (suggestion):
Would `where E: From<GridstoreError>` work here? This way we can get rid of `Either`, `?` would work on `GridstoreError`.

Code after:
    /// Wipe the storage, drop all pages and delete the base directory
    ///
    /// Takes ownership because this function leaves Gridstore in an inconsistent state which does
    /// not allow further usage. Use [`clear`](Self::clear) instead to clear and reuse the storage.
    pub fn wipe(self) -> Result<()> {
        let base_path = self.base_path.clone();

        // Wait for all background flush operations to finish, abort pending flushes
        self.is_alive_flush_lock.blocking_mark_dead();

        // Make sure strong references are dropped, to avoid starting another flush
        drop(self);

        // deleted base directory
        fs::remove_dir_all(base_path).map_err(|err| {
            GridstoreError::service_error(format!(
                "Failed to remove gridstore storage directory: {err}"
            ))
        })
    }

    /// Iterate over all the values in the storage
    ///
    /// Stops when the callback returns Ok(false)
    pub fn iter<F, E>(
        &self,
        mut callback: F,
        hw_counter: HwMetricRefCounter,
    ) -> std::result::Result<(), E>
    where
        F: FnMut(PointOffset, V) -> std::result::Result<bool, E>,
        E: From<GridstoreError>,
    {
        const BUFFER_SIZE: usize = 128;
        let max_point_offset = self.max_point_offset();

        let mut from = 0;
        let mut buffer = Vec::with_capacity(min(BUFFER_SIZE, max_point_offset as usize));

        loop {
            // Collect pointers into a buffer while holding the lock
            buffer.clear();
            buffer.extend(
                self.tracker
                    .read()
                    .iter_pointers(from)
                    .filter_map(|(point_offset, opt_pointer)| {
                        opt_pointer.map(|pointer| (point_offset, pointer))
                    })
                    .take(BUFFER_SIZE),
            );