IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an
email to Administrator. User accounts are meant only to access repo
and report issues and/or generate pull requests.
This is a purpose-specific Git hosting for
BaseALT
projects. Thank you for your understanding!
Только зарегистрированные пользователи имеют доступ к сервису!
Для получения аккаунта, обратитесь к администратору.
C macros are nasty. We use them, but we try to be conservative with
them. In particular passing literal, complex code blocks as argument is
icky, because of "," handling of C, and also because it's quite a
challange for most code highlighters and similar. Hence, let's avoid
that. Using macros for genreating functions is OK but if so, the
parameters should be simple words, not full code blocks.
hence, rework DEFINE_CUSTOM_TEST_MAIN() to take a function name instead
of code block as argument.
As side-effect this also fixes a bunch of cases where we might end up
returning a negative value from main().
Some uses of DEFINE_CUSTOM_TEST_MAIN() inserted local variables into the
main() functions, these are replaced by static variables, and their
destructors by the static destructor logic.
This doesn't fix any bugs or so, it's just supposed to make the code
easier to work with and improve it easthetically.
Or in other words: let's use macros where it really makes sense, but
let's not go overboard with it.
(And yes, FOREACH_DIRENT() is another one of those macros that take
code, and I dislike that too and regret I ever added that.)
This converts to TEST macro in less trivial cases. This is mostly
due to having an intro or outro before/after the actual tests.
Some notable changes:
- add a "test" to make sure the hashmap and ordered_hashmap tests
from different compilation units are actually run in test-hashmap.c
- make root arg a global var in test-install-root.c
- slightly rework an EFI specific test in test-proc-cmdline.c
- usage of saved_argv/saved_argc in test-process-util.c
- splitting test-rlimit-util.c into several tests
- moving the hwdb open check into intro in test-sd-hwdb.c
- condense several "tests" into one in test-udev-util.c
The point here is to compare speed of hashmap_destroy with free and a different
freeing function, to the implementation details of hashmap_clear can be
evaluated.
Results:
current code:
/* test_hashmap_free (slow, 1048576 entries) */
string_hash_ops test took 2.494499s
custom_free_hash_ops test took 2.640449s
string_hash_ops test took 2.287734s
custom_free_hash_ops test took 2.557632s
string_hash_ops test took 2.299791s
custom_free_hash_ops test took 2.586975s
string_hash_ops test took 2.314099s
custom_free_hash_ops test took 2.589327s
string_hash_ops test took 2.319137s
custom_free_hash_ops test took 2.584038s
code with a patch which restores the "fast path" using:
for (idx = skip_free_buckets(h, 0); idx != IDX_NIL; idx = skip_free_buckets(h, idx + 1))
in the case where both free_key and free_value are either free or NULL:
/* test_hashmap_free (slow, 1048576 entries) */
string_hash_ops test took 2.347013s
custom_free_hash_ops test took 2.585104s
string_hash_ops test took 2.311583s
custom_free_hash_ops test took 2.578388s
string_hash_ops test took 2.283658s
custom_free_hash_ops test took 2.621675s
string_hash_ops test took 2.334675s
custom_free_hash_ops test took 2.601568s
So the test is noisy, but there clearly is no significant difference with the
"fast path" restored. I'm surprised by this, but it shows that the current
"safe" implementation does not cause a performance loss.
When the code is compiled with optimization, those times are significantly
lower (e.g. 1.1s and 1.4s), but again, there is no difference with the "fast
path" restored.
The difference between string_hash_ops and custom_free_hash_ops is the
additional cost of global modification and the extra function call.
This part of the copyright blurb stems from the GPL use recommendations:
https://www.gnu.org/licenses/gpl-howto.en.html
The concept appears to originate in times where version control was per
file, instead of per tree, and was a way to glue the files together.
Ultimately, we nowadays don't live in that world anymore, and this
information is entirely useless anyway, as people are very welcome to
copy these files into any projects they like, and they shouldn't have to
change bits that are part of our copyright header for that.
hence, let's just get rid of this old cruft, and shorten our codebase a
bit.
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.
I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
This is similar to string_hash_ops but operates one file system paths
specifically. It will ensure that "/foo//bar" and "///foo/bar" are
considered to be the same path for hashmap purposes.
This makes use of the existing path_compare() API, and adds a matching
hashing function for it.
Note that relative and absolute paths will hash to different values,
however whether the path is suffixed with a slash or not is not
detected. This matches the existing path_compare() behaviour, and
follows the logic that on Linux there can't be two different objects at
path /foo/bar and /foo/bar/ either.
gcc5 spits out a warning about test-hashmap.c:
CC src/test/test-hashmap.o
src/test/test-hashmap.c: In function ‘test_string_compare_func’:
src/test/test-hashmap.c:76:79: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses]
This patch removes includes that are not used. The removals were found with
include-what-you-use which checks if any of the symbols from a header is
in use.
test-hashmap-ordered.c is generated from test-hashmap-plain.c simply by
substituting "ordered_hashmap" for "hashmap" etc.
In the cases where tests rely on the order of entries, a distinction
between plain and ordered hashmaps is made using the ORDERED macro,
which is defined only for test-hashmap-ordered.c.
The following hashmap_* and set_* functions/macros have never had any
users in systemd's history:
*_iterate_backwards
*_iterate_skip
*_last
*_FOREACH_BACKWARDS
Remove this dead code.
It is redundant to store 'hash' and 'compare' function pointers in
struct Hashmap separately. The functions always comprise a pair.
Store a single pointer to struct hash_ops instead.
systemd keeps hundreds of hashmaps, so this saves a little bit of
memory.
Instead of fixing the hashmap bucket array to 127 entries dynamically
size it, starting with a smaller one of 31. As soon as a fill level of
75% is reached, quadruple the size, and so on.
This should siginficantly optimize the lookup time in large tables
(from O(n) back to O(1)), and save memory on smaller tables (which most
are).