diff options
author | Thomas Haller <thaller@redhat.com> | 2017-07-07 23:34:41 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-07-25 06:44:12 +0200 |
commit | 22edeb5b691befd796c534cf71901b32f0b7945b (patch) | |
tree | 98cdbd184ae8d73242d267d27f4882094ecbf236 /src/nm-ip4-config.h | |
parent | 74816a22374091f1cde34372387f8c6bfcd688dc (diff) |
core: track addresses for NMIP4Config/NMIP6Config via NMDedupMultiIndex
Reasons:
- it adds an O(1) lookup index for accessing NMIPxConfig's addresses.
Hence, operations like merge/intersect have now runtime O(n) instead
of O(n^2).
Arguably, we expect low numbers of addresses in general. For low
numbers, the O(n^2) doesn't matter and quite likely in those cases
the previous implementation was just fine -- maybe even faster.
But the simple case works fine either way. It's important to scale
well in the exceptional case.
- the tracked objects can be shared between the various NMPI4Config,
NMIP6Config instances with NMPlatform and everybody else.
- the NMPObject can be treated generically, meaning it enables code to
handle both IPv4 and IPv6, or addresses and routes. See for example
_nm_ip_config_add_obj().
- I want core to evolve to somewhere where we don't keep copies of
NMPlatformIP4Address, et al. instances. Instead they shall all be
shared. I hope this will reduce memory consumption (although tracking a
reference consumes some memory too). Also, it shortcuts nmp_object_equal()
when comparing the same object. Calling nmp_object_equal() on the
identical objects would be a common case after the hash function
pre-evaluates equality.
Diffstat (limited to 'src/nm-ip4-config.h')
-rw-r--r-- | src/nm-ip4-config.h | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 463aa15bb..e11043b79 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -25,6 +25,7 @@ #include "nm-setting-ip4-config.h" #include "nm-utils/nm-dedup-multi.h" +#include "platform/nmp-object.h" /*****************************************************************************/ @@ -35,19 +36,64 @@ typedef struct { void nm_ip_config_dedup_multi_idx_type_init (NMIPConfigDedupMultiIdxType *idx_type, NMPObjectType obj_type); -void nm_ip4_config_iter_ip4_route_init (NMDedupMultiIter *iter, const NMIP4Config *self); -gboolean nm_ip4_config_iter_ip4_route_next (NMDedupMultiIter *iter, const NMPlatformIP4Route **out_route); +/*****************************************************************************/ + +void nm_ip_config_iter_ip4_address_init (NMDedupMultiIter *iter, const NMIP4Config *self); +void nm_ip_config_iter_ip4_route_init (NMDedupMultiIter *iter, const NMIP4Config *self); + +static inline gboolean +nm_ip_config_iter_ip4_address_next (NMDedupMultiIter *ipconf_iter, const NMPlatformIP4Address **out_address) +{ + gboolean has_next; + + g_return_val_if_fail (out_address, FALSE); + + has_next = nm_dedup_multi_iter_next (ipconf_iter); + if (has_next) + *out_address = NMP_OBJECT_CAST_IP4_ADDRESS (ipconf_iter->current->obj); + return has_next; +} + +static inline gboolean +nm_ip_config_iter_ip4_route_next (NMDedupMultiIter *ipconf_iter, const NMPlatformIP4Route **out_route) +{ + gboolean has_next; -#define nm_ip4_config_iter_ip4_route_for_each(iter, self, route) \ - for (nm_ip4_config_iter_ip4_route_init ((iter), (self)); \ - nm_ip4_config_iter_ip4_route_next ((iter), (route)); \ - ) + g_return_val_if_fail (out_route, FALSE); + has_next = nm_dedup_multi_iter_next (ipconf_iter); + if (has_next) + *out_route = NMP_OBJECT_CAST_IP4_ROUTE (ipconf_iter->current->obj); + return has_next; +} + +#define nm_ip_config_iter_ip4_address_for_each(iter, self, address) \ + for (*(address) = NULL, nm_ip_config_iter_ip4_address_init ((iter), (self)); \ + nm_ip_config_iter_ip4_address_next ((iter), (address)); \ + ) + +#define nm_ip_config_iter_ip4_route_for_each(iter, self, route) \ + for (*(route) = NULL, nm_ip_config_iter_ip4_route_init ((iter), (self)); \ + nm_ip_config_iter_ip4_route_next ((iter), (route)); \ + ) + +/*****************************************************************************/ + +gboolean nm_ip_config_obj_id_equal_ip4_address (const NMPlatformIP4Address *a, + const NMPlatformIP4Address *b); +gboolean nm_ip_config_obj_id_equal_ip6_address (const NMPlatformIP6Address *a, + const NMPlatformIP6Address *b); gboolean nm_ip_config_obj_id_equal_ip4_route (const NMPlatformIP4Route *r_a, const NMPlatformIP4Route *r_b); gboolean nm_ip_config_obj_id_equal_ip6_route (const NMPlatformIP6Route *r_a, const NMPlatformIP6Route *r_b); +gboolean _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, + NMIPConfigDedupMultiIdxType *idx_type, + int ifindex, + const NMPObject *obj_new, + const NMPlatformObject *pl_new); + /*****************************************************************************/ #define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type ()) @@ -110,13 +156,16 @@ gboolean nm_ip4_config_has_gateway (const NMIP4Config *self); guint32 nm_ip4_config_get_gateway (const NMIP4Config *self); gint64 nm_ip4_config_get_route_metric (const NMIP4Config *self); +const NMDedupMultiHeadEntry *nm_ip4_config_lookup_addresses (const NMIP4Config *self); void nm_ip4_config_reset_addresses (NMIP4Config *self); void nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *address); -void nm_ip4_config_del_address (NMIP4Config *self, guint i); +void _nmtst_nm_ip4_config_del_address (NMIP4Config *self, guint i); guint nm_ip4_config_get_num_addresses (const NMIP4Config *self); -const NMPlatformIP4Address *nm_ip4_config_get_address (const NMIP4Config *self, guint i); +const NMPlatformIP4Address *nm_ip4_config_get_first_address (const NMIP4Config *self); +const NMPlatformIP4Address *_nmtst_nm_ip4_config_get_address (const NMIP4Config *self, guint i); gboolean nm_ip4_config_address_exists (const NMIP4Config *self, const NMPlatformIP4Address *address); +const NMDedupMultiHeadEntry *nm_ip4_config_lookup_routes (const NMIP4Config *self); void nm_ip4_config_reset_routes (NMIP4Config *self); void nm_ip4_config_add_route (NMIP4Config *self, const NMPlatformIP4Route *route); void _nmtst_nm_ip4_config_del_route (NMIP4Config *self, guint i); |