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

vigna / webgraph-rs / 17735521500

15 Sep 2025 01:54PM UTC coverage: 49.961% (-0.03%) from 49.987%
17735521500

push

github

web-flow
Merge pull request #137 from progval/fix-compil

bench_unit_transpose: Fix compilation

3888 of 7782 relevant lines covered (49.96%)

23960578.28 hits per line

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

65.42
/webgraph/tests/test_bvcomp.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
use lender::*;
9
use std::{fs::File, io::BufWriter};
10
use tempfile::NamedTempFile;
11

12
const NODES: usize = 325557;
13

14
use anyhow::Result;
15
use dsi_bitstream::prelude::*;
16
use dsi_progress_logger::prelude::*;
17
use std::path::Path;
18
use webgraph::{graphs::random::ErdosRenyi, prelude::*};
19
use Codes::{Delta, Gamma, Unary, Zeta};
20

21
#[cfg_attr(feature = "slow_tests", test)]
22
#[cfg_attr(not(feature = "slow_tests"), allow(dead_code))]
23
fn test_bvcomp_slow() -> Result<()> {
1✔
24
    env_logger::builder()
2✔
25
        .is_test(true)
26
        .filter_level(log::LevelFilter::Info)
1✔
27
        .try_init()?;
28
    _test_bvcomp_slow::<LE>().and(_test_bvcomp_slow::<BE>())
1✔
29
}
30

31
fn _test_bvcomp_slow<E: Endianness>() -> Result<()>
2✔
32
where
33
    BufBitWriter<E, WordAdapter<usize, BufWriter<File>>>: CodesWrite<E>,
34
    BufBitReader<E, MemWordReader<u32, MmapHelper<u32>>>: CodesRead<E>,
35
{
36
    let tmp_file = NamedTempFile::new()?;
4✔
37
    let tmp_path = tmp_file.path();
×
38
    let seq_graph = ErdosRenyi::new(100, 0.1, 0);
×
39
    for compression_window in [0, 1, 3, 16] {
18✔
40
        for max_ref_count in [0, 1, 3, usize::MAX] {
72✔
41
            for min_interval_length in [0, 1, 3] {
224✔
42
                for outdegrees in [Unary, Gamma, Delta] {
288✔
43
                    for references in [Unary, Gamma, Delta] {
864✔
44
                        for blocks in [Unary, Gamma, Delta] {
2,592✔
45
                            for intervals in [Unary, Gamma, Delta] {
7,776✔
46
                                for residuals in [Gamma, Delta, Zeta { k: 2 }, Zeta { k: 3 }] {
31,104✔
47
                                    eprintln!();
×
48
                                    eprintln!(
×
49
                                        "Testing with outdegrees = {:?}, references = {:?}, blocks = {:?}, intervals = {:?}, residuals = {:?}, compression_window = {}, max_ref_count = {}, min_interval_length = {}",
×
50
                                        outdegrees,
×
51
                                        references,
×
52
                                        blocks,
×
53
                                        intervals,
×
54
                                        residuals,
×
55
                                        compression_window,
×
56
                                        max_ref_count,
×
57
                                        min_interval_length,
×
58
                                    );
59
                                    let compression_flags = CompFlags {
60
                                        outdegrees,
61
                                        references,
62
                                        blocks,
63
                                        intervals,
64
                                        residuals,
65
                                        min_interval_length,
66
                                        compression_window,
67
                                        max_ref_count,
68
                                    };
69

70
                                    _test_body::<E, _>(tmp_path, &seq_graph, compression_flags)?;
×
71
                                }
72
                            }
73
                        }
74
                    }
75
                }
76
            }
77
        }
78
    }
79
    std::fs::remove_file(tmp_path)?;
2✔
80
    Ok(())
2✔
81
}
82

83
fn _test_body<E: Endianness, P: AsRef<Path>>(
31,104✔
84
    tmp_path: P,
85
    seq_graph: &impl SequentialGraph,
86
    compression_flags: CompFlags,
87
) -> Result<()>
88
where
89
    BufBitWriter<E, WordAdapter<usize, BufWriter<File>>>: CodesWrite<E>,
90
    BufBitReader<E, MemWordReader<u32, MmapHelper<u32>>>: CodesRead<E>,
91
{
92
    let writer = EncoderValidator::new(<DynCodesEncoder<E, _>>::new(
62,208✔
93
        <BufBitWriter<E, _>>::new(<WordAdapter<usize, _>>::new(BufWriter::new(File::create(
31,104✔
94
            tmp_path.as_ref(),
62,208✔
95
        )?))),
96
        &compression_flags,
×
97
    )?);
98
    let mut bvcomp = BvComp::new(
99
        writer,
×
100
        compression_flags.compression_window,
×
101
        compression_flags.max_ref_count,
×
102
        compression_flags.min_interval_length,
×
103
        0,
104
    );
105

106
    let mut pl = ProgressLogger::default();
×
107
    pl.display_memory(true)
×
108
        .item_name("node")
109
        .expected_updates(Some(NODES));
×
110

111
    pl.start("Compressing...");
×
112

113
    // TODO: use LoadConfig
114
    let mut iter_nodes = seq_graph.iter();
×
115
    while let Some((_, iter)) = iter_nodes.next() {
6,251,904✔
116
        bvcomp.push(iter)?;
×
117
        pl.light_update();
3,110,400✔
118
    }
119

120
    pl.done();
62,208✔
121
    bvcomp.flush()?;
62,208✔
122

123
    let code_reader = DynCodesDecoder::new(
124
        BufBitReader::<E, _>::new(MemWordReader::<u32, _>::new(MmapHelper::mmap(
31,104✔
125
            tmp_path.as_ref(),
×
126
            mmap_rs::MmapFlags::empty(),
×
127
        )?)),
128
        &compression_flags,
×
129
    )?;
130
    let mut seq_reader1 = sequential::Iter::new(
131
        code_reader,
×
132
        NODES,
×
133
        compression_flags.compression_window,
×
134
        compression_flags.min_interval_length,
×
135
    );
136

137
    pl.start("Checking equality...");
×
138
    let mut iter_nodes = seq_graph.iter();
×
139
    for _ in 0..seq_graph.num_nodes() {
×
140
        let (node0, iter0) = iter_nodes.next().unwrap();
12,441,600✔
141
        let (node1, iter1) = seq_reader1.next().unwrap();
12,441,600✔
142
        assert_eq!(node0, node1);
3,110,400✔
143
        assert_eq!(
3,110,400✔
144
            iter0.into_iter().collect::<Vec<_>>(),
9,331,200✔
145
            iter1.into_iter().collect::<Vec<_>>()
9,331,200✔
146
        );
147
        pl.light_update();
3,110,400✔
148
    }
149
    pl.done();
31,104✔
150
    Ok(())
×
151
}
152

153
pub struct EncoderValidator<E: Encode> {
154
    encoder: E,
155
    start_nodes: usize,
156
    end_nodes: usize,
157
    flush: bool,
158
    // encoder has to be flushed, while estimator does not
159
    is_estimator: bool,
160
}
161

162
impl<E: Encode> EncoderValidator<E> {
163
    pub fn new(encoder: E) -> Self {
31,104✔
164
        Self {
165
            encoder,
166
            start_nodes: 0,
167
            end_nodes: 0,
168
            flush: false,
169
            is_estimator: false,
170
        }
171
    }
172
    pub fn new_estimator(encoder: E) -> Self {
12,564,552✔
173
        Self {
174
            encoder,
175
            start_nodes: 0,
176
            end_nodes: 0,
177
            flush: false,
178
            is_estimator: true,
179
        }
180
    }
181
}
182

