From 53568e6f838e3d6811658fe3a54d1853747c7e75 Mon Sep 17 00:00:00 2001 From: Richard Patel Date: Tue, 10 Dec 2024 08:14:51 +0000 Subject: [PATCH] Fix fd_redblack symbol visibility Fixes an issue where fd_redblack produces externally linked symbols even if the implementation style is set to 'local use only'. --- src/disco/rpcserver/fd_rpc_service.c | 5 +- src/flamenco/types/fd_types.c | 14 ---- src/flamenco/types/fd_types.h | 14 ---- src/flamenco/types/fd_types_custom.c | 3 +- src/flamenco/types/fd_types_custom.h | 4 +- src/flamenco/types/gen_stubs.py | 4 -- src/util/tmpl/fd_redblack.c | 100 +++++++++++++++------------ src/util/tmpl/test_redblack.c | 21 +++--- src/util/tmpl/test_redblack2.c | 9 +-- 9 files changed, 74 insertions(+), 100 deletions(-) diff --git a/src/disco/rpcserver/fd_rpc_service.c b/src/disco/rpcserver/fd_rpc_service.c index da65005575..c6ec88a00e 100644 --- a/src/disco/rpcserver/fd_rpc_service.c +++ b/src/disco/rpcserver/fd_rpc_service.c @@ -565,7 +565,7 @@ struct product_rb_node { typedef struct product_rb_node product_rb_node_t; #define REDBLK_T product_rb_node_t #define REDBLK_NAME product_rb -FD_FN_PURE long product_rb_compare(product_rb_node_t* left, product_rb_node_t* right) { +FD_FN_PURE static long product_rb_compare(product_rb_node_t* left, product_rb_node_t* right) { for( uint i = 0; i < sizeof(fd_pubkey_t)/sizeof(ulong); ++i ) { ulong a = left->key.ul[i]; ulong b = right->key.ul[i]; @@ -574,7 +574,6 @@ FD_FN_PURE long product_rb_compare(product_rb_node_t* left, product_rb_node_t* r return 0; } #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_NAME static int method_getBlockProduction(struct json_values* values, fd_rpc_ctx_t * ctx) { @@ -1023,7 +1022,7 @@ struct leader_rb_node { typedef struct leader_rb_node leader_rb_node_t; #define REDBLK_T leader_rb_node_t #define REDBLK_NAME leader_rb -FD_FN_PURE long leader_rb_compare(leader_rb_node_t* left, leader_rb_node_t* right) { +FD_FN_PURE static long leader_rb_compare(leader_rb_node_t* left, leader_rb_node_t* right) { for( uint i = 0; i < sizeof(fd_pubkey_t)/sizeof(ulong); ++i ) { ulong a = left->key.ul[i]; ulong b = right->key.ul[i]; diff --git a/src/flamenco/types/fd_types.c b/src/flamenco/types/fd_types.c index a278177209..fda01d57dc 100644 --- a/src/flamenco/types/fd_types.c +++ b/src/flamenco/types/fd_types.c @@ -32291,8 +32291,6 @@ ulong fd_duplicate_slot_proof_size( fd_duplicate_slot_proof_t const * self ) { #define REDBLK_NAME fd_hash_hash_age_pair_t_map #define REDBLK_IMPL_STYLE 2 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME long fd_hash_hash_age_pair_t_map_compare( fd_hash_hash_age_pair_t_mapnode_t * left, fd_hash_hash_age_pair_t_mapnode_t * right ) { return memcmp( left->elem.key.uc, right->elem.key.uc, sizeof(right->elem.key) ); } @@ -32300,8 +32298,6 @@ long fd_hash_hash_age_pair_t_map_compare( fd_hash_hash_age_pair_t_mapnode_t * le #define REDBLK_NAME fd_vote_accounts_pair_t_map #define REDBLK_IMPL_STYLE 2 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME long fd_vote_accounts_pair_t_map_compare( fd_vote_accounts_pair_t_mapnode_t * left, fd_vote_accounts_pair_t_mapnode_t * right ) { return memcmp( left->elem.key.uc, right->elem.key.uc, sizeof(right->elem.key) ); } @@ -32309,8 +32305,6 @@ long fd_vote_accounts_pair_t_map_compare( fd_vote_accounts_pair_t_mapnode_t * le #define REDBLK_NAME fd_stake_accounts_pair_t_map #define REDBLK_IMPL_STYLE 2 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME long fd_stake_accounts_pair_t_map_compare( fd_stake_accounts_pair_t_mapnode_t * left, fd_stake_accounts_pair_t_mapnode_t * right ) { return memcmp( left->elem.key.uc, right->elem.key.uc, sizeof(right->elem.key) ); } @@ -32318,8 +32312,6 @@ long fd_stake_accounts_pair_t_map_compare( fd_stake_accounts_pair_t_mapnode_t * #define REDBLK_NAME fd_stake_weight_t_map #define REDBLK_IMPL_STYLE 2 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME long fd_stake_weight_t_map_compare( fd_stake_weight_t_mapnode_t * left, fd_stake_weight_t_mapnode_t * right ) { return memcmp( left->elem.key.uc, right->elem.key.uc, sizeof(right->elem.key) ); } @@ -32327,8 +32319,6 @@ long fd_stake_weight_t_map_compare( fd_stake_weight_t_mapnode_t * left, fd_stake #define REDBLK_NAME fd_delegation_pair_t_map #define REDBLK_IMPL_STYLE 2 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME long fd_delegation_pair_t_map_compare( fd_delegation_pair_t_mapnode_t * left, fd_delegation_pair_t_mapnode_t * right ) { return memcmp( left->elem.account.uc, right->elem.account.uc, sizeof(right->elem.account) ); } @@ -32336,8 +32326,6 @@ long fd_delegation_pair_t_map_compare( fd_delegation_pair_t_mapnode_t * left, fd #define REDBLK_NAME fd_stake_pair_t_map #define REDBLK_IMPL_STYLE 2 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME long fd_stake_pair_t_map_compare( fd_stake_pair_t_mapnode_t * left, fd_stake_pair_t_mapnode_t * right ) { return memcmp( left->elem.account.uc, right->elem.account.uc, sizeof(right->elem.account) ); } @@ -32345,8 +32333,6 @@ long fd_stake_pair_t_map_compare( fd_stake_pair_t_mapnode_t * left, fd_stake_pai #define REDBLK_NAME fd_clock_timestamp_vote_t_map #define REDBLK_IMPL_STYLE 2 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME long fd_clock_timestamp_vote_t_map_compare( fd_clock_timestamp_vote_t_mapnode_t * left, fd_clock_timestamp_vote_t_mapnode_t * right ) { return memcmp( left->elem.pubkey.uc, right->elem.pubkey.uc, sizeof(right->elem.pubkey) ); } diff --git a/src/flamenco/types/fd_types.h b/src/flamenco/types/fd_types.h index e00c3565c4..a26e998d68 100644 --- a/src/flamenco/types/fd_types.h +++ b/src/flamenco/types/fd_types.h @@ -103,8 +103,6 @@ typedef struct fd_hash_hash_age_pair_t_mapnode fd_hash_hash_age_pair_t_mapnode_t #define REDBLK_NAME fd_hash_hash_age_pair_t_map #define REDBLK_IMPL_STYLE 1 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME struct fd_hash_hash_age_pair_t_mapnode { fd_hash_hash_age_pair_t elem; ulong redblack_parent; @@ -498,8 +496,6 @@ typedef struct fd_vote_accounts_pair_t_mapnode fd_vote_accounts_pair_t_mapnode_t #define REDBLK_NAME fd_vote_accounts_pair_t_map #define REDBLK_IMPL_STYLE 1 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME struct fd_vote_accounts_pair_t_mapnode { fd_vote_accounts_pair_t elem; ulong redblack_parent; @@ -551,8 +547,6 @@ typedef struct fd_stake_accounts_pair_t_mapnode fd_stake_accounts_pair_t_mapnode #define REDBLK_NAME fd_stake_accounts_pair_t_map #define REDBLK_IMPL_STYLE 1 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME struct fd_stake_accounts_pair_t_mapnode { fd_stake_accounts_pair_t elem; ulong redblack_parent; @@ -605,8 +599,6 @@ typedef struct fd_stake_weight_t_mapnode fd_stake_weight_t_mapnode_t; #define REDBLK_NAME fd_stake_weight_t_map #define REDBLK_IMPL_STYLE 1 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME struct fd_stake_weight_t_mapnode { fd_stake_weight_t elem; ulong redblack_parent; @@ -717,8 +709,6 @@ typedef struct fd_delegation_pair_t_mapnode fd_delegation_pair_t_mapnode_t; #define REDBLK_NAME fd_delegation_pair_t_map #define REDBLK_IMPL_STYLE 1 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME struct fd_delegation_pair_t_mapnode { fd_delegation_pair_t elem; ulong redblack_parent; @@ -762,8 +752,6 @@ typedef struct fd_stake_pair_t_mapnode fd_stake_pair_t_mapnode_t; #define REDBLK_NAME fd_stake_pair_t_map #define REDBLK_IMPL_STYLE 1 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME struct fd_stake_pair_t_mapnode { fd_stake_pair_t elem; ulong redblack_parent; @@ -2200,8 +2188,6 @@ typedef struct fd_clock_timestamp_vote_t_mapnode fd_clock_timestamp_vote_t_mapno #define REDBLK_NAME fd_clock_timestamp_vote_t_map #define REDBLK_IMPL_STYLE 1 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME struct fd_clock_timestamp_vote_t_mapnode { fd_clock_timestamp_vote_t elem; ulong redblack_parent; diff --git a/src/flamenco/types/fd_types_custom.c b/src/flamenco/types/fd_types_custom.c index 60d6a1c289..c1fd5da2d2 100644 --- a/src/flamenco/types/fd_types_custom.c +++ b/src/flamenco/types/fd_types_custom.c @@ -372,8 +372,7 @@ int fd_archive_decode_skip_field( fd_bincode_decode_ctx_t * ctx, ushort tag ) { #define REDBLK_NAME fd_vote_reward_t_map #define REDBLK_IMPL_STYLE 2 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME + long fd_vote_reward_t_map_compare( fd_vote_reward_t_mapnode_t * left, fd_vote_reward_t_mapnode_t * right ) { return memcmp( left->elem.pubkey.uc, right->elem.pubkey.uc, sizeof(right->elem.pubkey) ); } diff --git a/src/flamenco/types/fd_types_custom.h b/src/flamenco/types/fd_types_custom.h index 498743b4db..93640fec52 100644 --- a/src/flamenco/types/fd_types_custom.h +++ b/src/flamenco/types/fd_types_custom.h @@ -258,8 +258,6 @@ typedef struct fd_vote_reward_t_mapnode fd_vote_reward_t_mapnode_t; #define REDBLK_NAME fd_vote_reward_t_map #define REDBLK_IMPL_STYLE 1 #include "../../util/tmpl/fd_redblack.c" -#undef REDBLK_T -#undef REDBLK_NAME struct fd_vote_reward_t_mapnode { fd_vote_reward_t elem; ulong redblack_parent; @@ -388,7 +386,7 @@ typedef struct fd_epoch_reward_status fd_epoch_reward_status_t; enum { fd_epoch_reward_status_enum_Active = 0, fd_epoch_reward_status_enum_Inactive = 1, -}; +}; /*******************************************************************************************/ #endif diff --git a/src/flamenco/types/gen_stubs.py b/src/flamenco/types/gen_stubs.py index fc8bb21051..caffd5be59 100644 --- a/src/flamenco/types/gen_stubs.py +++ b/src/flamenco/types/gen_stubs.py @@ -866,8 +866,6 @@ def emitPreamble(self): print(f"#define REDBLK_NAME {mapname}", file=header) print(f"#define REDBLK_IMPL_STYLE 1", file=header) print(f'#include "../../util/tmpl/fd_redblack.c"', file=header) - print(f"#undef REDBLK_T", file=header) - print(f"#undef REDBLK_NAME", file=header) print(f"struct {nodename} {{", file=header) print(f" {element_type} elem;", file=header) print(f" ulong redblack_parent;", file=header) @@ -893,8 +891,6 @@ def emitPostamble(self): print(f'#define REDBLK_NAME {mapname}', file=body) print(f'#define REDBLK_IMPL_STYLE 2', file=body) print(f'#include "../../util/tmpl/fd_redblack.c"', file=body) - print(f'#undef REDBLK_T', file=body) - print(f'#undef REDBLK_NAME', file=body) print(f'long {mapname}_compare( {nodename} * left, {nodename} * right ) {{', file=body) key = self.key if key == "pubkey" or key == "account" or key == "key": diff --git a/src/util/tmpl/fd_redblack.c b/src/util/tmpl/fd_redblack.c index a016404acf..6766b31957 100644 --- a/src/util/tmpl/fd_redblack.c +++ b/src/util/tmpl/fd_redblack.c @@ -11,12 +11,12 @@ Tree nodes are allocated from a pool before insertion. After removal, they are returned to the pool. The pool is the result of the join operation. - + Multiple trees can coexist in the same pool, provided the total size of all the trees does not exceed the pool size. This is convenient for removing nodes from one tree and inserting them into another without copying the key or value. - + Example usage: struct my_rb_node { @@ -128,7 +128,7 @@ /* Namespace macro */ #define REDBLK_(n) FD_EXPAND_THEN_CONCAT3(REDBLK_NAME,_,n) -#if REDBLK_IMPL_STYLE==0 || REDBLK_IMPL_STYLE==1 /* need structures and inlines */ +#if REDBLK_IMPL_STYLE==1 /* need structures and inlines */ FD_PROTOTYPES_BEGIN @@ -235,7 +235,7 @@ REDBLK_T * REDBLK_(acquire)( REDBLK_T * pool ); my_node_t * n = my_rb_find( pool, root, &k ); n = my_rb_remove( pool, &root, n ); my_rb_release( pool, n ); - + */ void REDBLK_(release)( REDBLK_T * pool, REDBLK_T * node ); @@ -323,7 +323,7 @@ REDBLK_T * REDBLK_(insert)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * x); Remove a node from a tree. The node must be a member of the tree, usually the result of a find operation. The node is typically released to the pool afterwards. For example: - + my_node_t * n = my_rb_find( pool, root, &k ); n = my_rb_remove( pool, &root, n ); my_rb_pool_release( pool, n ); @@ -387,7 +387,7 @@ int REDBLK_(verify)(REDBLK_T * pool, REDBLK_T * root); /* E.g. long my_rb_compare(my_node_t * left, my_node_t * right); - + Defined by application to implement key comparison. Returns a negative number, zero, or positive depending on whether the left is less than, equal to, or greater than right. For example: @@ -404,6 +404,12 @@ FD_PROTOTYPES_END #endif /* REDBLK_IMPL_STYLE==0 || REDBLK_IMPL_STYLE==1 */ +#if REDBLK_IMPL_STYLE==0 /* local only */ +#define REDBLK_IMPL_STATIC FD_FN_UNUSED static +#else +#define REDBLK_IMPL_STATIC +#endif + #if REDBLK_IMPL_STYLE==0 || REDBLK_IMPL_STYLE==2 /* need implementations */ /* Tree node colors */ @@ -441,19 +447,19 @@ FD_PROTOTYPES_END #define REDBLK_NIL 0UL /* Must be same as pool sentinel */ -ulong REDBLK_(max_for_footprint)( ulong footprint ) { +REDBLK_IMPL_STATIC ulong REDBLK_(max_for_footprint)( ulong footprint ) { return REDBLK_POOL_(max_for_footprint)(footprint) - 1; /* Allow for sentinel */ } -ulong REDBLK_(align)( void ) { +REDBLK_IMPL_STATIC ulong REDBLK_(align)( void ) { return REDBLK_POOL_(align)(); } -ulong REDBLK_(footprint)( ulong max ) { +REDBLK_IMPL_STATIC ulong REDBLK_(footprint)( ulong max ) { return REDBLK_POOL_(footprint)(max + 1); /* Allow for sentinel */ } -void * REDBLK_(new)( void * shmem, ulong max ) { +REDBLK_IMPL_STATIC void * REDBLK_(new)( void * shmem, ulong max ) { void * shmem2 = REDBLK_POOL_(new)(shmem, max + 1); /* Allow for sentinel */ if ( FD_UNLIKELY( shmem2 == NULL ) ) return NULL; @@ -469,38 +475,38 @@ void * REDBLK_(new)( void * shmem, ulong max ) { return shmem2; } -REDBLK_T * REDBLK_(join)( void * shpool ) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(join)( void * shpool ) { FD_COMPILER_MFENCE(); return REDBLK_POOL_(join)(shpool); } -void * REDBLK_(leave)( REDBLK_T * pool ) { +REDBLK_IMPL_STATIC void * REDBLK_(leave)( REDBLK_T * pool ) { FD_COMPILER_MFENCE(); return REDBLK_POOL_(leave)(pool); } -void * REDBLK_(delete)( void * shpool ) { +REDBLK_IMPL_STATIC void * REDBLK_(delete)( void * shpool ) { FD_COMPILER_MFENCE(); return REDBLK_POOL_(delete)(shpool); } -ulong REDBLK_(max)( REDBLK_T const * pool ) { +REDBLK_IMPL_STATIC ulong REDBLK_(max)( REDBLK_T const * pool ) { return REDBLK_POOL_(max)(pool) - 1; /* Allow for sentinel */ } -ulong REDBLK_(free)( REDBLK_T const * pool ) { +REDBLK_IMPL_STATIC ulong REDBLK_(free)( REDBLK_T const * pool ) { return REDBLK_POOL_(free)(pool); } -ulong REDBLK_(idx)( REDBLK_T const * pool, REDBLK_T const * node ) { +REDBLK_IMPL_STATIC ulong REDBLK_(idx)( REDBLK_T const * pool, REDBLK_T const * node ) { return REDBLK_POOL_(idx)(pool, node); } -REDBLK_T * REDBLK_(node)( REDBLK_T * pool, ulong idx ) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(node)( REDBLK_T * pool, ulong idx ) { return REDBLK_POOL_(ele)(pool, idx); } -REDBLK_T * REDBLK_(acquire)( REDBLK_T * pool ) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(acquire)( REDBLK_T * pool ) { if ( REDBLK_POOL_(free)( pool ) == 0 ) return NULL; REDBLK_T * node = REDBLK_POOL_(ele_acquire)(pool); @@ -509,13 +515,13 @@ REDBLK_T * REDBLK_(acquire)( REDBLK_T * pool ) { } #ifndef REDBLK_UNSAFE -void REDBLK_(validate_element)( REDBLK_T * pool, REDBLK_T * node ) { +REDBLK_IMPL_STATIC void REDBLK_(validate_element)( REDBLK_T * pool, REDBLK_T * node ) { if ( !REDBLK_POOL_(ele_test)( pool, node ) ) FD_LOG_ERR(( "invalid redblack node" )); if ( node && node->REDBLK_COLOR == REDBLK_FREE ) FD_LOG_ERR(( "invalid redblack node" )); } -void REDBLK_(validate_element_const)( REDBLK_T const * pool, REDBLK_T const * node ) { +REDBLK_IMPL_STATIC void REDBLK_(validate_element_const)( REDBLK_T const * pool, REDBLK_T const * node ) { if ( !REDBLK_POOL_(ele_test)( pool, node ) ) FD_LOG_ERR(( "invalid redblack node" )); if ( node && node->REDBLK_COLOR == REDBLK_FREE ) @@ -523,7 +529,7 @@ void REDBLK_(validate_element_const)( REDBLK_T const * pool, REDBLK_T const * no } #endif -void REDBLK_(release)( REDBLK_T * pool, REDBLK_T * node ) { +REDBLK_IMPL_STATIC void REDBLK_(release)( REDBLK_T * pool, REDBLK_T * node ) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, node); #endif @@ -536,17 +542,17 @@ void REDBLK_(release)( REDBLK_T * pool, REDBLK_T * node ) { Recursively release all nodes in a tree to a pool. The root argument is invalid after this method is called. */ -void REDBLK_(release_tree)( REDBLK_T * pool, REDBLK_T * node ) { +REDBLK_IMPL_STATIC void REDBLK_(release_tree)( REDBLK_T * pool, REDBLK_T * node ) { if (!node || node == &pool[REDBLK_NIL]) return; #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, node); #endif - + REDBLK_T * left = &pool[node->REDBLK_LEFT]; REDBLK_T * right = &pool[node->REDBLK_RIGHT]; - + REDBLK_(release)(pool, node); REDBLK_(release_tree)(pool, left); @@ -556,7 +562,7 @@ void REDBLK_(release_tree)( REDBLK_T * pool, REDBLK_T * node ) { /* Return the node in a tree that has the smallest key (leftmost). */ -REDBLK_T * REDBLK_(minimum)(REDBLK_T * pool, REDBLK_T * node) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(minimum)(REDBLK_T * pool, REDBLK_T * node) { if (!node || node == &pool[REDBLK_NIL]) return NULL; #ifndef REDBLK_UNSAFE @@ -567,7 +573,7 @@ REDBLK_T * REDBLK_(minimum)(REDBLK_T * pool, REDBLK_T * node) { } return node; } -REDBLK_T const * REDBLK_(minimum_const)(REDBLK_T const * pool, REDBLK_T const * node) { +REDBLK_IMPL_STATIC REDBLK_T const * REDBLK_(minimum_const)(REDBLK_T const * pool, REDBLK_T const * node) { if (!node || node == &pool[REDBLK_NIL]) return NULL; #ifndef REDBLK_UNSAFE @@ -582,7 +588,7 @@ REDBLK_T const * REDBLK_(minimum_const)(REDBLK_T const * pool, REDBLK_T const * /* Return the node in a tree that has the largest key (rightmost). */ -REDBLK_T * REDBLK_(maximum)(REDBLK_T * pool, REDBLK_T * node) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(maximum)(REDBLK_T * pool, REDBLK_T * node) { if (!node || node == &pool[REDBLK_NIL]) return NULL; #ifndef REDBLK_UNSAFE @@ -593,7 +599,7 @@ REDBLK_T * REDBLK_(maximum)(REDBLK_T * pool, REDBLK_T * node) { } return node; } -REDBLK_T const * REDBLK_(maximum_const)(REDBLK_T const * pool, REDBLK_T const * node) { +REDBLK_IMPL_STATIC REDBLK_T const * REDBLK_(maximum_const)(REDBLK_T const * pool, REDBLK_T const * node) { if (!node || node == &pool[REDBLK_NIL]) return NULL; #ifndef REDBLK_UNSAFE @@ -608,7 +614,7 @@ REDBLK_T const * REDBLK_(maximum_const)(REDBLK_T const * pool, REDBLK_T const * /* Return the next node which is larger than the given node. */ -REDBLK_T * REDBLK_(successor)(REDBLK_T * pool, REDBLK_T * x) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(successor)(REDBLK_T * pool, REDBLK_T * x) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, x); #endif @@ -631,7 +637,7 @@ REDBLK_T * REDBLK_(successor)(REDBLK_T * pool, REDBLK_T * x) { x = y; } } -REDBLK_T const * REDBLK_(successor_const)(REDBLK_T const * pool, REDBLK_T const * x) { +REDBLK_IMPL_STATIC REDBLK_T const * REDBLK_(successor_const)(REDBLK_T const * pool, REDBLK_T const * x) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element_const)(pool, x); #endif @@ -658,13 +664,13 @@ REDBLK_T const * REDBLK_(successor_const)(REDBLK_T const * pool, REDBLK_T const /* Return the previous node which is smaller than the given node. */ -REDBLK_T * REDBLK_(predecessor)(REDBLK_T * pool, REDBLK_T * x) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(predecessor)(REDBLK_T * pool, REDBLK_T * x) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, x); #endif // if the left subtree is not null, - // the predecessor is the rightmost node in the + // the predecessor is the rightmost node in the // left subtree if (x->REDBLK_LEFT != REDBLK_NIL) { return REDBLK_(maximum)(pool, &pool[x->REDBLK_LEFT]); @@ -681,13 +687,13 @@ REDBLK_T * REDBLK_(predecessor)(REDBLK_T * pool, REDBLK_T * x) { x = y; } } -REDBLK_T const * REDBLK_(predecessor_const)(REDBLK_T const * pool, REDBLK_T const * x) { +REDBLK_IMPL_STATIC REDBLK_T const * REDBLK_(predecessor_const)(REDBLK_T const * pool, REDBLK_T const * x) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element_const)(pool, x); #endif // if the left subtree is not null, - // the predecessor is the rightmost node in the + // the predecessor is the rightmost node in the // left subtree if (x->REDBLK_LEFT != REDBLK_NIL) { return REDBLK_(maximum_const)(pool, &pool[x->REDBLK_LEFT]); @@ -799,7 +805,7 @@ static void REDBLK_(insertFixup)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * x gp->REDBLK_COLOR = REDBLK_RED; REDBLK_(rotateRight)(pool, root, gp); } - + } else { /* mirror image of above code */ REDBLK_T * y = &pool[gp->REDBLK_LEFT]; @@ -833,7 +839,7 @@ static void REDBLK_(insertFixup)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * x Insert a node into a tree. Typically, the node must be allocated from a pool first. */ -REDBLK_T * REDBLK_(insert)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * x) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(insert)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * x) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, *root); REDBLK_(validate_element)(pool, x); @@ -907,7 +913,7 @@ static void REDBLK_(deleteFixup)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * x REDBLK_(rotateLeft)(pool, root, p); x = *root; } - + } else { REDBLK_T * w = &pool[p->REDBLK_LEFT]; if (w->REDBLK_COLOR == REDBLK_RED) { @@ -937,7 +943,7 @@ static void REDBLK_(deleteFixup)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * x } } } - + x->REDBLK_COLOR = REDBLK_BLACK; } @@ -946,7 +952,7 @@ static void REDBLK_(deleteFixup)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * x usually the result of a find operation. The node is typically released to the pool afterwards. */ -REDBLK_T * REDBLK_(remove)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * z) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(remove)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * z) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, *root); REDBLK_(validate_element)(pool, z); @@ -1015,7 +1021,7 @@ REDBLK_T * REDBLK_(remove)(REDBLK_T * pool, REDBLK_T ** root, REDBLK_T * z) { temporary instance of the node type rather than a properly allocated node. */ -REDBLK_T * REDBLK_(find)(REDBLK_T * pool, REDBLK_T * root, REDBLK_T * key) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(find)(REDBLK_T * pool, REDBLK_T * root, REDBLK_T * key) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, root); #endif @@ -1039,7 +1045,7 @@ REDBLK_T * REDBLK_(find)(REDBLK_T * pool, REDBLK_T * root, REDBLK_T * key) { special case, the key can be a temporary instance of the node type rather than a properly allocated node. */ -REDBLK_T * REDBLK_(nearby)(REDBLK_T * pool, REDBLK_T * root, REDBLK_T * key) { +REDBLK_IMPL_STATIC REDBLK_T * REDBLK_(nearby)(REDBLK_T * pool, REDBLK_T * root, REDBLK_T * key) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, root); #endif @@ -1061,7 +1067,7 @@ REDBLK_T * REDBLK_(nearby)(REDBLK_T * pool, REDBLK_T * root, REDBLK_T * key) { /* Count the number of nodes in a tree. */ -ulong REDBLK_(size)(REDBLK_T * pool, REDBLK_T * root) { +REDBLK_IMPL_STATIC ulong REDBLK_(size)(REDBLK_T * pool, REDBLK_T * root) { #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, root); #endif @@ -1075,7 +1081,7 @@ ulong REDBLK_(size)(REDBLK_T * pool, REDBLK_T * root) { /* Recursive implementation of the verify function */ -int REDBLK_(verify_private)(REDBLK_T * pool, REDBLK_T * node, REDBLK_T * parent, ulong curblkcnt, ulong correctblkcnt) { +static int REDBLK_(verify_private)(REDBLK_T * pool, REDBLK_T * node, REDBLK_T * parent, ulong curblkcnt, ulong correctblkcnt) { # define REDBLK_TEST(c) do { \ if( FD_UNLIKELY( !(c) ) ) { FD_LOG_WARNING(( "FAIL: %s", #c )); return -1; } \ } while(0) @@ -1088,7 +1094,7 @@ int REDBLK_(verify_private)(REDBLK_T * pool, REDBLK_T * node, REDBLK_T * parent, #ifndef REDBLK_UNSAFE REDBLK_(validate_element)(pool, node); #endif - + REDBLK_TEST(&pool[node->REDBLK_PARENT] == parent); if (node->REDBLK_COLOR == REDBLK_BLACK) @@ -1097,7 +1103,7 @@ int REDBLK_(verify_private)(REDBLK_T * pool, REDBLK_T * node, REDBLK_T * parent, REDBLK_TEST(node->REDBLK_COLOR == REDBLK_RED); REDBLK_TEST(parent->REDBLK_COLOR == REDBLK_BLACK); } - + if (node->REDBLK_LEFT != REDBLK_NIL) REDBLK_TEST(REDBLK_(compare)(&pool[node->REDBLK_LEFT], node) <= 0); if (node->REDBLK_RIGHT != REDBLK_NIL) @@ -1113,7 +1119,7 @@ int REDBLK_(verify_private)(REDBLK_T * pool, REDBLK_T * node, REDBLK_T * parent, debugging memory corruption. A non-zero result is returned if an error is detected. */ -int REDBLK_(verify)(REDBLK_T * pool, REDBLK_T * root) { +REDBLK_IMPL_STATIC int REDBLK_(verify)(REDBLK_T * pool, REDBLK_T * root) { REDBLK_TEST(pool[REDBLK_NIL].REDBLK_LEFT == REDBLK_NIL && pool[REDBLK_NIL].REDBLK_RIGHT == REDBLK_NIL && pool[REDBLK_NIL].REDBLK_COLOR == REDBLK_BLACK); @@ -1151,6 +1157,8 @@ int REDBLK_(verify)(REDBLK_T * pool, REDBLK_T * root) { #endif /* REDBLK_IMPL_STYLE==0 || REDBLK_IMPL_STYLE==2 */ +#undef REDBLK_IMPL_STATIC #undef REDBLK_ #undef REDBLK_T #undef REDBLK_IMPL_STYLE +#undef REDBLK_NAME diff --git a/src/util/tmpl/test_redblack.c b/src/util/tmpl/test_redblack.c index c6aa40ae2d..acb1e0099e 100644 --- a/src/util/tmpl/test_redblack.c +++ b/src/util/tmpl/test_redblack.c @@ -13,12 +13,13 @@ struct my_rb_node { typedef struct my_rb_node my_rb_node_t; #define REDBLK_T my_rb_node_t #define REDBLK_NAME my_rb -#include "fd_redblack.c" -long my_rb_compare(my_rb_node_t* left, my_rb_node_t* right) { +static long my_rb_compare(my_rb_node_t* left, my_rb_node_t* right) { return (long)(left->key - right->key); } +#include "fd_redblack.c" + #define SCRATCH_ALIGN (128UL) #define SCRATCH_FOOTPRINT (1UL<<16) uchar scratch[ SCRATCH_FOOTPRINT ] __attribute__((aligned(SCRATCH_ALIGN))); @@ -78,7 +79,7 @@ main( int argc, my_rb_release_tree(pool, root); } - + ulong* list = (ulong*)malloc(max * sizeof(ulong)); for (ulong iter = 0; iter < 1000; ++iter) { @@ -106,7 +107,7 @@ main( int argc, FD_LOG_ERR(("did not get NULL as expected")); assert(!my_rb_verify(pool, root)); - + node = my_rb_minimum(pool, root); if (node->key != 1 || node->val != node->key*17UL) FD_LOG_ERR(("did not get right value")); @@ -115,7 +116,7 @@ main( int argc, if (node->key != ++j || node->val != node->key*17UL) FD_LOG_ERR(("did not get right value")); } - + node = my_rb_maximum(pool, root); if (node->key != max || node->val != node->key*17UL) FD_LOG_ERR(("did not get right value")); @@ -124,7 +125,7 @@ main( int argc, if (node->key != --j || node->val != node->key*17UL) FD_LOG_ERR(("did not get right value")); } - + for (ulong i = 0; i <= max+1; ++i) { my_rb_node_t key; key.key = i; @@ -161,12 +162,12 @@ main( int argc, } if (root != NULL) FD_LOG_ERR(("final root wrong")); - + assert(!my_rb_verify(pool, root)); } free(list); - + // Try 3 interesting cases for (ulong c = 0; c < 3; ++c) { my_rb_node_t* root = NULL; @@ -218,9 +219,9 @@ main( int argc, my_rb_release_tree(pool, root); } - + (void) my_rb_delete( my_rb_leave( pool )); - + fd_rng_delete( fd_rng_leave( rng ) ); FD_LOG_NOTICE(( "pass" )); diff --git a/src/util/tmpl/test_redblack2.c b/src/util/tmpl/test_redblack2.c index d67cbfffcb..d14e3aba49 100644 --- a/src/util/tmpl/test_redblack2.c +++ b/src/util/tmpl/test_redblack2.c @@ -34,16 +34,17 @@ typedef struct rbnode_struct rbnode; #define REDBLK_RIGHT u.rb.right #define REDBLK_COLOR u.rb.color #define REDBLK_NEXTFREE u.nf + +long rb_compare(rbnode* left, rbnode* right) { + return (long)(left->key - right->key); +} + #include "fd_redblack.c" typedef rbnode rbtree; static rbnode* pool = NULL; -long rb_compare(rbnode* left, rbnode* right) { - return (long)(left->key - right->key); -} - static rbtree *tree_create( void ); static void tree_destroy(rbtree *rbt); static rbnode *tree_find(rbtree *rbt, int key);