NetworkManager/src/libnmc-setting
Thomas Haller 611f2c3a60
libnm: use binary search for nm_meta_setting_infos_by_gtype() for libnmc
The file "nm-meta-setting-base-impl.c" is shared by "libnm-core-impl" and
"libnmc-setting". For "libnm-core-impl" it uses a efficient lookup from the
gtype. For "libnmc-setting", that class information is not available, so
it did a linear search. Instead, do a binary search.

Tested:

    diff --git a/src/libnm-core-impl/nm-meta-setting-base-impl.c b/src/libnm-core-impl/nm-meta-setting-base-impl.c
    index 3434c858391f..62c366d2ca42 100644
    --- a/src/libnm-core-impl/nm-meta-setting-base-impl.c
    +++ b/src/libnm-core-impl/nm-meta-setting-base-impl.c
    @@ -821,6 +821,11 @@ nm_meta_setting_infos_by_gtype(GType gtype)
     {
         const NMMetaSettingInfo *setting_info;

    +#if _NM_META_SETTING_BASE_IMPL_LIBNM
    +    return _infos_by_gtype_binary_search(gtype);
    +#endif
    +    nm_assert_not_reached();
    +
     #if _NM_META_SETTING_BASE_IMPL_LIBNM
         setting_info = _infos_by_gtype_from_class(gtype);
     #else
    diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c
    index 85d549eb766c..65fcafd076c9 100644
    --- a/src/libnm-core-impl/tests/test-setting.c
    +++ b/src/libnm-core-impl/tests/test-setting.c
    @@ -5134,6 +5134,29 @@ main(int argc, char **argv)
     {
         nmtst_init(&argc, &argv, TRUE);

    +    {
    +        gs_unref_object NMConnection *con = NULL;
    +        guint8                        ctr = 0;
    +        guint                         i;
    +
    +        con = nmtst_create_minimal_connection("test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL);
    +
    +        nm_connection_add_setting(con, nm_setting_wired_new());
    +
    +        nmtst_connection_normalize(con);
    +        nmtst_assert_connection_verifies_without_normalization(con);
    +
    +        for (i = 0; i < 10000000; i++) {
    +            ctr += GPOINTER_TO_UINT(nm_connection_get_setting(con, NM_TYPE_SETTING_WIRED));
    +            ctr += GPOINTER_TO_UINT(nm_connection_get_setting(con, NM_TYPE_SETTING_CONNECTION));
    +            ctr += GPOINTER_TO_UINT(nm_connection_get_setting(con, NM_TYPE_SETTING_PROXY));
    +            ctr += GPOINTER_TO_UINT(nm_connection_get_setting(con, NM_TYPE_SETTING_WIREGUARD));
    +            ctr += GPOINTER_TO_UINT(nm_connection_get_setting(con, NM_TYPE_SETTING_IP4_CONFIG));
    +        }
    +
    +        return !!ctr;
    +    }
    +
         g_test_add_func("/libnm/test_connection_uuid", test_connection_uuid);

         g_test_add_func("/libnm/settings/test_nm_meta_setting_types_by_priority",

Results of `make src/libnm-core-impl/tests/test-setting && libtool --mode=execute perf stat -r 5 -B src/libnm-core-impl/tests/test-setting`:

 1) previous linear search: 3,182.81 msec
 2) bsearch not inlined:    1,611.19 msec
 3) bsearch open-coded:     1,214.45 msec
 4) bsearch inlined:        1,167.70 msec
 5) lookup from class:      1,147.64 msec

 1) previous implementation
 2) using nm_array_find_bsearch()
 3) manually implementing binary search
 4) using nm_array_find_bsearch_inline()
 5) only available to libnm-core as it uses internal meta data

Note that for "libnm-core-impl" the implementation was already fast (5), and
it didn't change. It only changed to binary search for "libnmc-setting",
which arguably is a less strong use-case.
2022-10-11 08:59:49 +02:00
..
tests libnm-client: Add public nm_conn_wireguard_import() func 2022-07-21 14:53:26 +02:00
meson.build doc: preserve paraghraphs in nmcli man pages 2022-07-15 17:25:15 +02:00
nm-meta-setting-access.c all: use nm_g_array_{index,first,last,index_p}() instead of g_array_index() 2022-09-15 12:39:07 +02:00
nm-meta-setting-access.h format: reformat source tree with clang-format 13.0 2021-11-29 09:31:09 +00:00
nm-meta-setting-base-impl.c libnm: use binary search for nm_meta_setting_infos_by_gtype() for libnmc 2022-10-11 08:59:49 +02:00
nm-meta-setting-base-impl.h libnm: add nm_setting_8021x_scheme_vtable_by_setting_key() helper 2022-03-28 18:27:36 +02:00
nm-meta-setting-base.h build: move "clients/common/" to "src/libnmc-{base,setting}/" 2021-03-02 08:38:25 +01:00
nm-meta-setting-desc.c ovs: add ofport_request option to ovs interface 2022-09-02 08:46:36 +00:00
nm-meta-setting-desc.h nmcli: add get_env_flags() accessor to NMMetaEnvironment for checking offline mode 2022-08-31 19:20:11 +02:00
README.md all: add some README.md files describing the purpose of our sources 2021-08-19 17:51:11 +02:00
settings-docs.h.in tools: preserve newlines and indentation in "generate-docs-nm-property-infos.py" 2022-10-06 13:40:29 +02:00

libnmc-setting

A client library on top of libnm (and libnm-base). Like libnmc-base, this is a helper library that a libnm client could use.

But its purpose is more specific. It's mainly about providing a generic API for handling connection properties. As such, it's only used by nmcli and in practice also specific to nmcli.

Theoretically, the API is supposed to be generic, so we could imagine another client that uses this beside nmcli.

Like libnm-base, this has a similar purpose and application as ../libnm-client-aux-extern/, the difference is that it's even more specific.