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

vigna / webgraph-rs / 18008720487

25 Sep 2025 01:16PM UTC coverage: 49.589% (-0.4%) from 49.949%
18008720487

push

github

vigna
Fixed fuzzing code for new epserde

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

650 existing lines in 25 files now uncovered.

3862 of 7788 relevant lines covered (49.59%)

25127316.85 hits per line

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

30.3
/webgraph/src/graphs/bvgraph/codecs/dec_const.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 std::marker::PhantomData;
9

10
use super::super::*;
11
use anyhow::bail;
12
use anyhow::Result;
13
use dsi_bitstream::dispatch::code_consts;
14
use dsi_bitstream::dispatch::factory::CodesReaderFactoryHelper;
15
use dsi_bitstream::prelude::*;
16

17
use epserde::deser::MemCase;
18
use epserde::deser::Owned;
19
use sux::traits::IndexedSeq;
20

21
#[repr(transparent)]
22
/// An implementation of [`Decode`]  with compile-time defined codes.
23
#[derive(Debug, Clone)]
24
pub struct ConstCodesDecoder<
25
    E: Endianness,
26
    CR: CodesRead<E>,
27
    const OUTDEGREES: usize = { code_consts::GAMMA },
28
    const REFERENCES: usize = { code_consts::UNARY },
29
    const BLOCKS: usize = { code_consts::GAMMA },
30
    const INTERVALS: usize = { code_consts::GAMMA },
31
    const RESIDUALS: usize = { code_consts::ZETA3 },
32
> {
33
    /// The inner codes reader we will dispatch to
34
    pub(crate) code_reader: CR,
35
    /// Make the compiler happy with the generics we don't use in the struct
36
    /// (but we need them to be able to use the trait)
37
    pub(crate) _marker: core::marker::PhantomData<E>,
38
}
39

40
impl<
41
        E: Endianness,
42
        CR: CodesRead<E> + BitSeek,
43
        const OUTDEGREES: usize,
44
        const REFERENCES: usize,
45
        const BLOCKS: usize,
46
        const INTERVALS: usize,
47
        const RESIDUALS: usize,
48
    > BitSeek for ConstCodesDecoder<E, CR, OUTDEGREES, REFERENCES, BLOCKS, INTERVALS, RESIDUALS>
49
{
50
    type Error = <CR as BitSeek>::Error;
51

UNCOV
52
    fn set_bit_pos(&mut self, bit_index: u64) -> Result<(), Self::Error> {
×
UNCOV
53
        self.code_reader.set_bit_pos(bit_index)
×
54
    }
55

UNCOV
56
    fn bit_pos(&mut self) -> Result<u64, Self::Error> {
×
UNCOV
57
        self.code_reader.bit_pos()
×
58
    }
59
}
60

61
impl<
62
        E: Endianness,
63
        CR: CodesRead<E>,
64
        const OUTDEGREES: usize,
65
        const REFERENCES: usize,
66
        const BLOCKS: usize,
67
        const INTERVALS: usize,
68
        const RESIDUALS: usize,
69
    > ConstCodesDecoder<E, CR, OUTDEGREES, REFERENCES, BLOCKS, INTERVALS, RESIDUALS>
70
{
71
    /// Creates a new [`ConstCodesEncoder`] from a [`CodesRead`] implementation.
72
    /// and a [`CompFlags`] struct
73
    /// # Errors
74
    /// If the codes in the [`CompFlags`] do not match the compile-time defined codes
75
    pub fn new(code_reader: CR, comp_flags: &CompFlags) -> Result<Self> {
10✔
76
        if comp_flags.outdegrees.to_code_const()? != OUTDEGREES {
20✔
77
            bail!("Code for outdegrees does not match");
×
78
        }
UNCOV
79
        if comp_flags.references.to_code_const()? != REFERENCES {
×
80
            bail!("Cod for references does not match");
×
81
        }
UNCOV
82
        if comp_flags.blocks.to_code_const()? != BLOCKS {
×
83
            bail!("Code for blocks does not match");
×
84
        }
UNCOV
85
        if comp_flags.intervals.to_code_const()? != INTERVALS {
×
86
            bail!("Code for intervals does not match");
×
87
        }
UNCOV
88
        if comp_flags.residuals.to_code_const()? != RESIDUALS {
×
89
            bail!("Code for residuals does not match");
×
90
        }
91
        Ok(Self {
×
UNCOV
92
            code_reader,
×
UNCOV
93
            _marker: core::marker::PhantomData,
×
94
        })
95
    }
96
}
97

98
impl<
99
        E: Endianness,
