mirror of
https://github.com/RGBCube/dix
synced 2025-07-27 03:37:45 +00:00
Benches - criterion benchmarks (#5)
* split crate into library and binary criterion can not benchmark binary crates * Add store benchmarks * Add more, not reproducible benchmarks The benchmarks are currently hardcoded to use a specific system on my computer. To run the tests yourself, change QUERY_DERIV__OLD in benches/common.rs In the future, I would like to pull a specific copy of the nixos sqlite db from e.g. a github repo to make the benchmarks reproducible * Do not hardcode system derivations to use in benchmars By default, the oldest system is compared to the current system A specific system can be specified using environment variables (see benches/common.rs)
This commit is contained in:
parent
86564fbdda
commit
5e317983c2
9 changed files with 797 additions and 77 deletions
438
Cargo.lock
generated
438
Cargo.lock
generated
|
@ -61,12 +61,47 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.0"
|
version = "2.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cast"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.21"
|
version = "1.2.21"
|
||||||
|
@ -76,6 +111,23 @@ dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "2.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"textwrap",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.37"
|
version = "4.5.37"
|
||||||
|
@ -122,6 +174,88 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "criterion"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"cast",
|
||||||
|
"clap 2.34.0",
|
||||||
|
"criterion-plot",
|
||||||
|
"csv",
|
||||||
|
"itertools",
|
||||||
|
"lazy_static",
|
||||||
|
"num-traits",
|
||||||
|
"oorandom",
|
||||||
|
"plotters",
|
||||||
|
"rayon",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_cbor",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"tinytemplate",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "criterion-plot"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876"
|
||||||
|
dependencies = [
|
||||||
|
"cast",
|
||||||
|
"itertools",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csv"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
|
||||||
|
dependencies = [
|
||||||
|
"csv-core",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csv-core"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diff"
|
name = "diff"
|
||||||
version = "0.1.13"
|
version = "0.1.13"
|
||||||
|
@ -132,9 +266,11 @@ checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||||
name = "dix"
|
name = "dix"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap 4.5.37",
|
||||||
|
"criterion",
|
||||||
"diff",
|
"diff",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
|
@ -142,6 +278,12 @@ dependencies = [
|
||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_filter"
|
name = "env_filter"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -183,6 +325,12 @@ version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "half"
|
||||||
|
version = "1.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.3"
|
version = "0.15.3"
|
||||||
|
@ -207,12 +355,36 @@ version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.1"
|
version = "1.70.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jiff"
|
name = "jiff"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
|
@ -237,6 +409,28 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.172"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libsqlite3-sys"
|
name = "libsqlite3-sys"
|
||||||
version = "0.33.0"
|
version = "0.33.0"
|
||||||
|
@ -260,18 +454,61 @@ version = "2.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.3"
|
version = "1.21.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oorandom"
|
||||||
|
version = "11.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.32"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plotters"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
"plotters-backend",
|
||||||
|
"plotters-svg",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plotters-backend"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plotters-svg"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670"
|
||||||
|
dependencies = [
|
||||||
|
"plotters-backend",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portable-atomic"
|
name = "portable-atomic"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
@ -305,6 +542,26 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
|
@ -340,7 +597,7 @@ version = "0.35.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a22715a5d6deef63c637207afbe68d0c72c3f8d0022d7cf9714c442d6157606b"
|
checksum = "a22715a5d6deef63c637207afbe68d0c72c3f8d0022d7cf9714c442d6157606b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.9.0",
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
"fallible-streaming-iterator",
|
"fallible-streaming-iterator",
|
||||||
"hashlink",
|
"hashlink",
|
||||||
|
@ -348,6 +605,27 @@ dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "same-file"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.219"
|
version = "1.0.219"
|
||||||
|
@ -357,6 +635,16 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_cbor"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
|
||||||
|
dependencies = [
|
||||||
|
"half",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.219"
|
version = "1.0.219"
|
||||||
|
@ -368,6 +656,18 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.140"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -397,6 +697,15 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.12"
|
version = "2.0.12"
|
||||||
|
@ -417,12 +726,28 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinytemplate"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -435,6 +760,115 @@ version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "walkdir"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||||
|
dependencies = [
|
||||||
|
"same-file",
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-sys"
|
||||||
|
version = "0.3.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.59.0"
|
version = "0.59.0"
|
||||||
|
|
25
Cargo.toml
25
Cargo.toml
|
@ -3,6 +3,15 @@ name = "dix"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "dix"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "dixlib"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.37", features = ["derive"] }
|
clap = { version = "4.5.37", features = ["derive"] }
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
|
@ -12,3 +21,19 @@ log = "0.4.20"
|
||||||
env_logger = "0.11.3"
|
env_logger = "0.11.3"
|
||||||
rusqlite = { version = "0.35.0", features = ["bundled"] }
|
rusqlite = { version = "0.35.0", features = ["bundled"] }
|
||||||
diff = "0.1.13"
|
diff = "0.1.13"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
criterion = "0.3"
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "store"
|
||||||
|
harness=false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "print"
|
||||||
|
harness=false
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "util"
|
||||||
|
harness=false
|
||||||
|
|
89
benches/common.rs
Normal file
89
benches/common.rs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
fs::{self, DirEntry},
|
||||||
|
path::PathBuf,
|
||||||
|
sync::OnceLock,
|
||||||
|
};
|
||||||
|
|
||||||
|
use dixlib::{store, util::PackageDiff};
|
||||||
|
|
||||||
|
/// tries to get the path of the oldest nixos system derivation
|
||||||
|
/// this function is pretty hacky and only used so that
|
||||||
|
/// you don't have to specify a specific derivation to
|
||||||
|
/// run the benchmarks
|
||||||
|
fn get_oldest_nixos_system() -> Option<PathBuf> {
|
||||||
|
let profile_dir = fs::read_dir("/nix/var/nix/profiles").ok()?;
|
||||||
|
|
||||||
|
let files = profile_dir.filter_map(Result::ok).filter_map(|entry| {
|
||||||
|
entry
|
||||||
|
.file_type()
|
||||||
|
.ok()
|
||||||
|
.and_then(|f| f.is_symlink().then_some(entry.path()))
|
||||||
|
});
|
||||||
|
|
||||||
|
files.min_by_key(|path| {
|
||||||
|
// extract all digits from the file name and use that as key
|
||||||
|
let p = path.as_os_str().to_str().unwrap_or_default();
|
||||||
|
let digits: String = p.chars().filter(|c| c.is_ascii_digit()).collect();
|
||||||
|
// if we are not able to produce a key (e.g. because the path does not contain digits)
|
||||||
|
// we put it last
|
||||||
|
digits.parse::<u32>().unwrap_or(u32::MAX)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_deriv_query() -> &'static PathBuf {
|
||||||
|
static _QUERY_DERIV: OnceLock<PathBuf> = OnceLock::new();
|
||||||
|
_QUERY_DERIV.get_or_init(|| {
|
||||||
|
let path = PathBuf::from(
|
||||||
|
env::var("DIX_BENCH_NEW_SYSTEM")
|
||||||
|
.unwrap_or_else(|_| "/run/current-system/system".into()),
|
||||||
|
);
|
||||||
|
path
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn get_deriv_query_old() -> &'static PathBuf {
|
||||||
|
static _QUERY_DERIV: OnceLock<PathBuf> = OnceLock::new();
|
||||||
|
_QUERY_DERIV.get_or_init(|| {
|
||||||
|
let path = env::var("DIX_BENCH_OLD_SYSTEM")
|
||||||
|
.ok()
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.or(get_oldest_nixos_system())
|
||||||
|
.unwrap_or_else(|| PathBuf::from("/run/current-system/system"));
|
||||||
|
path
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_packages() -> &'static (Vec<String>, Vec<String>) {
|
||||||
|
static _PKGS: OnceLock<(Vec<String>, Vec<String>)> = OnceLock::new();
|
||||||
|
_PKGS.get_or_init(|| {
|
||||||
|
let pkgs_before = store::get_packages(std::path::Path::new(get_deriv_query_old()))
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.map(|(_, name)| name)
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
let pkgs_after = store::get_packages(std::path::Path::new(get_deriv_query()))
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.map(|(_, name)| name)
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
(pkgs_before, pkgs_after)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_pkg_diff() -> &'static PackageDiff<'static> {
|
||||||
|
static _PKG_DIFF: OnceLock<PackageDiff> = OnceLock::new();
|
||||||
|
_PKG_DIFF.get_or_init(|| {
|
||||||
|
let (pkgs_before, pkgs_after) = get_packages();
|
||||||
|
PackageDiff::new(pkgs_before, pkgs_after)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// prints the old and new NixOs system used for benchmarking
|
||||||
|
///
|
||||||
|
/// is used to give information about the old and new system
|
||||||
|
pub fn print_used_nixos_systems() {
|
||||||
|
let old = get_deriv_query_old();
|
||||||
|
let new = get_deriv_query();
|
||||||
|
println!("old system used {:?}", old);
|
||||||
|
println!("new system used {:?}", new);
|
||||||
|
}
|
86
benches/print.rs
Normal file
86
benches/print.rs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
use std::{fs::File, os::fd::AsRawFd};
|
||||||
|
|
||||||
|
use common::{get_pkg_diff, print_used_nixos_systems};
|
||||||
|
use criterion::{Criterion, black_box, criterion_group, criterion_main};
|
||||||
|
use dixlib::print;
|
||||||
|
|
||||||
|
/// reroutes stdout and stderr to the null device before
|
||||||
|
/// executing `f`
|
||||||
|
fn suppress_output<F: FnOnce()>(f: F) {
|
||||||
|
let stdout = std::io::stdout();
|
||||||
|
let stderr = std::io::stderr();
|
||||||
|
|
||||||
|
// Save original FDs
|
||||||
|
let orig_stdout_fd = stdout.as_raw_fd();
|
||||||
|
let orig_stderr_fd = stderr.as_raw_fd();
|
||||||
|
|
||||||
|
// Open /dev/null and get its FD
|
||||||
|
let devnull = File::create("/dev/null").unwrap();
|
||||||
|
let null_fd = devnull.as_raw_fd();
|
||||||
|
|
||||||
|
// Redirect stdout and stderr to /dev/null
|
||||||
|
let _ = unsafe { libc::dup2(null_fd, orig_stdout_fd) };
|
||||||
|
let _ = unsafe { libc::dup2(null_fd, orig_stderr_fd) };
|
||||||
|
|
||||||
|
f();
|
||||||
|
|
||||||
|
let _ = unsafe { libc::dup2(orig_stdout_fd, 1) };
|
||||||
|
let _ = unsafe { libc::dup2(orig_stderr_fd, 2) };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bench_print_added(c: &mut Criterion) {
|
||||||
|
print_used_nixos_systems();
|
||||||
|
let diff = get_pkg_diff();
|
||||||
|
c.bench_function("print_added", |b| {
|
||||||
|
b.iter(|| {
|
||||||
|
suppress_output(|| {
|
||||||
|
print::print_added(
|
||||||
|
black_box(&diff.added),
|
||||||
|
black_box(&diff.pkg_to_versions_post),
|
||||||
|
30,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pub fn bench_print_removed(c: &mut Criterion) {
|
||||||
|
print_used_nixos_systems();
|
||||||
|
let diff = get_pkg_diff();
|
||||||
|
c.bench_function("print_removed", |b| {
|
||||||
|
b.iter(|| {
|
||||||
|
suppress_output(|| {
|
||||||
|
print::print_removed(
|
||||||
|
black_box(&diff.removed),
|
||||||
|
black_box(&diff.pkg_to_versions_pre),
|
||||||
|
30,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pub fn bench_print_changed(c: &mut Criterion) {
|
||||||
|
print_used_nixos_systems();
|
||||||
|
let diff = get_pkg_diff();
|
||||||
|
c.bench_function("print_changed", |b| {
|
||||||
|
b.iter(|| {
|
||||||
|
suppress_output(|| {
|
||||||
|
print::print_changes(
|
||||||
|
black_box(&diff.changed),
|
||||||
|
black_box(&diff.pkg_to_versions_pre),
|
||||||
|
black_box(&diff.pkg_to_versions_post),
|
||||||
|
30,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group!(
|
||||||
|
benches,
|
||||||
|
bench_print_added,
|
||||||
|
bench_print_removed,
|
||||||
|
bench_print_changed
|
||||||
|
);
|
||||||
|
criterion_main!(benches);
|
36
benches/store.rs
Normal file
36
benches/store.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
mod common;
|
||||||
|
use criterion::{Criterion, black_box, criterion_group, criterion_main};
|
||||||
|
use dixlib::store;
|
||||||
|
|
||||||
|
// basic benchmarks using the current system
|
||||||
|
//
|
||||||
|
// problem: this is not reproducible at all
|
||||||
|
// since this is very depending on the current
|
||||||
|
// system and the nature of the system in general
|
||||||
|
//
|
||||||
|
// we might want to think about using a copy of the sqlite
|
||||||
|
// db to benchmark instead to make the results comparable
|
||||||
|
|
||||||
|
pub fn bench_get_packages(c: &mut Criterion) {
|
||||||
|
c.bench_function("get_packages", |b| {
|
||||||
|
b.iter(|| store::get_packages(black_box(common::get_deriv_query())));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pub fn bench_get_closure_size(c: &mut Criterion) {
|
||||||
|
c.bench_function("get_closure_size", |b| {
|
||||||
|
b.iter(|| store::get_closure_size(black_box(common::get_deriv_query())));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pub fn bench_get_dependency_graph(c: &mut Criterion) {
|
||||||
|
c.bench_function("get_dependency_graph", |b| {
|
||||||
|
b.iter(|| store::get_dependency_graph(black_box(common::get_deriv_query())));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group!(
|
||||||
|
benches,
|
||||||
|
bench_get_packages,
|
||||||
|
bench_get_closure_size,
|
||||||
|
bench_get_dependency_graph
|
||||||
|
);
|
||||||
|
criterion_main!(benches);
|
15
benches/util.rs
Normal file
15
benches/util.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
use common::get_packages;
|
||||||
|
use criterion::{Criterion, black_box, criterion_group, criterion_main};
|
||||||
|
use dixlib::util::PackageDiff;
|
||||||
|
|
||||||
|
pub fn bench_package_diff(c: &mut Criterion) {
|
||||||
|
let (pkgs_before, pkgs_after) = get_packages();
|
||||||
|
c.bench_function("PackageDiff::new", |b| {
|
||||||
|
b.iter(|| PackageDiff::new(black_box(pkgs_before), black_box(pkgs_after)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group!(benches, bench_package_diff);
|
||||||
|
criterion_main!(benches);
|
4
src/lib.rs
Normal file
4
src/lib.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
pub mod error;
|
||||||
|
pub mod print;
|
||||||
|
pub mod store;
|
||||||
|
pub mod util;
|
56
src/main.rs
56
src/main.rs
|
@ -1,19 +1,14 @@
|
||||||
mod print;
|
|
||||||
mod util;
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use core::str;
|
use core::str;
|
||||||
|
use dixlib::print;
|
||||||
|
use dixlib::store;
|
||||||
|
use dixlib::util::PackageDiff;
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
thread,
|
thread,
|
||||||
};
|
};
|
||||||
use yansi::Paint;
|
use yansi::Paint;
|
||||||
mod error;
|
|
||||||
mod store;
|
|
||||||
use error::AppError;
|
|
||||||
|
|
||||||
// Use type alias for Result with our custom error type
|
|
||||||
type Result<T> = std::result::Result<T, AppError>;
|
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(name = "dix")]
|
#[command(name = "dix")]
|
||||||
|
@ -145,42 +140,15 @@ fn main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Map from packages of the first closure to their version
|
let PackageDiff {
|
||||||
let mut pre = HashMap::<&str, HashSet<&str>>::new();
|
pkg_to_versions_pre: pre,
|
||||||
let mut post = HashMap::<&str, HashSet<&str>>::new();
|
pkg_to_versions_post: post,
|
||||||
|
pre_keys: _,
|
||||||
for p in &package_list_pre {
|
post_keys: _,
|
||||||
match util::get_version(&**p) {
|
added,
|
||||||
Ok((name, version)) => {
|
removed,
|
||||||
pre.entry(name).or_default().insert(version);
|
changed,
|
||||||
}
|
} = PackageDiff::new(&package_list_pre, &package_list_post);
|
||||||
Err(e) => {
|
|
||||||
debug!("Error parsing package version: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for p in &package_list_post {
|
|
||||||
match util::get_version(&**p) {
|
|
||||||
Ok((name, version)) => {
|
|
||||||
post.entry(name).or_default().insert(version);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
debug!("Error parsing package version: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare the package names of both versions
|
|
||||||
let pre_keys: HashSet<&str> = pre.keys().copied().collect();
|
|
||||||
let post_keys: HashSet<&str> = post.keys().copied().collect();
|
|
||||||
|
|
||||||
// Difference gives us added and removed packages
|
|
||||||
let added: HashSet<&str> = &post_keys - &pre_keys;
|
|
||||||
|
|
||||||
let removed: HashSet<&str> = &pre_keys - &post_keys;
|
|
||||||
// Get the intersection of the package names for version changes
|
|
||||||
let changed: HashSet<&str> = &pre_keys & &post_keys;
|
|
||||||
|
|
||||||
debug!("Added packages: {}", added.len());
|
debug!("Added packages: {}", added.len());
|
||||||
debug!("Removed packages: {}", removed.len());
|
debug!("Removed packages: {}", removed.len());
|
||||||
|
|
125
src/util.rs
125
src/util.rs
|
@ -1,18 +1,18 @@
|
||||||
use crate::error::AppError;
|
|
||||||
use log::{debug, error};
|
|
||||||
use regex::Regex;
|
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
cmp::Ordering,
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
string::ToString,
|
|
||||||
sync::OnceLock,
|
sync::OnceLock,
|
||||||
thread,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::error::AppError;
|
||||||
|
use log::debug;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
// Use type alias for Result with our custom error type
|
// Use type alias for Result with our custom error type
|
||||||
type Result<T> = std::result::Result<T, AppError>;
|
type Result<T> = std::result::Result<T, AppError>;
|
||||||
|
|
||||||
|
use std::string::ToString;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
enum VersionComponent {
|
enum VersionComponent {
|
||||||
Number(u64),
|
Number(u64),
|
||||||
|
@ -104,29 +104,6 @@ pub fn compare_versions(a: &str, b: &str) -> Ordering {
|
||||||
iter_a.cmp(iter_b)
|
iter_a.cmp(iter_b)
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test {
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_version_component_iter() {
|
|
||||||
use super::VersionComponent::{Number, Text};
|
|
||||||
use crate::util::VersionComponentIterator;
|
|
||||||
let v = "132.1.2test234-1-man----.--.......---------..---";
|
|
||||||
|
|
||||||
let comp: Vec<_> = VersionComponentIterator::new(v).collect();
|
|
||||||
assert_eq!(
|
|
||||||
comp,
|
|
||||||
[
|
|
||||||
Number(132),
|
|
||||||
Number(1),
|
|
||||||
Number(2),
|
|
||||||
Text("test".into()),
|
|
||||||
Number(234),
|
|
||||||
Number(1),
|
|
||||||
Text("man".into())
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Parses a nix store path to extract the packages name and version
|
/// Parses a nix store path to extract the packages name and version
|
||||||
///
|
///
|
||||||
/// This function first drops the inputs first 44 chars, since that is exactly the length of the /nix/store/... prefix. Then it matches that against our store path regex.
|
/// This function first drops the inputs first 44 chars, since that is exactly the length of the /nix/store/... prefix. Then it matches that against our store path regex.
|
||||||
|
@ -174,10 +151,96 @@ pub fn get_version<'a>(pack: impl Into<&'a str>) -> Result<(&'a str, &'a str)> {
|
||||||
|
|
||||||
// Returns a reference to the compiled regex pattern.
|
// Returns a reference to the compiled regex pattern.
|
||||||
// The regex is compiled only once.
|
// The regex is compiled only once.
|
||||||
fn store_path_regex() -> &'static Regex {
|
pub fn store_path_regex() -> &'static Regex {
|
||||||
static REGEX: OnceLock<Regex> = OnceLock::new();
|
static REGEX: OnceLock<Regex> = OnceLock::new();
|
||||||
REGEX.get_or_init(|| {
|
REGEX.get_or_init(|| {
|
||||||
Regex::new(r"(.+?)(-([0-9].*?))?$")
|
Regex::new(r"(.+?)(-([0-9].*?))?$")
|
||||||
.expect("Failed to compile regex pattern for nix store paths")
|
.expect("Failed to compile regex pattern for nix store paths")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: move this somewhere else, this does not really
|
||||||
|
// belong into this file
|
||||||
|
pub struct PackageDiff<'a> {
|
||||||
|
pub pkg_to_versions_pre: HashMap<&'a str, HashSet<&'a str>>,
|
||||||
|
pub pkg_to_versions_post: HashMap<&'a str, HashSet<&'a str>>,
|
||||||
|
pub pre_keys: HashSet<&'a str>,
|
||||||
|
pub post_keys: HashSet<&'a str>,
|
||||||
|
pub added: HashSet<&'a str>,
|
||||||
|
pub removed: HashSet<&'a str>,
|
||||||
|
pub changed: HashSet<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> PackageDiff<'a> {
|
||||||
|
pub fn new<S: AsRef<str> + 'a>(pkgs_pre: &'a [S], pkgs_post: &'a [S]) -> Self {
|
||||||
|
// Map from packages of the first closure to their version
|
||||||
|
let mut pre = HashMap::<&str, HashSet<&str>>::new();
|
||||||
|
let mut post = HashMap::<&str, HashSet<&str>>::new();
|
||||||
|
|
||||||
|
for p in pkgs_pre {
|
||||||
|
match get_version(p.as_ref()) {
|
||||||
|
Ok((name, version)) => {
|
||||||
|
pre.entry(name).or_default().insert(version);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
debug!("Error parsing package version: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for p in pkgs_post {
|
||||||
|
match get_version(p.as_ref()) {
|
||||||
|
Ok((name, version)) => {
|
||||||
|
post.entry(name).or_default().insert(version);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
debug!("Error parsing package version: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare the package names of both versions
|
||||||
|
let pre_keys: HashSet<&str> = pre.keys().copied().collect();
|
||||||
|
let post_keys: HashSet<&str> = post.keys().copied().collect();
|
||||||
|
|
||||||
|
// Difference gives us added and removed packages
|
||||||
|
let added: HashSet<&str> = &post_keys - &pre_keys;
|
||||||
|
|
||||||
|
let removed: HashSet<&str> = &pre_keys - &post_keys;
|
||||||
|
// Get the intersection of the package names for version changes
|
||||||
|
let changed: HashSet<&str> = &pre_keys & &post_keys;
|
||||||
|
Self {
|
||||||
|
pkg_to_versions_pre: pre,
|
||||||
|
pkg_to_versions_post: post,
|
||||||
|
pre_keys,
|
||||||
|
post_keys,
|
||||||
|
added,
|
||||||
|
removed,
|
||||||
|
changed,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod test {
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_version_component_iter() {
|
||||||
|
use super::VersionComponent::{Number, Text};
|
||||||
|
use crate::util::VersionComponentIterator;
|
||||||
|
let v = "132.1.2test234-1-man----.--.......---------..---";
|
||||||
|
|
||||||
|
let comp: Vec<_> = VersionComponentIterator::new(v).collect();
|
||||||
|
assert_eq!(
|
||||||
|
comp,
|
||||||
|
[
|
||||||
|
Number(132),
|
||||||
|
Number(1),
|
||||||
|
Number(2),
|
||||||
|
Text("test".into()),
|
||||||
|
Number(234),
|
||||||
|
Number(1),
|
||||||
|
Text("man".into())
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue