Skip to main content

diskann_utils/views/
mod.rs

1/*
2 * Copyright (c) Microsoft Corporation.
3 * Licensed under the MIT license.
4 */
5
6pub mod rowmajor;
7
8/// This trait can be implemented by wrappers for immutable and mutable slice references,
9/// allowing for a common code path for immutable and mutable view types.
10///
11/// The main goal is to provide a way of retrieving an underlying dense slice, which can
12/// then be used as the building block for higher level abstractions.
13///
14/// # Safety
15///
16/// This trait is unsafe because it requires `as_slice` to be idempotent (and unsafe code
17/// relies on this).
18///
19/// In other words: `as_slice` must **always** return the same slice with the same length.
20pub unsafe trait DenseData {
21    type Elem;
22
23    /// Return the underlying data as a slice.
24    fn as_slice(&self) -> &[Self::Elem];
25}
26
27/// A mutable companion to [`DenseData`].
28///
29/// This trait allows mutable methods on view types to be selectively enabled when data
30/// underlying the type is mutable.
31///
32/// # Safety
33///
34/// This trait is unsafe because it requires `as_slice` to be idempotent (and unsafe code
35/// relies on this).
36///
37/// In other words: `as_slice` must **always** return the same slice with the same length.
38///
39/// Additionally, the returned slice must span the exact same memory as `as_slice`.
40pub unsafe trait MutDenseData: DenseData {
41    fn as_mut_slice(&mut self) -> &mut [Self::Elem];
42}
43
44// SAFETY: This fulfills the idempotency requirement.
45unsafe impl<T> DenseData for &[T] {
46    type Elem = T;
47    fn as_slice(&self) -> &[Self::Elem] {
48        self
49    }
50}
51
52// SAFETY: This fulfills the idempotency requirement.
53unsafe impl<T> DenseData for &mut [T] {
54    type Elem = T;
55    fn as_slice(&self) -> &[Self::Elem] {
56        self
57    }
58}
59
60// SAFETY: This fulfills the idempotency requirement and returns a slice spanning the same
61// range as `as_slice`.
62unsafe impl<T> MutDenseData for &mut [T] {
63    fn as_mut_slice(&mut self) -> &mut [Self::Elem] {
64        self
65    }
66}
67
68// SAFETY: This fulfills the idempotency requirement.
69unsafe impl<T> DenseData for Box<[T]> {
70    type Elem = T;
71    fn as_slice(&self) -> &[Self::Elem] {
72        self
73    }
74}
75
76// SAFETY: This fulfills the idempotency requirement and returns a slice spanning the same
77// memory as `as_slice`.
78unsafe impl<T> MutDenseData for Box<[T]> {
79    fn as_mut_slice(&mut self) -> &mut [Self::Elem] {
80        self
81    }
82}
83
84///////////
85// Tests //
86///////////
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    use crate::lazy_format;
93
94    /// Test the that provided representation yields a slice with the expected base pointer
95    /// and length.
96    fn test_dense_data_repr<T, Repr>(
97        ptr: *const T,
98        len: usize,
99        repr: Repr,
100        context: &dyn std::fmt::Display,
101    ) where
102        T: Copy,
103        Repr: DenseData<Elem = T>,
104    {
105        let retrieved = repr.as_slice();
106        assert_eq!(retrieved.len(), len, "{}", context);
107        assert_eq!(retrieved.as_ptr(), ptr, "{}", context);
108    }
109
110    /// Set the underlying data for the provided representation to the following:
111    ///
112    /// [base, base + increment, base + increment + increment, ...]
113    fn set_mut_dense_data_repr<T, Repr>(repr: &mut Repr, base: T, increment: T)
114    where
115        T: Copy + std::ops::Add<Output = T>,
116        Repr: DenseData<Elem = T> + MutDenseData,
117    {
118        let slice = repr.as_mut_slice();
119        for i in 0..slice.len() {
120            if i == 0 {
121                slice[i] = base;
122            } else {
123                slice[i] = slice[i - 1] + increment;
124            }
125        }
126    }
127
128    #[test]
129    fn slice_implements_dense_data_repr() {
130        for len in 0..10 {
131            let context = lazy_format!("len = {}", len);
132            let data: Vec<f32> = vec![0.0; len];
133            let slice = data.as_slice();
134            test_dense_data_repr(slice.as_ptr(), slice.len(), slice, &context);
135        }
136    }
137
138    #[test]
139    fn mut_slice_implements_dense_data_repr() {
140        for len in 0..10 {
141            let context = lazy_format!("len = {}", len);
142            let mut data: Vec<f32> = vec![0.0; len];
143            let slice = data.as_mut_slice();
144
145            let ptr = slice.as_ptr();
146            let len = slice.len();
147            test_dense_data_repr(ptr, len, slice, &context);
148        }
149    }
150
151    #[test]
152    fn mut_slice_implements_mut_dense_data_repr() {
153        for len in 0..10 {
154            let context = lazy_format!("len = {}", len);
155            let mut data: Vec<f32> = vec![0.0; len];
156            let mut slice = data.as_mut_slice();
157
158            let base = 2.0;
159            let increment = 1.0;
160            set_mut_dense_data_repr(&mut slice, base, increment);
161
162            for (i, &v) in slice.iter().enumerate() {
163                let context = lazy_format!("entry {}, {}", i, context);
164                assert_eq!(v, base + increment * (i as f32), "{}", context);
165            }
166        }
167    }
168
169    #[test]
170    fn test_box_slice_dense_data_impls() {
171        // Test Box<[T]> implementations
172        let data: Box<[f32]> = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0].into();
173        let ptr = data.as_ptr();
174        let len = data.len();
175
176        // Test DenseData impl for Box<[T]>
177        test_dense_data_repr(ptr, len, data, &lazy_format!("Box<[T]> DenseData"));
178
179        // Test MutDenseData impl for Box<[T]>
180        let mut data: Box<[f32]> = vec![0.0; 6].into();
181        set_mut_dense_data_repr(&mut data, 1.0, 2.0);
182        for (i, &v) in data.iter().enumerate() {
183            assert_eq!(
184                v,
185                1.0 + 2.0 * (i as f32),
186                "Box<[T]> MutDenseData at index {}",
187                i
188            );
189        }
190    }
191}