use std::alloc::Layout;
use std::borrow::Cow;
use std::fmt;
use std::mem::MaybeUninit;
use std::ops::Range;
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;

use bitvec::prelude::BitSlice;
use common::counter::hardware_counter::HardwareCounterCell;
use common::maybe_uninit::maybe_uninit_fill_from;
use common::types::PointOffsetType;
use sparse::common::sparse_vector::SparseVector;

use super::dense::memmap_dense_vector_storage::MemmapDenseVectorStorage;
#[cfg(feature = "rocksdb")]
use super::dense::simple_dense_vector_storage::SimpleDenseVectorStorage;
use super::dense::volatile_dense_vector_storage::VolatileDenseVectorStorage;
use super::multi_dense::appendable_mmap_multi_dense_vector_storage::AppendableMmapMultiDenseVectorStorage;
#[cfg(feature = "rocksdb")]
use super::multi_dense::simple_multi_dense_vector_storage::SimpleMultiDenseVectorStorage;
use super::multi_dense::volatile_multi_dense_vector_storage::VolatileMultiDenseVectorStorage;
use super::sparse::mmap_sparse_vector_storage::MmapSparseVectorStorage;
use super::sparse::volatile_sparse_vector_storage::VolatileSparseVectorStorage;
use crate::common::Flusher;
use crate::common::operation_error::{OperationError, OperationResult};
use crate::data_types::named_vectors::{CowMultiVector, CowVector};
use crate::data_types::primitive::PrimitiveVectorElement;
use crate::data_types::vectors::{
    MultiDenseVectorInternal, VectorElementType, VectorElementTypeByte, VectorElementTypeHalf,
    VectorInternal, VectorRef,
};
use crate::types::{Distance, MultiVectorConfig, VectorStorageDatatype};
use crate::vector_storage::common::VECTOR_READ_BATCH_SIZE;
use crate::vector_storage::dense::appendable_dense_vector_storage::AppendableMmapDenseVectorStorage;
#[cfg(feature = "rocksdb")]
use crate::vector_storage::sparse::simple_sparse_vector_storage::SimpleSparseVectorStorage;

/// In case of simple vector storage, vector offset is the same as [`PointOffsetType`].
/// But in case of multivectors, it requires an additional lookup.
pub type VectorOffsetType = usize;

/// Generalized vector offset.
pub trait VectorOffset: Copy + fmt::Display + fmt::Debug {
    fn offset(self) -> VectorOffsetType;
}

impl VectorOffset for PointOffsetType {
    fn offset(self) -> VectorOffsetType {
        self as VectorOffsetType
    }
}

impl VectorOffset for VectorOffsetType {
    fn offset(self) -> VectorOffsetType {
        self
    }
}

pub trait AccessPattern: Copy {
    const IS_SEQUENTIAL: bool;
}

#[derive(Copy, Clone)]
pub struct Random;

#[derive(Copy, Clone)]
pub struct Sequential;

impl AccessPattern for Random {
    const IS_SEQUENTIAL: bool = false;
}

impl AccessPattern for Sequential {
    const IS_SEQUENTIAL: bool = true;
}

/// Trait for vector storage
/// El - type of vector element, expected numerical type
/// Storage operates with internal IDs (`PointOffsetType`), which always starts with zero and have no skips
pub trait VectorStorage {
    fn distance(&self) -> Distance;

    fn datatype(&self) -> VectorStorageDatatype;

    fn is_on_disk(&self) -> bool;

    /// Number of vectors
    ///
    /// - includes soft deleted vectors, as they are still stored
    fn total_vector_count(&self) -> usize;

    /// Get the number of available vectors, considering deleted points and vectors
    ///
    /// This uses [`VectorStorage::total_vector_count`] and [`VectorStorage::deleted_vector_count`] internally.
    ///
    /// # Warning
    ///
    /// This number may not always be accurate. See warning in [`VectorStorage::deleted_vector_count`] documentation.
    fn available_vector_count(&self) -> usize {
        self.total_vector_count()
            .saturating_sub(self.deleted_vector_count())
    }

    /// Get the vector by the given key
    /// Get the vector by the given key with potential optimizations for sequential reads.
    fn get_vector<P: AccessPattern>(&self, key: PointOffsetType) -> CowVector<'_>;