183
impl<E: Encode> core::ops::Drop for EncoderValidator<E> {
184
    fn drop(&mut self) {
12,595,656✔
185
        assert_eq!(self.start_nodes, self.end_nodes);
12,595,656✔
186
        if !self.is_estimator {
12,595,656✔
187
            assert!(self.flush, "flush not called");
31,104✔
188
        }
189
    }
190
}
191

192
impl<E: Encode> Encode for EncoderValidator<E> {
193
    type Error = E::Error;
194
    fn start_node(&mut self, node: usize) -> std::prelude::v1::Result<usize, Self::Error> {
15,674,952✔
195
        assert_eq!(self.start_nodes, self.end_nodes);
15,674,952✔
196
        self.start_nodes += 1;
15,674,952✔
197
        self.encoder.start_node(node)
47,024,856✔
198
    }
199
    fn end_node(&mut self, node: usize) -> std::prelude::v1::Result<usize, Self::Error> {
15,674,952✔
200
        self.end_nodes += 1;
15,674,952✔
201
        assert_eq!(self.start_nodes, self.end_nodes);
15,674,952✔
202
        self.encoder.end_node(node)
47,024,856✔
203
    }
204
    fn flush(&mut self) -> std::prelude::v1::Result<usize, Self::Error> {
31,104✔
205
        assert!(!self.flush, "flush called twice");
62,208✔
206
        self.flush = true;
31,104✔
207
        self.encoder.flush()
×
208
    }
209
    fn write_outdegree(&mut self, value: u64) -> std::prelude::v1::Result<usize, Self::Error> {
15,674,952✔
210
        self.encoder.write_outdegree(value)
47,024,856✔
211
    }
212
    fn write_reference_offset(
14,897,352✔
213
        &mut self,
214
        value: u64,
215
    ) -> std::prelude::v1::Result<usize, Self::Error> {
216
        self.encoder.write_reference_offset(value)
44,692,056✔
217
    }
218
    fn write_block_count(&mut self, value: u64) -> std::prelude::v1::Result<usize, Self::Error> {
10,417,404✔
219
        self.encoder.write_block_count(value)
31,252,212✔
220
    }
221
    fn write_block(&mut self, value: u64) -> std::prelude::v1::Result<usize, Self::Error> {
27,154,824✔
222
        self.encoder.write_block(value)
81,464,472✔
223
    }
224
    fn write_interval_count(&mut self, value: u64) -> std::prelude::v1::Result<usize, Self::Error> {
10,345,422✔
225
        self.encoder.write_interval_count(value)
31,036,266✔
226
    }
227
    fn write_interval_start(&mut self, value: u64) -> std::prelude::v1::Result<usize, Self::Error> {
5,462,520✔
228
        self.encoder.write_interval_start(value)
16,387,560✔
229
    }
230
    fn write_interval_len(&mut self, value: u64) -> std::prelude::v1::Result<usize, Self::Error> {
5,462,520✔
231
        self.encoder.write_interval_len(value)
16,387,560✔
232
    }
233
    fn write_first_residual(&mut self, value: u64) -> std::prelude::v1::Result<usize, Self::Error> {
15,674,952✔
234
        self.encoder.write_first_residual(value)
47,024,856✔
235
    }
236
    fn write_residual(&mut self, value: u64) -> std::prelude::v1::Result<usize, Self::Error> {
121,542,528✔
237
        self.encoder.write_residual(value)
364,627,584✔
238
    }
239
}
240

241
impl<E: EncodeAndEstimate> EncodeAndEstimate for EncoderValidator<E> {
242
    type Estimator<'a>
243
        = EncoderValidator<E::Estimator<'a>>
244
    where
245
        Self: 'a;
246

247
    fn estimator(&mut self) -> Self::Estimator<'_> {
12,564,552✔
248
        EncoderValidator::new_estimator(self.encoder.estimator())
37,693,656✔
249
    }
250
}
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