Alberto Ruiz [Wed, 18 Mar 2026 03:54:01 +0000 (03:54 +0000)]
Extract makeevr helper from makeevr_atts with memcpy optimization
Split makeevr_atts into a parsing wrapper and a makeevr helper that
takes pre-parsed epoch/ver/rel strings. The helper uses memcpy with
precomputed lengths instead of strcpy+strlen, avoiding redundant
string walks when building the EVR string. This also enables callers
that already have the parsed components to skip the attribute scan.
Alberto Ruiz [Wed, 18 Mar 2026 03:53:57 +0000 (03:53 +0000)]
Use hash table for XML element name lookup in solv_xmlparser
Replace the per-state linked list traversal with an open-addressing
hash table keyed on (fromstate, element_name). The old approach did
a linear scan with strcmp over all valid elements for the current
state on every XML start tag, which for STATE_SOLVABLE meant ~40
strcmp calls per tag. The hash table reduces this to typically one
hash probe plus one strcmp for confirmation.
Alberto Ruiz [Wed, 18 Mar 2026 07:23:09 +0000 (07:23 +0000)]
Add hash table to dirpool for O(1) directory lookup
Profiling repo2solv with perf on a full primary+filelists workload
(Fedora 42, ~75K packages) revealed that dirpool_add_dir consumed
48.6% of all cycles and caused 92% of last-level cache misses.
The root cause: directories sharing a parent are stored across
multiple non-contiguous blocks in the dirs[] array, linked through
the dirtraverse[] auxiliary array. Looking up whether a (parent,
component) pair already exists required scanning every block for
that parent -- O(B*C) where B is the number of blocks and C the
average block size. Popular parents like /usr accumulate hundreds
of blocks from filelists data, causing cache-hostile pointer chasing
across scattered memory.
Replace the dirtraverse-based lookup with an open-addressed hash
table mapping (parent, comp) pairs to directory ids. The hash is
computed via relhash() (same scheme used for reldeps), and parent
is verified by a short backward walk to the block header -- always
within a few entries of the matched slot, so it stays in the same
cache line.
The hash table is built on demand and resized at 50% load factor.
The dirtraverse array is kept for dirpool_child/dirpool_sibling
traversal APIs but is no longer needed for the add_dir fast path.
Benchmark results (Fedora 42 metadata, 5 runs, median wall-clock):
primary + filelists: 10,256 ms vs 20,028 ms baseline (49% faster)
primary only: 2,629 ms vs 2,546 ms baseline (within noise)
perf profile after the change shows dirpool_add_dir dropped from
48.6% to 1.78% of cycles. Output is byte-identical to baseline.
rewrite_suse_dep: always make a copy of the dependency string
Unfortunately we cannot call strn2id on a buffer coming from
id2str, as strn2id may reallocate the string space and then the copy
of the string will lead to access of freed memory.
Hijacking the isdefault variable makes the code hard to understand
and also can lead to the SOLVABLE_ISDEFAULT flag being set on
the environment if the last groupid used the default flag.
So just add a new "groupid_isdefault" flag. We also no longer downgrade
a "Requires" to a "Recommends" if the default attribute is set
in a grouplist entry.
Respect the "default" attribute in environment optionlist in comps xml
Add the default groups in optionlist with the "recommends" dependency
instead of "suggests" to differentiate between them.
The "reqtype" attribute of the "parsedata" structure cannot be used
directly, because it wouldn't be clear whether to use the "suggests" or
"requires" dependency for non-default groups, since the information was
already processed in the parent element and is not available at the time
of processing the individual "groupid" elements other than through the
"reqtype" attribute. Therefore, the "isdefault" attribute is used for
this.
Gong Zhile [Wed, 22 Oct 2025 10:14:30 +0000 (18:14 +0800)]
Fix qsort_r preprocessor for musl and FreeBSD
The original mentioned qsort_r signature difference now only exists in DragonFly
BSD & MacOS. However, the preprocessor also broke the compliation on musl+linux
and FreeBSD, leading the compilation error on buildroot.
solver_addbestrules: recalculate pointer to current rule after adding a new rule
The code adds new rules in a FOR_RULELITERALS loop. The iterator needs
to access elements of the rule it iterates over, so if we add a new
rule in the loop body, we have to make sure that the pointer to the
current rule stays valid.
repo_autopattern: support creation of obsoletes for product packages
This adds support for provides of the type "product-obsoletes(name)".
We translate this to "Obsoletes: product:<name>" in the generated
product pseudo package.
We need this because people used "Obsoletes: product:name" in the
"release" package, but this is no longer allowed in newer rpm versions.
Besides, the obsoletes is kind of wrong in the "release" package
anyway, it belongs in the generated "product:" package.
Implement color filtering when adding update targets
The old code created update jobs spanning multiple architectures
even if "implicitobsoleteusescolors" was set.
Also add color filtering in replaces_installed_package, where it
seems to be also missing
Petr Písař [Tue, 4 Mar 2025 08:02:22 +0000 (09:02 +0100)]
Increase CMake version to 3.5
CMake 4.0.0 removed a support for CMake scripts older than 3.5 and a build
with CMake 4.0.0-rc2 fails like this:
$ /usr/bin/cmake -S . -B redhat-linux-build
CMake Warning (dev) at CMakeLists.txt:1 (PROJECT):
cmake_minimum_required() should be called prior to this top-level project()
call. Please see the cmake-commands(7) manual for usage documentation of
both commands.
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Error at CMakeLists.txt:3 (CMAKE_MINIMUM_REQUIRED):
Compatibility with CMake < 3.5 has been removed from CMake.
Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
to tell CMake that the project requires at least <min> but has been updated
to work with policies introduced by <max> or earlier.
Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3.5 to try configuring anyway.
-- Configuring incomplete, errors occurred!
There seems to be no way of making the script working with all
versions. CMake 3.5 was relased in 2016.
This patch increases the minimal version to 3.5 and moves it to the top
of the script as it needs to be the very first thing of a script as
recommeded by cmake:
CMake Warning (dev) at CMakeLists.txt:1 (PROJECT):
cmake_minimum_required() should be called prior to this top-level project()
call. Please see the cmake-commands(7) manual for usage documentation of
both commands.
I did not set a supported upper version of CMake since I guess
we do not want to update it with every new minor CMake release.
Other printed CMake warnings are not news are not addressed with
this patch.