@@ -910,6 +910,157 @@ bk_bool multimap_remove_all(multimap me, void *const key)
910910 return BK_TRUE ;
911911}
912912
913+ /**
914+ * Returns the first (lowest) key in this multi-map. The returned key is a
915+ * pointer to the internally stored key, which should not be modified. Modifying
916+ * it results in undefined behaviour.
917+ *
918+ * @param me the multi-map to get the key from
919+ *
920+ * @return the lowest key in this multi-map, or NULL if it is empty
921+ */
922+ void * multimap_first (multimap me )
923+ {
924+ char * traverse = me -> root ;
925+ char * traverse_left ;
926+ if (!traverse ) {
927+ return NULL ;
928+ }
929+ memcpy (& traverse_left , traverse + node_left_child_offset , ptr_size );
930+ while (traverse_left ) {
931+ traverse = traverse_left ;
932+ memcpy (& traverse_left , traverse + node_left_child_offset , ptr_size );
933+ }
934+ return traverse + node_key_offset ;
935+ }
936+
937+ /**
938+ * Returns the last (highest) key in this multi-map. The returned key is a
939+ * pointer to the internally stored key, which should not be modified. Modifying
940+ * it results in undefined behaviour.
941+ *
942+ * @param me the multi-map to get the key from
943+ *
944+ * @return the highest key in this multi-map, or NULL if it is empty
945+ */
946+ void * multimap_last (multimap me )
947+ {
948+ char * traverse = me -> root ;
949+ char * traverse_right ;
950+ if (!traverse ) {
951+ return NULL ;
952+ }
953+ memcpy (& traverse_right , traverse + node_right_child_offset , ptr_size );
954+ while (traverse_right ) {
955+ traverse = traverse_right ;
956+ memcpy (& traverse_right , traverse + node_right_child_offset , ptr_size );
957+ }
958+ return traverse + node_key_offset ;
959+ }
960+
961+ /**
962+ * Returns the key which is strictly lower than the comparison key. Meaning that
963+ * the highest key which is lower than the key used for comparison is returned.
964+ *
965+ * @param me the multi-map to get the lower key from
966+ * @param key the key to use for comparison
967+ *
968+ * @return the key which is strictly lower, or NULL if it does not exist
969+ */
970+ void * multimap_lower (multimap me , void * const key )
971+ {
972+ char * ret = NULL ;
973+ char * traverse = me -> root ;
974+ while (traverse ) {
975+ const int compare = me -> key_comparator (traverse + node_key_offset , key );
976+ if (compare < 0 ) {
977+ ret = traverse + node_key_offset ;
978+ memcpy (& traverse , traverse + node_right_child_offset , ptr_size );
979+ } else {
980+ memcpy (& traverse , traverse + node_left_child_offset , ptr_size );
981+ }
982+ }
983+ return ret ;
984+ }
985+
986+ /**
987+ * Returns the key which is strictly higher than the comparison key. Meaning
988+ * that the lowest key which is higher than the key used for comparison is
989+ * returned.
990+ *
991+ * @param me the multi-map to get the higher key from
992+ * @param key the key to use for comparison
993+ *
994+ * @return the key which is strictly higher, or NULL if it does not exist
995+ */
996+ void * multimap_higher (multimap me , void * const key )
997+ {
998+ char * ret = NULL ;
999+ char * traverse = me -> root ;
1000+ while (traverse ) {
1001+ const int compare = me -> key_comparator (traverse + node_key_offset , key );
1002+ if (compare > 0 ) {
1003+ ret = traverse + node_key_offset ;
1004+ memcpy (& traverse , traverse + node_left_child_offset , ptr_size );
1005+ } else {
1006+ memcpy (& traverse , traverse + node_right_child_offset , ptr_size );
1007+ }
1008+ }
1009+ return ret ;
1010+ }
1011+
1012+ /**
1013+ * Returns the key which is the floor of the comparison key. Meaning that the
1014+ * the highest key which is lower or equal to the key used for comparison is
1015+ * returned.
1016+ *
1017+ * @param me the multi-map to get the floor key from
1018+ * @param key the key to use for comparison
1019+ *
1020+ * @return the key which is the floor, or NULL if it does not exist
1021+ */
1022+ void * multimap_floor (multimap me , void * const key )
1023+ {
1024+ char * ret = NULL ;
1025+ char * traverse = me -> root ;
1026+ while (traverse ) {
1027+ const int compare = me -> key_comparator (traverse + node_key_offset , key );
1028+ if (compare <= 0 ) {
1029+ ret = traverse + node_key_offset ;
1030+ memcpy (& traverse , traverse + node_right_child_offset , ptr_size );
1031+ } else {
1032+ memcpy (& traverse , traverse + node_left_child_offset , ptr_size );
1033+ }
1034+ }
1035+ return ret ;
1036+ }
1037+
1038+ /**
1039+ * Returns the key which is the ceiling of the comparison key. Meaning that the
1040+ * the lowest key which is higher or equal to the key used for comparison is
1041+ * returned.
1042+ *
1043+ * @param me the multi-map to get the ceiling key from
1044+ * @param key the key to use for comparison
1045+ *
1046+ * @return the key which is the ceiling, or NULL if it does not exist
1047+ */
1048+ void * multimap_ceiling (multimap me , void * const key )
1049+ {
1050+ char * ret = NULL ;
1051+ char * traverse = me -> root ;
1052+ while (traverse ) {
1053+ const int compare = me -> key_comparator (traverse + node_key_offset , key );
1054+ if (compare >= 0 ) {
1055+ ret = traverse + node_key_offset ;
1056+ memcpy (& traverse , traverse + node_left_child_offset , ptr_size );
1057+ } else {
1058+ memcpy (& traverse , traverse + node_right_child_offset , ptr_size );
1059+ }
1060+ }
1061+ return ret ;
1062+ }
1063+
9131064/**
9141065 * Clears the key-value pairs from the multi-map.
9151066 *
0 commit comments