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

vigna / webgraph-rs / 18277715517

06 Oct 2025 10:22AM UTC coverage: 49.037% (+0.06%) from 48.974%
18277715517

push

github

vigna
HalfMemory -> Half

0 of 1 new or added line in 1 file covered. (0.0%)

3896 of 7945 relevant lines covered (49.04%)

23434912.41 hits per line

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

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

8
//! Miscellaneous utilities.
9

10
use rand::Rng;
11
use std::path::PathBuf;
12

13
/// An enum expressing the memory requirements for batched algorithms
14
/// such as [`SortPairs`] and [`ParSortPairs`].
15
pub enum MemoryUsage {
16
    /// Use half of the physical memory.
17
    Half,
18
    /// The target overall memory usage in bytes.
19
    MemorySize(usize),
20
    /// The number of elements in a batch.
21
    ///
22
    /// Note that the size of elements depends on the size of
23
    /// labels for labelled graphs, and that the actual memory
24
    /// usage may depend on the implementation (e.g., [`SortPairs`]
25
    /// will use this number of elements, but [`ParSortPairs`] will
26
    /// use this number of elements multiplied by the square of
27
    /// the number of threads).
28
    BatchSize(usize),
29
}
30

31
impl Default for MemoryUsage {
32
    fn default() -> Self {
×
NEW
33
        MemoryUsage::Half
×
34
    }
35
}
36

37
/// Creates a new random dir inside the given folder
38
pub fn temp_dir<P: AsRef<std::path::Path>>(base: P) -> anyhow::Result<PathBuf> {
9✔
39
    let mut base = base.as_ref().to_owned();
27✔
40
    const ALPHABET: &[u8] = b"0123456789abcdef";
41
    let mut rnd = rand::rng();
18✔
42
    let mut random_str = String::new();
18✔
43
    loop {
×
44
        random_str.clear();
18✔
45
        for _ in 0..16 {
297✔
46
            let idx = rnd.random_range(0..ALPHABET.len());
144✔
47
            random_str.push(ALPHABET[idx] as char);
144✔
48
        }
49
        base.push(&random_str);
27✔
50

51
        if !base.exists() {
9✔
52
            std::fs::create_dir(&base)?;
18✔
53
            return Ok(base);
9✔
54
        }
55
        base.pop();
×
56
    }
57
}
58

59
mod circular_buffer;
60
pub(crate) use circular_buffer::*;
61

62
mod mmap_helper;
63
pub use mmap_helper::*;
64

65
mod java_perm;
66
pub use java_perm::*;
67

68
mod granularity;
69
pub use granularity::*;
70

71
pub mod sort_pairs;
72
pub use sort_pairs::SortPairs;
73

74
pub mod par_sort_pairs;
75
pub use par_sort_pairs::ParSortPairs;
76

77
use crate::graphs::bvgraph::{Decode, Encode};
78

79
/// A decoder that encodes the read values using the given encoder.
80
/// This is commonly used to change the codes of a graph without decoding and
81
/// re-encoding it but by changing the codes.
82
pub struct Converter<D: Decode, E: Encode> {
83
    pub decoder: D,
84
    pub encoder: E,
85
    pub offset: usize,
86
}
87

88
impl<D: Decode, E: Encode> Decode for Converter<D, E> {
89
    // TODO: implement correctly start_node/end_node
90
    #[inline(always)]
91
    fn read_outdegree(&mut self) -> u64 {
×
92
        let res = self.decoder.read_outdegree();
×
93
        self.offset += self.encoder.write_outdegree(res).unwrap();
×
94
        res
×
95
    }
96
    #[inline(always)]
97
    fn read_reference_offset(&mut self) -> u64 {
×
98
        let res = self.decoder.read_reference_offset();
×
99
        self.offset += self.encoder.write_reference_offset(res).unwrap();
×
100
        res
×
101
    }
102
    #[inline(always)]
103
    fn read_block_count(&mut self) -> u64 {
×
104
        let res = self.decoder.read_block_count();
×
105
        self.offset += self.encoder.write_block_count(res).unwrap();
×
106
        res
×
107
    }
108
    #[inline(always)]
109
    fn read_block(&mut self) -> u64 {
×
110
        let res = self.decoder.read_block();
×
111
        self.offset += self.encoder.write_block(res).unwrap();
×
112
        res
×
113
    }
114
    #[inline(always)]
115
    fn read_interval_count(&mut self) -> u64 {
×
116
        let res = self.decoder.read_interval_count();
×
117
        self.offset += self.encoder.write_interval_count(res).unwrap();
×
118
        res
×
119
    }
120
    #[inline(always)]
121
    fn read_interval_start(&mut self) -> u64 {
×
122
        let res = self.decoder.read_interval_start();
×
123
        self.offset += self.encoder.write_interval_start(res).unwrap();
×
124
        res
×
125
    }
126
    #[inline(always)]
127
    fn read_interval_len(&mut self) -> u64 {
×
128
        let res = self.decoder.read_interval_len();
×
129
        self.offset += self.encoder.write_interval_len(res).unwrap();
×
130
        res
×
131
    }
132
    #[inline(always)]
133
    fn read_first_residual(&mut self) -> u64 {
×
134
        let res = self.decoder.read_first_residual();
×
135
        self.offset += self.encoder.write_first_residual(res).unwrap();
×
136
        res
×
137
    }
138
    #[inline(always)]
139
    fn read_residual(&mut self) -> u64 {
×
140
        let res = self.decoder.read_residual();
×
141
        self.offset += self.encoder.write_residual(res).unwrap();
×
142
        res
×
143
    }
144
}
145

146
/// Utility macro to create [`thread_pools`](`rayon::ThreadPool`).
147
///
148
/// There are two forms of this macro:
149
/// * Create a [`ThreadPool`](rayon::ThreadPool) with the default settings:
150
/// ```
151
/// # use webgraph::thread_pool;
152
/// let t: rayon::ThreadPool = thread_pool![];
153
/// ```
154
/// * Create a [`ThreadPool`](rayon::ThreadPool) with a given number of threads:
155
/// ```
156
/// # use webgraph::thread_pool;
157
/// let t: rayon::ThreadPool = thread_pool![7];
158
/// assert_eq!(t.current_num_threads(), 7);
159
/// ```
160
#[macro_export]
161
macro_rules! thread_pool {
162
    () => {
163
        rayon::ThreadPoolBuilder::new()
164
            .build()
165
            .expect("Cannot build a ThreadPool with default parameters")
166
    };
167
    ($num_threads:expr) => {
168
        rayon::ThreadPoolBuilder::new()
169
            .num_threads($num_threads)
170
            .build()
171
            .unwrap_or_else(|_| {
×
172
                panic!(
×
173
                    "Cannot build a ThreadPool with default parameters and {} threads",
×
174
                    $num_threads,
175
                )
176
            })
177
    };
178
}
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