    /// Get multiple vectors by the given keys
    /// Potentially optimized for internal parallel reads.
    fn read_vectors<P: AccessPattern>(
        &self,
        keys: impl IntoIterator<Item = PointOffsetType>,
        mut callback: impl FnMut(PointOffsetType, CowVector<'_>),
    ) {
        for key in keys {
            callback(key, self.get_vector::<P>(key));
        }
    }

    /// Get the vector by the given key if it exists
    fn get_vector_opt<P: AccessPattern>(&self, key: PointOffsetType) -> Option<CowVector<'_>>;

    fn insert_vector(
        &mut self,
        key: PointOffsetType,
        vector: VectorRef,
        hw_counter: &HardwareCounterCell,
    ) -> OperationResult<()>;

    /// Add the given vectors to the storage.
    ///
    /// # Returns
    /// The range of point offsets that were added to the storage.
    ///
    /// If stopped, the operation returns a cancellation error.
    fn update_from<'a>(
        &mut self,
        other_vectors: &'a mut impl Iterator<Item = (CowVector<'a>, bool)>,
        stopped: &AtomicBool,
    ) -> OperationResult<Range<PointOffsetType>>;

    fn flusher(&self) -> Flusher;

    fn files(&self) -> Vec<PathBuf>;

    fn immutable_files(&self) -> Vec<PathBuf> {
        Vec::new()
    }

    /// Flag the vector by the given key as deleted
    ///
    /// Returns true if the vector was not deleted before and is now deleted
    fn delete_vector(&mut self, key: PointOffsetType) -> OperationResult<bool>;

    /// Check whether the vector at the given key is flagged as deleted
    fn is_deleted_vector(&self, key: PointOffsetType) -> bool;

    /// Get the number of deleted vectors, considering deleted points and vectors
    ///
    /// Vectors may be deleted at two levels, as point or as vector. Deleted points should
    /// propagate to deleting the vectors. That means that the deleted vector count includes the
    /// number of deleted points as well.
    ///
    /// This includes any vectors that were deleted at creation.
    ///
    /// # Warning
    ///
    /// In some very exceptional cases it is possible for this count not to include some deleted
    /// points. That may happen when flushing a segment to disk fails. This should be recovered
    /// when loading/recovering the segment, but that isn't guaranteed. You should therefore use
    /// the deleted count with care.
    fn deleted_vector_count(&self) -> usize;

    /// Get [`BitSlice`] representation for deleted vectors with deletion flags
    ///
    /// The size of this slice is not guaranteed. It may be smaller/larger than the number of
    /// vectors in this segment.
    fn deleted_vector_bitslice(&self) -> &BitSlice;
}

pub trait DenseVectorStorage<T: PrimitiveVectorElement>: VectorStorage {
    fn vector_dim(&self) -> usize;

    fn get_dense<P: AccessPattern>(&self, key: PointOffsetType) -> Cow<'_, [T]>;

    /// Get the raw bytes of the vector by the given key if it exists
    fn get_dense_bytes_opt<P: AccessPattern>(&self, key: PointOffsetType) -> Option<Cow<'_, [u8]>> {
        ((key as usize) < self.total_vector_count()).then(|| match self.get_dense::<P>(key) {
            Cow::Borrowed(slice) => Cow::Borrowed(bytemuck::cast_slice(slice)),
            Cow::Owned(vec) => Cow::Owned(bytemuck::cast_vec(vec)),
        })
    }

    /// Get layout for a single vector
    fn get_dense_vector_layout(&self) -> OperationResult<Layout> {
        Layout::array::<T>(self.vector_dim())
            .map_err(|_| OperationError::service_error("Layout is too big"))
    }

    /// Run given function for each vector in the dense batch.
    ///
    /// Implementation can assume that the keys are consecutive
    fn for_each_in_dense_batch<F: FnMut(usize, &[T])>(&self, keys: &[PointOffsetType], mut f: F) {
        for (idx, &key) in keys.iter().enumerate() {
            f(idx, &self.get_dense::<Random>(key));
        }
    }

    fn size_of_available_vectors_in_bytes(&self) -> usize {
        self.available_vector_count() * self.vector_dim() * std::mem::size_of::<T>()
    }
}

pub trait SparseVectorStorage: VectorStorage {
    fn get_sparse<P: AccessPattern>(&self, key: PointOffsetType) -> OperationResult<SparseVector>;
    fn get_sparse_opt<P: AccessPattern>(
        &self,
        key: PointOffsetType,
    ) -> OperationResult<Option<SparseVector>>;
}

pub trait MultiVectorStorage<T: PrimitiveVectorElement>: VectorStorage {
    fn vector_dim(&self) -> usize;
    fn get_multi<P: AccessPattern>(&self, key: PointOffsetType) -> CowMultiVector<'_, T>;
    fn get_multi_opt<P: AccessPattern>(
        &self,
        key: PointOffsetType,
    ) -> Option<CowMultiVector<'_, T>>;
    fn get_batch_multi<'a>(
        &'a self,
        keys: &[PointOffsetType],
        vectors: &'a mut [MaybeUninit<CowMultiVector<'a, T>>],
    ) -> &'a [CowMultiVector<'a, T>] {
        debug_assert_eq!(keys.len(), vectors.len());
        debug_assert!(keys.len() <= VECTOR_READ_BATCH_SIZE);
        let iter = keys.iter().map(|key| self.get_multi::<Random>(*key));
        maybe_uninit_fill_from(vectors, iter).0
    }
    fn iterate_inner_vectors(&self) -> impl Iterator<Item = Cow<'_, [T]>> + Clone + Send;
    fn multi_vector_config(&self) -> &MultiVectorConfig;

    fn size_of_available_vectors_in_bytes(&self) -> usize;
}