100
        CR: CodesRead<E>,
101
        const OUTDEGREES: usize,
102
        const REFERENCES: usize,
103
        const BLOCKS: usize,
104
        const INTERVALS: usize,
105
        const RESIDUALS: usize,
106
    > Decode for ConstCodesDecoder<E, CR, OUTDEGREES, REFERENCES, BLOCKS, INTERVALS, RESIDUALS>
107
{
108
    #[inline(always)]
109
    fn read_outdegree(&mut self) -> u64 {
3,255,570✔
110
        ConstCode::<OUTDEGREES>.read(&mut self.code_reader).unwrap()
13,022,280✔
111
    }
112

113
    #[inline(always)]
114
    fn read_reference_offset(&mut self) -> u64 {
1,732,507✔
115
        ConstCode::<REFERENCES>.read(&mut self.code_reader).unwrap()
6,930,028✔
116
    }
117

118
    #[inline(always)]
119
    fn read_block_count(&mut self) -> u64 {
1,062,515✔
120
        ConstCode::<BLOCKS>.read(&mut self.code_reader).unwrap()
4,250,060✔
121
    }
122
    #[inline(always)]
123
    fn read_block(&mut self) -> u64 {
1,862,472✔
124
        ConstCode::<BLOCKS>.read(&mut self.code_reader).unwrap()
7,449,888✔
125
    }
126

127
    #[inline(always)]
128
    fn read_interval_count(&mut self) -> u64 {
1,491,316✔
129
        ConstCode::<INTERVALS>.read(&mut self.code_reader).unwrap()
5,965,264✔
130
    }
131
    #[inline(always)]
132
    fn read_interval_start(&mut self) -> u64 {
1,235,114✔
133
        ConstCode::<INTERVALS>.read(&mut self.code_reader).unwrap()
4,940,456✔
134
    }
135
    #[inline(always)]
136
    fn read_interval_len(&mut self) -> u64 {
1,235,114✔
137
        ConstCode::<INTERVALS>.read(&mut self.code_reader).unwrap()
4,940,456✔
138
    }
139

140
    #[inline(always)]
141
    fn read_first_residual(&mut self) -> u64 {
2,050,877✔
142
        ConstCode::<RESIDUALS>.read(&mut self.code_reader).unwrap()
8,203,508✔
143
    }
144
    #[inline(always)]
145
    fn read_residual(&mut self) -> u64 {
7,674,595✔
146
        ConstCode::<RESIDUALS>.read(&mut self.code_reader).unwrap()
30,698,380✔
147
    }
148
}
149

150
pub struct ConstCodesDecoderFactory<
151
    E: Endianness,
152
    F: CodesReaderFactoryHelper<E>,
153
    OFF: Offsets,
154
    const OUTDEGREES: usize = { code_consts::GAMMA },
155
    const REFERENCES: usize = { code_consts::UNARY },
156
    const BLOCKS: usize = { code_consts::GAMMA },
157
    const INTERVALS: usize = { code_consts::GAMMA },
158
    const RESIDUALS: usize = { code_consts::ZETA3 },
159
> {
160
    /// The owned data
161
    factory: F,
162
    /// The offsets into the data.
163
    offsets: MemCase<OFF>,
164
    /// Tell the compiler that's Ok that we don't store `E` but we need it
165
    /// for typing.
166
    _marker: core::marker::PhantomData<E>,
167
}
168

169
impl<
170
        E: Endianness,
171
        F: CodesReaderFactoryHelper<E>,
172
        OFF: Offsets,
173
        const OUTDEGREES: usize,
174
        const REFERENCES: usize,
175
        const BLOCKS: usize,
176
        const INTERVALS: usize,
177
        const RESIDUALS: usize,
178
    > ConstCodesDecoderFactory<E, F, OFF, OUTDEGREES, REFERENCES, BLOCKS, INTERVALS, RESIDUALS>
179
{
180
    /// Remaps the offsets in a slice of `usize`.
181
    ///
182
    /// This method is mainly useful for benchmarking and testing purposes, as
183
    /// representing the offsets as a slice increasing significantly the
184
    /// memory footprint.
185
    ///
186
    /// This method is used by [`BvGraph::offsets_to_slice`].
187
    pub fn offsets_to_slice(
×
188
        self,
189
    ) -> ConstCodesDecoderFactory<
190
        E,
191
        F,
192
        Owned<Box<[usize]>>,
193
        OUTDEGREES,
194
        REFERENCES,
195
        BLOCKS,
196
        INTERVALS,
197
        RESIDUALS,
198
    > {
UNCOV
199
        let offsets = self.offsets.uncase();
×
200
        ConstCodesDecoderFactory {
201
            factory: self.factory,
×
UNCOV
202
            offsets: (0..offsets.len())
×
203
                .map(|i| unsafe { offsets.get_unchecked(i) })
204
                .collect::<Vec<_>>()
205
                .into_boxed_slice()
206
                .into(),
207
            _marker: PhantomData,
208
        }
209
    }
210
}
211

212
impl<
213
        E: Endianness,
214
        F: CodesReaderFactoryHelper<E>,
215
        OFF: Offsets,
216
        const OUTDEGREES: usize,
217
        const REFERENCES: usize,
218
        const BLOCKS: usize,
219
        const INTERVALS: usize,
220
        const RESIDUALS: usize,
221
    > ConstCodesDecoderFactory<E, F, OFF, OUTDEGREES, REFERENCES, BLOCKS, INTERVALS, RESIDUALS>
222
{
223
    /// Creates a new builder from the given data and compression flags.
UNCOV
224
    pub fn new(factory: F, offsets: MemCase<OFF>, comp_flags: CompFlags) -> anyhow::Result<Self> {
×
225
        if comp_flags.outdegrees.to_code_const()? != OUTDEGREES {
×
226
            bail!("Code for outdegrees does not match");
×
227
        }
UNCOV
228
        if comp_flags.references.to_code_const()? != REFERENCES {
×
229
            bail!("Cod for references does not match");
×
230
        }
UNCOV
231
        if comp_flags.blocks.to_code_const()? != BLOCKS {
×
232
            bail!("Code for blocks does not match");
×
233
        }
UNCOV
234
        if comp_flags.intervals.to_code_const()? != INTERVALS {
×
235
            bail!("Code for intervals does not match");
×
236
        }
UNCOV
237
        if comp_flags.residuals.to_code_const()? != RESIDUALS {
×
238
            bail!("Code for residuals does not match");
×
239
        }
UNCOV
240
        Ok(Self {
×
241
            factory,
×
242
            offsets,
×
243
            _marker: core::marker::PhantomData,
×
244
        })
245
    }
246
}
247

248
impl<
249
        E: Endianness,
250
        F: CodesReaderFactoryHelper<E>,
251
        OFF: Offsets,
252
        const OUTDEGREES: usize,
253
        const REFERENCES: usize,
254
        const BLOCKS: usize,
255
        const INTERVALS: usize,
256
        const RESIDUALS: usize,
257
    > RandomAccessDecoderFactory
258
    for ConstCodesDecoderFactory<E, F, OFF, OUTDEGREES, REFERENCES, BLOCKS, INTERVALS, RESIDUALS>
259
where
260
    for<'a> <F as CodesReaderFactory<E>>::CodesReader<'a>: BitSeek,
261
{
262
    type Decoder<'a>
263
        = ConstCodesDecoder<E, <F as CodesReaderFactory<E>>::CodesReader<'a>>
264
    where
265
        Self: 'a;
266

UNCOV
267
    fn new_decoder(&self, offset: usize) -> anyhow::Result<Self::Decoder<'_>> {
×
268
        let mut code_reader = self.factory.new_reader();
×
269
        code_reader.set_bit_pos(unsafe { self.offsets.uncase().get_unchecked(offset) } as u64)?;
×
270

UNCOV
271
        Ok(ConstCodesDecoder {
×
272
            code_reader,
×
273
            _marker: PhantomData,
×
274
        })
275
    }
276
}
277

278
impl<
279
        E: Endianness,
280
        F: CodesReaderFactoryHelper<E>,
281
        OFF: Offsets,
282
        const OUTDEGREES: usize,
283
        const REFERENCES: usize,
284
        const BLOCKS: usize,
285
        const INTERVALS: usize,
286
        const RESIDUALS: usize,
287
    > SequentialDecoderFactory
288
    for ConstCodesDecoderFactory<E, F, OFF, OUTDEGREES, REFERENCES, BLOCKS, INTERVALS, RESIDUALS>
289
{
290
    type Decoder<'a>
291
        = ConstCodesDecoder<E, <F as CodesReaderFactory<E>>::CodesReader<'a>>
292
    where
293
        Self: 'a;
294

UNCOV
295
    fn new_decoder(&self) -> anyhow::Result<Self::Decoder<'_>> {
×
296
        let code_reader = self.factory.new_reader();
×
297

UNCOV
298
        Ok(ConstCodesDecoder {
×
299
            code_reader,
×
300
            _marker: PhantomData,
×
301
        })
302
    }
303
}
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