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

vigna / webgraph-rs / 23365769388

20 Mar 2026 10:52PM UTC coverage: 68.228% (-3.0%) from 71.245%
23365769388

push

github

vigna
No le_bins,be_bins for webgraph

6655 of 9754 relevant lines covered (68.23%)

46582760.24 hits per line

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

61.22
/cli/src/perm/comp.rs
1
/*
2
 * SPDX-FileCopyrightText: 2023 Sebastiano Vigna
3
 * SPDX-FileCopyrightText: 2023 Tommaso Fontana
4
 *
5
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
6
 */
7

8
use crate::{IntSlice, IntSliceFormat, LogIntervalArg, create_parent_dir};
9
use anyhow::{Result, ensure};
10
use clap::Parser;
11
use dsi_progress_logger::prelude::*;
12
use std::path::PathBuf;
13
use value_traits::slices::SliceByValue;
14

15
#[derive(Parser, Debug)]
16
#[command(name = "comp", about = "Composes multiple permutations into a single one.", long_about = None, next_line_help = true)]
17
pub struct CliArgs {
18
    /// The filename of the resulting permutation.​
19
    pub dst: PathBuf,
20

21
    #[arg(num_args(1..))]
22
    /// Filenames of the permutations to compose (in order of application).​
23
    pub perms: Vec<PathBuf>,
24

25
    #[arg(long, value_enum, default_value_t)]
26
    /// The format of the source permutation files.​
27
    pub src_fmt: IntSliceFormat,
28

29
    #[arg(long, value_enum, default_value_t)]
30
    /// The format of the destination permutation file.​
31
    pub dst_fmt: IntSliceFormat,
32

33
    #[clap(flatten)]
34
    pub log_interval: LogIntervalArg,
35
}
36

37
fn compose<P: SliceByValue<Value = usize>>(
5✔
38
    perms: &[&P],
39
    len: usize,
40
    pl: &mut ProgressLogger,
41
) -> Vec<usize> {
42
    let mut merged = Vec::with_capacity(len);
15✔
43
    pl.start("Combining permutations...");
10✔
44
    for i in 0..len {
1,627,790✔
45
        let mut v = i;
3,255,570✔
46
        for p in perms {
8,138,925✔
47
            v = p.index_value(v);
6,511,140✔
48
        }
49
        merged.push(v);
4,883,355✔
50
        pl.light_update();
3,255,570✔
51
    }
52
    pl.done();
10✔
53
    merged
5✔
54
}
55

56
pub fn main(args: CliArgs) -> Result<()> {
5✔
57
    create_parent_dir(&args.dst)?;
10✔
58

59
    let mut pl = progress_logger![display_memory = true, item_name = "indices"];
10✔
60

61
    if let Some(duration) = args.log_interval.log_interval {
5✔
62
        pl.log_interval(duration);
×
63
    }
64

65
    let mut perms: Vec<IntSlice> = Vec::new();
15✔
66
    for path in &args.perms {
15✔
67
        perms.push(args.src_fmt.load(path)?);
50✔
68
    }
69

70
    let len = perms[0].len();
15✔
71
    ensure!(
5✔
72
        perms.iter().all(|p| p.len() == len),
40✔
73
        "All permutations must have the same length"
74
    );
75
    pl.expected_updates(Some(len));
15✔
76

77
    // Dispatch on the concrete type for static dispatch in the composition
78
    // loop. All perms share the same variant since they are loaded with the
79
    // same src_fmt.
80
    let merged = match &perms[0] {
10✔
81
        IntSlice::Owned(_) => {
82
            let refs: Vec<_> = perms
15✔
83
                .iter()
84
                .map(|p| {
15✔
85
                    let IntSlice::Owned(v) = p else {
20✔
86
                        unreachable!()
×
87
                    };
88
                    v
10✔
89
                })
90
                .collect();
91
            compose(&refs, len, &mut pl)
20✔
92
        }
93
        #[cfg(target_pointer_width = "64")]
94
        IntSlice::Java(_) => {
95
            let refs: Vec<_> = perms
×
96
                .iter()
97
                .map(|p| {
×
98
                    let IntSlice::Java(j) = p else { unreachable!() };
×
99
                    j
×
100
                })
101
                .collect();
102
            compose(&refs, len, &mut pl)
×
103
        }
104
        IntSlice::Epserde(_) => {
105
            let refs: Vec<_> = perms
×
106
                .iter()
107
                .map(|p| {
×
108
                    let IntSlice::Epserde(m) = p else {
×
109
                        unreachable!()
×
110
                    };
111
                    m.uncase()
×
112
                })
113
                .collect();
114
            compose(&refs, len, &mut pl)
×
115
        }
116
        IntSlice::BitFieldVec(_) => {
117
            let refs: Vec<_> = perms
×
118
                .iter()
119
                .map(|p| {
×
120
                    let IntSlice::BitFieldVec(m) = p else {
×
121
                        unreachable!()
×
122
                    };
123
                    m.uncase()
×
124
                })
125
                .collect();
126
            compose(&refs, len, &mut pl)
×
127
        }
128
    };
129

130
    args.dst_fmt.store(&args.dst, &merged, None)?;
25✔
131

132
    Ok(())
5✔
133
}
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