#[derive(Debug)]
pub enum VectorStorageEnum {
    #[cfg(feature = "rocksdb")]
    DenseSimple(SimpleDenseVectorStorage<VectorElementType>),
    #[cfg(feature = "rocksdb")]
    DenseSimpleByte(SimpleDenseVectorStorage<VectorElementTypeByte>),
    #[cfg(feature = "rocksdb")]
    DenseSimpleHalf(SimpleDenseVectorStorage<VectorElementTypeHalf>),
    DenseVolatile(VolatileDenseVectorStorage<VectorElementType>),
    #[cfg(test)]
    DenseVolatileByte(VolatileDenseVectorStorage<VectorElementTypeByte>),
    #[cfg(test)]
    DenseVolatileHalf(VolatileDenseVectorStorage<VectorElementTypeHalf>),
    DenseMemmap(Box<MemmapDenseVectorStorage<VectorElementType>>),
    DenseMemmapByte(Box<MemmapDenseVectorStorage<VectorElementTypeByte>>),
    DenseMemmapHalf(Box<MemmapDenseVectorStorage<VectorElementTypeHalf>>),
    DenseAppendableMemmap(Box<AppendableMmapDenseVectorStorage<VectorElementType>>),
    DenseAppendableMemmapByte(Box<AppendableMmapDenseVectorStorage<VectorElementTypeByte>>),
    DenseAppendableMemmapHalf(Box<AppendableMmapDenseVectorStorage<VectorElementTypeHalf>>),
    #[cfg(feature = "rocksdb")]
    SparseSimple(SimpleSparseVectorStorage),
    SparseVolatile(VolatileSparseVectorStorage),
    SparseMmap(MmapSparseVectorStorage),
    #[cfg(feature = "rocksdb")]
    MultiDenseSimple(SimpleMultiDenseVectorStorage<VectorElementType>),
    #[cfg(feature = "rocksdb")]
    MultiDenseSimpleByte(SimpleMultiDenseVectorStorage<VectorElementTypeByte>),
    #[cfg(feature = "rocksdb")]
    MultiDenseSimpleHalf(SimpleMultiDenseVectorStorage<VectorElementTypeHalf>),
    MultiDenseVolatile(VolatileMultiDenseVectorStorage<VectorElementType>),
    #[cfg(test)]
    MultiDenseVolatileByte(VolatileMultiDenseVectorStorage<VectorElementTypeByte>),
    #[cfg(test)]
    MultiDenseVolatileHalf(VolatileMultiDenseVectorStorage<VectorElementTypeHalf>),
    MultiDenseAppendableMemmap(Box<AppendableMmapMultiDenseVectorStorage<VectorElementType>>),
    MultiDenseAppendableMemmapByte(
        Box<AppendableMmapMultiDenseVectorStorage<VectorElementTypeByte>>,
    ),
    MultiDenseAppendableMemmapHalf(
        Box<AppendableMmapMultiDenseVectorStorage<VectorElementTypeHalf>>,
    ),
}

