• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vigna / webgraph-rs / 24296210049

12 Apr 2026 01:49AM UTC coverage: 66.827% (-0.05%) from 66.877%
24296210049

push

github

vigna
Clippy hapy

6674 of 9987 relevant lines covered (66.83%)

47792805.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.43
/webgraph/src/utils/circular_buffer.rs
1
/*
2
 * SPDX-FileCopyrightText: 2023 Inria
3
 * SPDX-FileCopyrightText: 2024 Sebastiano Vigna
4
 *
5
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
6
 */
7

8
/// A circular buffer which is used to keep the backreferences both in
9
/// sequential reads and compression.
10
///
11
/// For efficiency reasons, we reuse the allocated buffers to avoid pressure
12
/// over the allocator.
13
///
14
/// This structure implements [`Index`] and [`IndexMut`] with both positive and
15
/// negative indices, which are resolved with modular arithmetic. It is also
16
/// possible to [take] and [replace] the value at a given index.
17
///
18
/// [`Index`]: std::ops::Index
19
/// [`IndexMut`]: std::ops::IndexMut
20
/// [take]: CircularBuffer::take
21
/// [replace]: CircularBuffer::replace
22
#[derive(Debug, Clone)]
23
pub(crate) struct CircularBuffer<T: Default> {
24
    data: Vec<T>,
25
}
26

27
impl<T: Default> CircularBuffer<T> {
28
    /// Creates a new circular buffer which can hold `len` values.
29
    pub(crate) fn new(len: usize) -> Self {
2,845,344✔
30
        Self {
31
            data: (0..len).map(|_| T::default()).collect::<Vec<_>>(),
29,226,396✔
32
        }
33
    }
34

35
    /// Takes an element from the buffer, replacing it with its default value.
36
    pub(crate) fn take(&mut self, index: usize) -> T {
288,943,137✔
37
        let idx = index % self.data.len();
866,829,411✔
38
        core::mem::take(&mut self.data[idx])
577,886,274✔
39
    }
40

41
    /// Replaces an element in the buffer with a new value and
42
    /// return a reference to the new value in the buffer.
43
    pub(crate) fn replace(&mut self, index: usize, data: T) -> &T {
289,068,457✔
44
        let idx = index % self.data.len();
867,205,371✔
45
        self.data[idx] = data;
578,136,914✔
46
        &self.data[idx]
289,068,457✔
47
    }
48
}
49

50
impl<T: Default> core::ops::Index<usize> for CircularBuffer<T> {
51
    type Output = T;
52

53
    #[inline]
54
    fn index(&self, node_id: usize) -> &Self::Output {
729,649,722✔
55
        let idx = node_id % self.data.len();
2,147,483,647✔
56
        &self.data[idx]
729,649,722✔
57
    }
58
}
59

60
impl<T: Default> core::ops::IndexMut<usize> for CircularBuffer<T> {
61
    #[inline]
62
    fn index_mut(&mut self, node_id: usize) -> &mut Self::Output {
97,854,643✔
63
        let idx = node_id % self.data.len();
293,563,929✔
64
        &mut self.data[idx]
97,854,643✔
65
    }
66
}
67

68
impl<T: Default> core::ops::Index<isize> for CircularBuffer<T> {
69
    type Output = T;
70

71
    #[inline]
72
    fn index(&self, node_id: isize) -> &Self::Output {
×
73
        let idx = node_id.rem_euclid(self.data.len() as isize) as usize;
×
74
        &self.data[idx]
×
75
    }
76
}
77

78
impl<T: Default> core::ops::IndexMut<isize> for CircularBuffer<T> {
79
    #[inline]
80
    fn index_mut(&mut self, node_id: isize) -> &mut Self::Output {
×
81
        let idx = node_id.rem_euclid(self.data.len() as isize) as usize;
×
82
        &mut self.data[idx]
×
83
    }
84
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc