]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Hash: Assert that table is not resized during HASH_WALK
authorIgor Putovny <igor.putovny@nic.cz>
Wed, 11 Jun 2025 15:44:38 +0000 (17:44 +0200)
committerMaria Matejka <mq@ucw.cz>
Mon, 22 Sep 2025 11:35:02 +0000 (13:35 +0200)
According to measurements of hash_test, hash table with this assertion added
was not found to be significantly slower than without it on average. Therefore
we conclude that this addition would not hamper the performance of HASH_WALK.

lib/hash.h

index 47029385956f53a9e194408d09ac10009f91700f..c08458109d48aee2b05b58bb70f42b7fa42b92f9 100644 (file)
 #define HASH_WALK(v,next,n)                                            \
   do {                                                                 \
     HASH_TYPE(v) *n;                                                   \
+    const uint _count = (v).count;                                     \
     uint _i;                                                           \
     uint _s = HASH_SIZE(v);                                            \
     for (_i = 0; _i < _s; _i++)                                                \
-      for (n = (v).data[_i]; n; n = n->next)
+      for (n = (v).data[_i]; n;                                                \
+         ({ASSERT_DIE(v.count == _count);}), n = n->next)
 
 #define HASH_WALK_END } while (0)
 
 #define HASH_WALK_DELSAFE(v,next,n)                                    \
   do {                                                                 \
     HASH_TYPE(v) *n, *_next;                                           \
+    const uint _order = (v).order;                                     \
     uint _i;                                                           \
     uint _s = HASH_SIZE(v);                                            \
     for (_i = 0; _i < _s; _i++)                                                \
-      for (n = (v).data[_i]; n && (_next = n->next, 1); n = _next)
+      for (n = (v).data[_i]; n && (_next = n->next, 1);                        \
+        ({ASSERT_DIE((v).order == _order);}), n = _next)
 
 #define HASH_WALK_DELSAFE_END } while (0)
 
 #define HASH_WALK_FILTER(v,next,n,nn)                                  \
   do {                                                                 \
     HASH_TYPE(v) *n, **nn;                                             \
+    const uint _order = (v).order;                                     \
     uint _i;                                                           \
     uint _s = HASH_SIZE(v);                                            \
     for (_i = 0; _i < _s; _i++)                                                \
-      for (nn = (v).data + _i; n = *nn; (*nn == n) ? (nn = &n->next) : NULL)
+      for (nn = (v).data + _i; n = *nn;                                        \
+         ({ASSERT_DIE((v).order == _order);}),                         \
+         (*nn == n) ? (nn = &n->next) : NULL)
 
 #define HASH_WALK_FILTER_END } while (0)