impl VectorStorageEnum {
    pub fn try_multi_vector_config(&self) -> Option<&MultiVectorConfig> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(_) => None,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(_) => None,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(_) => None,
            VectorStorageEnum::DenseVolatile(_) => None,
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(_) => None,
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(_) => None,
            VectorStorageEnum::DenseMemmap(_) => None,
            VectorStorageEnum::DenseMemmapByte(_) => None,
            VectorStorageEnum::DenseMemmapHalf(_) => None,
            VectorStorageEnum::DenseAppendableMemmap(_) => None,
            VectorStorageEnum::DenseAppendableMemmapByte(_) => None,
            VectorStorageEnum::DenseAppendableMemmapHalf(_) => None,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(_) => None,
            VectorStorageEnum::SparseVolatile(_) => None,
            VectorStorageEnum::SparseMmap(_) => None,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(s) => Some(s.multi_vector_config()),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(s) => Some(s.multi_vector_config()),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(s) => Some(s.multi_vector_config()),
            VectorStorageEnum::MultiDenseVolatile(s) => Some(s.multi_vector_config()),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(s) => Some(s.multi_vector_config()),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(s) => Some(s.multi_vector_config()),
            VectorStorageEnum::MultiDenseAppendableMemmap(s) => Some(s.multi_vector_config()),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(s) => Some(s.multi_vector_config()),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(s) => Some(s.multi_vector_config()),
        }
    }

    pub(crate) fn default_vector(&self) -> VectorInternal {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => VectorInternal::from(vec![1.0; v.vector_dim()]),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => {
                VectorInternal::from(vec![1.0; v.vector_dim()])
            }
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => {
                VectorInternal::from(vec![1.0; v.vector_dim()])
            }
            VectorStorageEnum::DenseVolatile(v) => VectorInternal::from(vec![1.0; v.vector_dim()]),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => {
                VectorInternal::from(vec![1.0; v.vector_dim()])
            }
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => {
                VectorInternal::from(vec![1.0; v.vector_dim()])
            }
            VectorStorageEnum::DenseMemmap(v) => VectorInternal::from(vec![1.0; v.vector_dim()]),
            VectorStorageEnum::DenseMemmapByte(v) => {
                VectorInternal::from(vec![1.0; v.vector_dim()])
            }
            VectorStorageEnum::DenseMemmapHalf(v) => {
                VectorInternal::from(vec![1.0; v.vector_dim()])
            }
            VectorStorageEnum::DenseAppendableMemmap(v) => {
                VectorInternal::from(vec![1.0; v.vector_dim()])
            }
            VectorStorageEnum::DenseAppendableMemmapByte(v) => {
                VectorInternal::from(vec![1.0; v.vector_dim()])
            }
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => {
                VectorInternal::from(vec![1.0; v.vector_dim()])
            }
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(_) => VectorInternal::from(SparseVector::default()),
            VectorStorageEnum::SparseVolatile(_) => VectorInternal::from(SparseVector::default()),
            VectorStorageEnum::SparseMmap(_) => VectorInternal::from(SparseVector::default()),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => {
                VectorInternal::from(MultiDenseVectorInternal::placeholder(v.vector_dim()))
            }
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => {
                VectorInternal::from(MultiDenseVectorInternal::placeholder(v.vector_dim()))
            }
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => {
                VectorInternal::from(MultiDenseVectorInternal::placeholder(v.vector_dim()))
            }
            VectorStorageEnum::MultiDenseVolatile(v) => {
                VectorInternal::from(MultiDenseVectorInternal::placeholder(v.vector_dim()))
            }
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => {
                VectorInternal::from(MultiDenseVectorInternal::placeholder(v.vector_dim()))
            }
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => {
                VectorInternal::from(MultiDenseVectorInternal::placeholder(v.vector_dim()))
            }
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => {
                VectorInternal::from(MultiDenseVectorInternal::placeholder(v.vector_dim()))
            }
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => {
                VectorInternal::from(MultiDenseVectorInternal::placeholder(v.vector_dim()))
            }
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => {
                VectorInternal::from(MultiDenseVectorInternal::placeholder(v.vector_dim()))
            }
        }
    }

    pub fn size_of_available_vectors_in_bytes(&self) -> usize {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.size_of_available_vectors_in_bytes(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.size_of_available_vectors_in_bytes(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::DenseVolatile(v) => v.size_of_available_vectors_in_bytes(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.size_of_available_vectors_in_bytes(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::DenseMemmap(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::DenseMemmapByte(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => {
                v.size_of_available_vectors_in_bytes()
            }
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => {
                v.size_of_available_vectors_in_bytes()
            }
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::SparseVolatile(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::SparseMmap(_v) => {
                unreachable!(
                    "Mmap sparse storage does not know its total size, get from index instead"
                )
            }
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.size_of_available_vectors_in_bytes(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.size_of_available_vectors_in_bytes(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.size_of_available_vectors_in_bytes(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.size_of_available_vectors_in_bytes(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.size_of_available_vectors_in_bytes(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => {
                v.size_of_available_vectors_in_bytes()
            }
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => {
                v.size_of_available_vectors_in_bytes()
            }
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => {
                v.size_of_available_vectors_in_bytes()
            }
        }
    }

    pub fn populate(&self) -> OperationResult<()> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(_) => {} // Can't populate as it is not mmap
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(_) => {} // Can't populate as it is not mmap
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::DenseVolatile(_) => {} // Can't populate as it is not mmap
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(_) => {} // Can't populate as it is not mmap
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::DenseMemmap(vs) => vs.populate(),
            VectorStorageEnum::DenseMemmapByte(vs) => vs.populate(),
            VectorStorageEnum::DenseMemmapHalf(vs) => vs.populate(),
            VectorStorageEnum::DenseAppendableMemmap(vs) => vs.populate()?,
            VectorStorageEnum::DenseAppendableMemmapByte(vs) => vs.populate()?,
            VectorStorageEnum::DenseAppendableMemmapHalf(vs) => vs.populate()?,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::SparseVolatile(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::SparseMmap(vs) => vs.populate()?,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(_) => {} // Can't populate as it is not mmap
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(_) => {} // Can't populate as it is not mmap
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::MultiDenseVolatile(_) => {} // Can't populate as it is not mmap
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(_) => {} // Can't populate as it is not mmap
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::MultiDenseAppendableMemmap(vs) => vs.populate()?,
            VectorStorageEnum::MultiDenseAppendableMemmapByte(vs) => vs.populate()?,
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(vs) => vs.populate()?,
        }
        Ok(())
    }

    pub fn clear_cache(&self) -> OperationResult<()> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(_) => {} // Can't populate as it is not mmap
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(_) => {} // Can't populate as it is not mmap
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::DenseVolatile(_) => {} // Can't populate as it is not mmap
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(_) => {} // Can't populate as it is not mmap
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::DenseMemmap(vs) => vs.clear_cache()?,
            VectorStorageEnum::DenseMemmapByte(vs) => vs.clear_cache()?,
            VectorStorageEnum::DenseMemmapHalf(vs) => vs.clear_cache()?,
            VectorStorageEnum::DenseAppendableMemmap(vs) => vs.clear_cache()?,
            VectorStorageEnum::DenseAppendableMemmapByte(vs) => vs.clear_cache()?,
            VectorStorageEnum::DenseAppendableMemmapHalf(vs) => vs.clear_cache()?,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::SparseVolatile(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::SparseMmap(vs) => vs.clear_cache()?,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(_) => {} // Can't populate as it is not mmap
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(_) => {} // Can't populate as it is not mmap
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::MultiDenseVolatile(_) => {} // Can't populate as it is not mmap
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(_) => {} // Can't populate as it is not mmap
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(_) => {} // Can't populate as it is not mmap
            VectorStorageEnum::MultiDenseAppendableMemmap(vs) => vs.clear_cache()?,
            VectorStorageEnum::MultiDenseAppendableMemmapByte(vs) => vs.clear_cache()?,
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(vs) => vs.clear_cache()?,
        }
        Ok(())
    }

    /// Get the raw bytes of the vector by the given key if it exists
    pub fn get_vector_bytes_opt<P: AccessPattern>(
        &self,
        key: PointOffsetType,
    ) -> Option<Cow<'_, [u8]>> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.get_dense_bytes_opt::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.get_dense_bytes_opt::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.get_dense_bytes_opt::<P>(key),
            VectorStorageEnum::DenseVolatile(v) => v.get_dense_bytes_opt::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.get_dense_bytes_opt::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.get_dense_bytes_opt::<P>(key),
            VectorStorageEnum::DenseMemmap(v) => v.get_dense_bytes_opt::<P>(key),
            VectorStorageEnum::DenseMemmapByte(v) => v.get_dense_bytes_opt::<P>(key),
            VectorStorageEnum::DenseMemmapHalf(v) => v.get_dense_bytes_opt::<P>(key),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.get_dense_bytes_opt::<P>(key),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.get_dense_bytes_opt::<P>(key),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.get_dense_bytes_opt::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(_) => None,
            VectorStorageEnum::SparseVolatile(_) => None,
            VectorStorageEnum::SparseMmap(_) => None,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(_) => None,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(_) => None,
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(_) => None,
            VectorStorageEnum::MultiDenseVolatile(_) => None,
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(_) => None,
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(_) => None,
            VectorStorageEnum::MultiDenseAppendableMemmap(_) => None,
            VectorStorageEnum::MultiDenseAppendableMemmapByte(_) => None,
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(_) => None,
        }
    }

    /// Get layout for a single vector
    pub fn get_vector_layout(&self) -> OperationResult<Layout> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => return v.get_dense_vector_layout(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => return v.get_dense_vector_layout(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => return v.get_dense_vector_layout(),
            VectorStorageEnum::DenseVolatile(v) => return v.get_dense_vector_layout(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => return v.get_dense_vector_layout(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => return v.get_dense_vector_layout(),
            VectorStorageEnum::DenseMemmap(v) => return v.get_dense_vector_layout(),
            VectorStorageEnum::DenseMemmapByte(v) => return v.get_dense_vector_layout(),
            VectorStorageEnum::DenseMemmapHalf(v) => return v.get_dense_vector_layout(),
            VectorStorageEnum::DenseAppendableMemmap(v) => return v.get_dense_vector_layout(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => return v.get_dense_vector_layout(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => return v.get_dense_vector_layout(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(_) => {}
            VectorStorageEnum::SparseVolatile(_) => {}
            VectorStorageEnum::SparseMmap(_) => {}
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(_) => {}
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(_) => {}
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(_) => {}
            VectorStorageEnum::MultiDenseVolatile(_) => {}
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(_) => {}
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(_) => {}
            VectorStorageEnum::MultiDenseAppendableMemmap(_) => {}
            VectorStorageEnum::MultiDenseAppendableMemmapByte(_) => {}
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(_) => {}
        }
        Err(OperationError::service_error(
            "Vector layout is not implemented for this storage",
        ))
    }
}

impl VectorStorage for VectorStorageEnum {
    fn distance(&self) -> Distance {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.distance(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.distance(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.distance(),
            VectorStorageEnum::DenseVolatile(v) => v.distance(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.distance(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.distance(),
            VectorStorageEnum::DenseMemmap(v) => v.distance(),
            VectorStorageEnum::DenseMemmapByte(v) => v.distance(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.distance(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.distance(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.distance(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.distance(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.distance(),
            VectorStorageEnum::SparseVolatile(v) => v.distance(),
            VectorStorageEnum::SparseMmap(v) => v.distance(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.distance(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.distance(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.distance(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.distance(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.distance(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.distance(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.distance(),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.distance(),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.distance(),
        }
    }

    fn datatype(&self) -> VectorStorageDatatype {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.datatype(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.datatype(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.datatype(),
            VectorStorageEnum::DenseVolatile(v) => v.datatype(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.datatype(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.datatype(),
            VectorStorageEnum::DenseMemmap(v) => v.datatype(),
            VectorStorageEnum::DenseMemmapByte(v) => v.datatype(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.datatype(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.datatype(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.datatype(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.datatype(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.datatype(),
            VectorStorageEnum::SparseVolatile(v) => v.datatype(),
            VectorStorageEnum::SparseMmap(v) => v.datatype(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.datatype(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.datatype(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.datatype(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.datatype(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.datatype(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.datatype(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.datatype(),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.datatype(),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.datatype(),
        }
    }

    /// If false - data is stored in RAM (and persisted on disk)
    /// If true - data is stored on disk, and is not forced to be in RAM
    fn is_on_disk(&self) -> bool {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.is_on_disk(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.is_on_disk(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.is_on_disk(),
            VectorStorageEnum::DenseVolatile(v) => v.is_on_disk(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.is_on_disk(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.is_on_disk(),
            VectorStorageEnum::DenseMemmap(v) => v.is_on_disk(),
            VectorStorageEnum::DenseMemmapByte(v) => v.is_on_disk(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.is_on_disk(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.is_on_disk(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.is_on_disk(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.is_on_disk(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.is_on_disk(),
            VectorStorageEnum::SparseVolatile(v) => v.is_on_disk(),
            VectorStorageEnum::SparseMmap(v) => v.is_on_disk(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.is_on_disk(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.is_on_disk(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.is_on_disk(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.is_on_disk(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.is_on_disk(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.is_on_disk(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.is_on_disk(),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.is_on_disk(),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.is_on_disk(),
        }
    }

    fn total_vector_count(&self) -> usize {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.total_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.total_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.total_vector_count(),
            VectorStorageEnum::DenseVolatile(v) => v.total_vector_count(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.total_vector_count(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.total_vector_count(),
            VectorStorageEnum::DenseMemmap(v) => v.total_vector_count(),
            VectorStorageEnum::DenseMemmapByte(v) => v.total_vector_count(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.total_vector_count(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.total_vector_count(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.total_vector_count(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.total_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.total_vector_count(),
            VectorStorageEnum::SparseVolatile(v) => v.total_vector_count(),
            VectorStorageEnum::SparseMmap(v) => v.total_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.total_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.total_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.total_vector_count(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.total_vector_count(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.total_vector_count(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.total_vector_count(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.total_vector_count(),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.total_vector_count(),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.total_vector_count(),
        }
    }

    fn get_vector<P: AccessPattern>(&self, key: PointOffsetType) -> CowVector<'_> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.get_vector::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.get_vector::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.get_vector::<P>(key),
            VectorStorageEnum::DenseVolatile(v) => v.get_vector::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.get_vector::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.get_vector::<P>(key),
            VectorStorageEnum::DenseMemmap(v) => v.get_vector::<P>(key),
            VectorStorageEnum::DenseMemmapByte(v) => v.get_vector::<P>(key),
            VectorStorageEnum::DenseMemmapHalf(v) => v.get_vector::<P>(key),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.get_vector::<P>(key),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.get_vector::<P>(key),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.get_vector::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.get_vector::<P>(key),
            VectorStorageEnum::SparseVolatile(v) => v.get_vector::<P>(key),
            VectorStorageEnum::SparseMmap(v) => v.get_vector::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.get_vector::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.get_vector::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.get_vector::<P>(key),
            VectorStorageEnum::MultiDenseVolatile(v) => v.get_vector::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.get_vector::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.get_vector::<P>(key),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.get_vector::<P>(key),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.get_vector::<P>(key),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.get_vector::<P>(key),
        }
    }

    fn read_vectors<P: AccessPattern>(
        &self,
        keys: impl IntoIterator<Item = PointOffsetType>,
        callback: impl FnMut(PointOffsetType, CowVector<'_>),
    ) {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::DenseVolatile(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::DenseMemmap(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::DenseMemmapByte(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::DenseMemmapHalf(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::SparseVolatile(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::SparseMmap(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::MultiDenseVolatile(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.read_vectors::<P>(keys, callback),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.read_vectors::<P>(keys, callback),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => {
                v.read_vectors::<P>(keys, callback)
            }
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => {
                v.read_vectors::<P>(keys, callback)
            }
        }
    }

    fn get_vector_opt<P: AccessPattern>(&self, key: PointOffsetType) -> Option<CowVector<'_>> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.get_vector_opt::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.get_vector_opt::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::DenseVolatile(v) => v.get_vector_opt::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.get_vector_opt::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::DenseMemmap(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::DenseMemmapByte(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::DenseMemmapHalf(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.get_vector_opt::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::SparseVolatile(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::SparseMmap(v) => v.get_vector_opt::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.get_vector_opt::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.get_vector_opt::<P>(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::MultiDenseVolatile(v) => v.get_vector_opt::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.get_vector_opt::<P>(key),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.get_vector_opt::<P>(key),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.get_vector_opt::<P>(key),
        }
    }

    fn insert_vector(
        &mut self,
        key: PointOffsetType,
        vector: VectorRef,
        hw_counter: &HardwareCounterCell,
    ) -> OperationResult<()> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.insert_vector(key, vector, hw_counter),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.insert_vector(key, vector, hw_counter),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.insert_vector(key, vector, hw_counter),
            VectorStorageEnum::DenseVolatile(v) => v.insert_vector(key, vector, hw_counter),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.insert_vector(key, vector, hw_counter),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.insert_vector(key, vector, hw_counter),
            VectorStorageEnum::DenseMemmap(v) => v.insert_vector(key, vector, hw_counter),
            VectorStorageEnum::DenseMemmapByte(v) => v.insert_vector(key, vector, hw_counter),
            VectorStorageEnum::DenseMemmapHalf(v) => v.insert_vector(key, vector, hw_counter),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.insert_vector(key, vector, hw_counter),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => {
                v.insert_vector(key, vector, hw_counter)
            }
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => {
                v.insert_vector(key, vector, hw_counter)
            }
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.insert_vector(key, vector, hw_counter),
            VectorStorageEnum::SparseVolatile(v) => v.insert_vector(key, vector, hw_counter),
            VectorStorageEnum::SparseMmap(v) => v.insert_vector(key, vector, hw_counter),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.insert_vector(key, vector, hw_counter),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.insert_vector(key, vector, hw_counter),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.insert_vector(key, vector, hw_counter),
            VectorStorageEnum::MultiDenseVolatile(v) => v.insert_vector(key, vector, hw_counter),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => {
                v.insert_vector(key, vector, hw_counter)
            }
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => {
                v.insert_vector(key, vector, hw_counter)
            }
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => {
                v.insert_vector(key, vector, hw_counter)
            }
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => {
                v.insert_vector(key, vector, hw_counter)
            }
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => {
                v.insert_vector(key, vector, hw_counter)
            }
        }
    }

    fn update_from<'a>(
        &mut self,
        other_vectors: &'a mut impl Iterator<Item = (CowVector<'a>, bool)>,
        stopped: &AtomicBool,
    ) -> OperationResult<Range<PointOffsetType>> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.update_from(other_vectors, stopped),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.update_from(other_vectors, stopped),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::DenseVolatile(v) => v.update_from(other_vectors, stopped),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.update_from(other_vectors, stopped),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::DenseMemmap(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::DenseMemmapByte(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::DenseMemmapHalf(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => {
                v.update_from(other_vectors, stopped)
            }
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => {
                v.update_from(other_vectors, stopped)
            }
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::SparseVolatile(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::SparseMmap(v) => v.update_from(other_vectors, stopped),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.update_from(other_vectors, stopped),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.update_from(other_vectors, stopped),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::MultiDenseVolatile(v) => v.update_from(other_vectors, stopped),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.update_from(other_vectors, stopped),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.update_from(other_vectors, stopped),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => {
                v.update_from(other_vectors, stopped)
            }
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => {
                v.update_from(other_vectors, stopped)
            }
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => {
                v.update_from(other_vectors, stopped)
            }
        }
    }

    fn flusher(&self) -> Flusher {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.flusher(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.flusher(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.flusher(),
            VectorStorageEnum::DenseVolatile(v) => v.flusher(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.flusher(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.flusher(),
            VectorStorageEnum::DenseMemmap(v) => v.flusher(),
            VectorStorageEnum::DenseMemmapByte(v) => v.flusher(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.flusher(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.flusher(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.flusher(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.flusher(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.flusher(),
            VectorStorageEnum::SparseVolatile(v) => v.flusher(),
            VectorStorageEnum::SparseMmap(v) => v.flusher(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.flusher(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.flusher(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.flusher(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.flusher(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.flusher(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.flusher(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.flusher(),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.flusher(),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.flusher(),
        }
    }

    fn files(&self) -> Vec<PathBuf> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.files(),
            VectorStorageEnum::DenseVolatile(v) => v.files(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.files(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.files(),
            VectorStorageEnum::DenseMemmap(v) => v.files(),
            VectorStorageEnum::DenseMemmapByte(v) => v.files(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.files(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.files(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.files(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.files(),
            VectorStorageEnum::SparseVolatile(v) => v.files(),
            VectorStorageEnum::SparseMmap(v) => v.files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.files(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.files(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.files(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.files(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.files(),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.files(),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.files(),
        }
    }

    fn immutable_files(&self) -> Vec<PathBuf> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.immutable_files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.immutable_files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.immutable_files(),
            VectorStorageEnum::DenseVolatile(v) => v.immutable_files(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.immutable_files(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.immutable_files(),
            VectorStorageEnum::DenseMemmap(v) => v.immutable_files(),
            VectorStorageEnum::DenseMemmapByte(v) => v.immutable_files(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.immutable_files(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.immutable_files(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.immutable_files(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.immutable_files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.immutable_files(),
            VectorStorageEnum::SparseVolatile(v) => v.immutable_files(),
            VectorStorageEnum::SparseMmap(v) => v.immutable_files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.immutable_files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.immutable_files(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.immutable_files(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.immutable_files(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.immutable_files(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.immutable_files(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.immutable_files(),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.immutable_files(),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.immutable_files(),
        }
    }

    fn delete_vector(&mut self, key: PointOffsetType) -> OperationResult<bool> {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.delete_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.delete_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.delete_vector(key),
            VectorStorageEnum::DenseVolatile(v) => v.delete_vector(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.delete_vector(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.delete_vector(key),
            VectorStorageEnum::DenseMemmap(v) => v.delete_vector(key),
            VectorStorageEnum::DenseMemmapByte(v) => v.delete_vector(key),
            VectorStorageEnum::DenseMemmapHalf(v) => v.delete_vector(key),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.delete_vector(key),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.delete_vector(key),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.delete_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.delete_vector(key),
            VectorStorageEnum::SparseVolatile(v) => v.delete_vector(key),
            VectorStorageEnum::SparseMmap(v) => v.delete_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.delete_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.delete_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.delete_vector(key),
            VectorStorageEnum::MultiDenseVolatile(v) => v.delete_vector(key),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.delete_vector(key),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.delete_vector(key),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.delete_vector(key),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.delete_vector(key),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.delete_vector(key),
        }
    }

    fn is_deleted_vector(&self, key: PointOffsetType) -> bool {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.is_deleted_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.is_deleted_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.is_deleted_vector(key),
            VectorStorageEnum::DenseVolatile(v) => v.is_deleted_vector(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.is_deleted_vector(key),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.is_deleted_vector(key),
            VectorStorageEnum::DenseMemmap(v) => v.is_deleted_vector(key),
            VectorStorageEnum::DenseMemmapByte(v) => v.is_deleted_vector(key),
            VectorStorageEnum::DenseMemmapHalf(v) => v.is_deleted_vector(key),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.is_deleted_vector(key),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.is_deleted_vector(key),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.is_deleted_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.is_deleted_vector(key),
            VectorStorageEnum::SparseVolatile(v) => v.is_deleted_vector(key),
            VectorStorageEnum::SparseMmap(v) => v.is_deleted_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.is_deleted_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.is_deleted_vector(key),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.is_deleted_vector(key),
            VectorStorageEnum::MultiDenseVolatile(v) => v.is_deleted_vector(key),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.is_deleted_vector(key),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.is_deleted_vector(key),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.is_deleted_vector(key),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.is_deleted_vector(key),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.is_deleted_vector(key),
        }
    }

    fn deleted_vector_count(&self) -> usize {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.deleted_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.deleted_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.deleted_vector_count(),
            VectorStorageEnum::DenseVolatile(v) => v.deleted_vector_count(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.deleted_vector_count(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.deleted_vector_count(),
            VectorStorageEnum::DenseMemmap(v) => v.deleted_vector_count(),
            VectorStorageEnum::DenseMemmapByte(v) => v.deleted_vector_count(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.deleted_vector_count(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.deleted_vector_count(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.deleted_vector_count(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.deleted_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.deleted_vector_count(),
            VectorStorageEnum::SparseVolatile(v) => v.deleted_vector_count(),
            VectorStorageEnum::SparseMmap(v) => v.deleted_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.deleted_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.deleted_vector_count(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.deleted_vector_count(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.deleted_vector_count(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.deleted_vector_count(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.deleted_vector_count(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.deleted_vector_count(),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.deleted_vector_count(),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.deleted_vector_count(),
        }
    }

    fn deleted_vector_bitslice(&self) -> &BitSlice {
        match self {
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimple(v) => v.deleted_vector_bitslice(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleByte(v) => v.deleted_vector_bitslice(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::DenseSimpleHalf(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::DenseVolatile(v) => v.deleted_vector_bitslice(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileByte(v) => v.deleted_vector_bitslice(),
            #[cfg(test)]
            VectorStorageEnum::DenseVolatileHalf(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::DenseMemmap(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::DenseMemmapByte(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::DenseMemmapHalf(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::DenseAppendableMemmap(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::DenseAppendableMemmapByte(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::DenseAppendableMemmapHalf(v) => v.deleted_vector_bitslice(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::SparseSimple(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::SparseVolatile(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::SparseMmap(v) => v.deleted_vector_bitslice(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimple(v) => v.deleted_vector_bitslice(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleByte(v) => v.deleted_vector_bitslice(),
            #[cfg(feature = "rocksdb")]
            VectorStorageEnum::MultiDenseSimpleHalf(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::MultiDenseVolatile(v) => v.deleted_vector_bitslice(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileByte(v) => v.deleted_vector_bitslice(),
            #[cfg(test)]
            VectorStorageEnum::MultiDenseVolatileHalf(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::MultiDenseAppendableMemmap(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::MultiDenseAppendableMemmapByte(v) => v.deleted_vector_bitslice(),
            VectorStorageEnum::MultiDenseAppendableMemmapHalf(v) => v.deleted_vector_bitslice(),
        }
    }
}
