]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
table: Add O(1) lookups for bitfield flag to string identifiers
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 17 Apr 2020 17:19:00 +0000 (12:19 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 17 Apr 2020 17:20:32 +0000 (12:20 -0500)
src/lib/util/table.c
src/lib/util/table.h

index 56d3c734872da662062ac1049ddde403f9e5ce11..0ddb1acf56cf779fdd6400b99c2fc7668e38c7bd 100644 (file)
@@ -24,6 +24,7 @@
 RCSID("$Id$")
 
 #include <freeradius-devel/util/table.h>
+#include <freeradius-devel/util/misc.h>
 
 #include <string.h>
 #include <stdio.h>
@@ -94,12 +95,17 @@ _our_return_type _our_name(size_t *match_len, _our_table_type table, size_t tabl
 char const *_our_name(_our_table_type table, size_t table_len, _our_value_type value, char const *def) \
 { \
        size_t          i; \
-       for (i = 0; i < table_len; i++) { \
-               if (table[i].value == value) return table[i].name; \
-       } \
+       for (i = 0; i < table_len; i++) if (table[i].value == value) return table[i].name; \
        return def; \
 }
 
+#define TABLE_TYPE_VALUE_INDEX_BIT_FIELD_FUNC(_our_table_type, _our_name, _our_value_type) \
+char const *_our_name(_our_table_type table, size_t table_len, _our_value_type value, char const *def) \
+{ \
+       uint8_t idx = fr_high_bit_pos_uint64(value); \
+       if (idx >= table_len) return def; \
+       return table[idx].name; \
+}
 
 /** Convert a string to a value using a lexicographically sorted table
  *
@@ -430,3 +436,11 @@ TABLE_TYPE_VALUE_FUNC(fr_table_num_sorted_t const *, fr_table_sorted_str_by_num,
 TABLE_TYPE_VALUE_FUNC(fr_table_num_ordered_t const *, fr_table_ordered_str_by_num, int)
 TABLE_TYPE_VALUE_FUNC(fr_table_ptr_sorted_t const *, fr_table_sorted_str_by_ptr, void const *)
 TABLE_TYPE_VALUE_FUNC(fr_table_ptr_ordered_t const *, fr_table_ordered_str_by_ptr, void const *)
+
+/*
+ *     Indexed value to string conversion functions
+ *     These are O(1) for bitfields, and are
+ *     particularly useful for looking up string
+ *     definitions for flag values.
+ */
+TABLE_TYPE_VALUE_INDEX_BIT_FIELD_FUNC(fr_table_num_indexed_bit_pos_t const *, fr_table_indexed_str_by_bit_field, uint64_t);
index 2c7edc47fc217e290d526c9a3f688861f745b7b8..b4d414c7137743c7b641d2dae95d8a40b594a72c 100644 (file)
@@ -34,13 +34,6 @@ extern "C" {
 #include <stdint.h>
 #include <sys/types.h>
 
-/** An element in a table
- *
- */
-typedef struct {
-       char const              *name;
-} fr_table_t;
-
 /** An element in a lexicographically sorted array of name to num mappings
  *
  */
@@ -73,6 +66,16 @@ typedef struct {
        void const              *value;
 } fr_table_ptr_ordered_t;
 
+/** An element in a table indexed by bit position
+ *
+ * i.e. if only the first bit is set in a bitfield, the entry at index 0
+ * will be returned.
+ */
+typedef struct {
+       char const              *name;
+       uint64_t                value;
+} fr_table_num_indexed_bit_pos_t;
+
 /** Macro to use as dflt
  *
  */
@@ -102,14 +105,16 @@ void              *fr_table_ordered_ptr_by_str(fr_table_ptr_ordered_t const *table, size_t t
  */
 #define fr_table_value_by_str(_table, _name, _def) \
 _Generic((_table), \
-        fr_table_num_sorted_t const *          :       fr_table_sorted_num_by_str,     \
-        fr_table_num_ordered_t const *         :       fr_table_ordered_num_by_str,    \
-        fr_table_num_sorted_t *                :       fr_table_sorted_num_by_str,     \
-        fr_table_num_ordered_t *               :       fr_table_ordered_num_by_str,    \
-        fr_table_ptr_sorted_t const *          :       fr_table_sorted_ptr_by_str,     \
-        fr_table_ptr_ordered_t const *         :       fr_table_ordered_ptr_by_str,    \
-        fr_table_ptr_sorted_t *                :       fr_table_sorted_ptr_by_str,     \
-        fr_table_ptr_ordered_t *               :       fr_table_ordered_ptr_by_str     \
+        fr_table_num_sorted_t const *          : fr_table_sorted_num_by_str,                   \
+        fr_table_num_ordered_t const *         : fr_table_ordered_num_by_str,                  \
+        fr_table_num_sorted_t *                : fr_table_sorted_num_by_str,                   \
+        fr_table_num_ordered_t *               : fr_table_ordered_num_by_str,                  \
+        fr_table_ptr_sorted_t const *          : fr_table_sorted_ptr_by_str,                   \
+        fr_table_ptr_ordered_t const *         : fr_table_ordered_ptr_by_str,                  \
+        fr_table_ptr_sorted_t *                : fr_table_sorted_ptr_by_str,                   \
+        fr_table_ptr_ordered_t *               : fr_table_ordered_ptr_by_str,                  \
+        fr_table_num_indexed_bit_pos_t *       : fr_table_ordered_num_by_str,                  \
+        fr_table_num_indexed_bit_pos_t const * : fr_table_ordered_num_by_str                   \
 )(_table, _table ## _len, _name, _def)
 
 int            fr_table_sorted_num_by_substr(fr_table_num_sorted_t const *table, size_t table_len,
@@ -138,14 +143,16 @@ void              *fr_table_ordered_ptr_by_substr(fr_table_ptr_ordered_t const *table, size_
  */
 #define fr_table_value_by_substr(_table, _name, _name_len, _def) \
 _Generic((_table), \
-        fr_table_num_sorted_t const *          :       fr_table_sorted_num_by_substr,  \
-        fr_table_num_ordered_t const *         :       fr_table_ordered_num_by_substr, \
-        fr_table_num_sorted_t *                :       fr_table_sorted_num_by_substr,  \
-        fr_table_num_ordered_t *               :       fr_table_ordered_num_by_substr, \
-        fr_table_ptr_sorted_t const *          :       fr_table_sorted_ptr_by_substr,  \
-        fr_table_ptr_ordered_t const *         :       fr_table_ordered_ptr_by_substr, \
-        fr_table_ptr_sorted_t *                :       fr_table_sorted_ptr_by_substr,  \
-        fr_table_ptr_ordered_t *               :       fr_table_ordered_ptr_by_substr  \
+        fr_table_num_sorted_t const *          : fr_table_sorted_num_by_substr,                \
+        fr_table_num_ordered_t const *         : fr_table_ordered_num_by_substr,               \
+        fr_table_num_sorted_t *                : fr_table_sorted_num_by_substr,                \
+        fr_table_num_ordered_t *               : fr_table_ordered_num_by_substr,               \
+        fr_table_ptr_sorted_t const *          : fr_table_sorted_ptr_by_substr,                \
+        fr_table_ptr_ordered_t const *         : fr_table_ordered_ptr_by_substr,               \
+        fr_table_ptr_sorted_t *                : fr_table_sorted_ptr_by_substr,                \
+        fr_table_ptr_ordered_t *               : fr_table_ordered_ptr_by_substr,               \
+        fr_table_num_indexed_bit_pos_t *       : fr_table_ordered_num_by_substr,               \
+        fr_table_num_indexed_bit_pos_t const * : fr_table_ordered_num_by_substr                \
 )(_table, _table ## _len, _name, _name_len, _def)
 
 int    fr_table_sorted_num_by_longest_prefix(size_t *match_len, fr_table_num_sorted_t const *table, size_t table_len,
@@ -173,14 +180,16 @@ void      *fr_table_ordered_ptr_by_longest_prefix(size_t *match_len, fr_table_ptr_ord
  */
 #define fr_table_value_by_longest_prefix(_match_len, _table, _name, _name_len, _def) \
 _Generic((_table), \
-        fr_table_num_sorted_t const *          :       fr_table_sorted_num_by_longest_prefix,  \
-        fr_table_num_ordered_t const *         :       fr_table_ordered_num_by_longest_prefix, \
-        fr_table_num_sorted_t *                :       fr_table_sorted_num_by_longest_prefix,  \
-        fr_table_num_ordered_t *               :       fr_table_ordered_num_by_longest_prefix, \
-        fr_table_ptr_sorted_t const *          :       fr_table_sorted_ptr_by_longest_prefix,  \
-        fr_table_ptr_ordered_t const *         :       fr_table_ordered_ptr_by_longest_prefix, \
-        fr_table_ptr_sorted_t *                :       fr_table_sorted_ptr_by_longest_prefix,  \
-        fr_table_ptr_ordered_t *               :       fr_table_ordered_ptr_by_longest_prefix  \
+        fr_table_num_sorted_t const *          : fr_table_sorted_num_by_longest_prefix,        \
+        fr_table_num_ordered_t const *         : fr_table_ordered_num_by_longest_prefix,       \
+        fr_table_num_sorted_t *                : fr_table_sorted_num_by_longest_prefix,        \
+        fr_table_num_ordered_t *               : fr_table_ordered_num_by_longest_prefix,       \
+        fr_table_ptr_sorted_t const *          : fr_table_sorted_ptr_by_longest_prefix,        \
+        fr_table_ptr_ordered_t const *         : fr_table_ordered_ptr_by_longest_prefix,       \
+        fr_table_ptr_sorted_t *                : fr_table_sorted_ptr_by_longest_prefix,        \
+        fr_table_ptr_ordered_t *               : fr_table_ordered_ptr_by_longest_prefix,       \
+        fr_table_num_indexed_bit_pos_t *       : fr_table_ordered_num_by_longest_prefix,       \
+        fr_table_num_indexed_bit_pos_t const * : fr_table_ordered_num_by_longest_prefix        \
 )(_match_len, _table, _table ## _len, _name, _name_len, _def)
 
 char const     *fr_table_ordered_str_by_num(fr_table_num_ordered_t const *table, size_t table_len,
@@ -192,6 +201,9 @@ char const  *fr_table_ordered_str_by_ptr(fr_table_ptr_ordered_t const *table, siz
 char const     *fr_table_sorted_str_by_ptr(fr_table_ptr_sorted_t const *table, size_t table_len,
                                            void const *ptr, char const *def);
 
+char const     *fr_table_indexed_str_by_bit_field(fr_table_num_indexed_bit_pos_t const *table, size_t table_len,
+                                                  uint64_t number, char const *def);
+
 /** Convert an integer to a string
  *
  * @param[in] _table           to search in.
@@ -203,14 +215,16 @@ char const        *fr_table_sorted_str_by_ptr(fr_table_ptr_sorted_t const *table, size_
  */
 #define fr_table_str_by_value(_table, _number, _def) \
 _Generic((_table), \
-        fr_table_num_sorted_t const *          :       fr_table_sorted_str_by_num,     \
-        fr_table_num_ordered_t const *         :       fr_table_ordered_str_by_num,    \
-        fr_table_num_sorted_t *                :       fr_table_sorted_str_by_num,     \
-        fr_table_num_ordered_t *               :       fr_table_ordered_str_by_num,    \
-        fr_table_ptr_sorted_t const *          :       fr_table_sorted_str_by_ptr,     \
-        fr_table_ptr_ordered_t const *         :       fr_table_ordered_str_by_ptr,    \
-        fr_table_ptr_sorted_t *                :       fr_table_sorted_str_by_ptr,     \
-        fr_table_ptr_ordered_t *               :       fr_table_ordered_str_by_ptr     \
+        fr_table_num_sorted_t const *          : fr_table_sorted_str_by_num,                   \
+        fr_table_num_ordered_t const *         : fr_table_ordered_str_by_num,                  \
+        fr_table_num_sorted_t *                : fr_table_sorted_str_by_num,                   \
+        fr_table_num_ordered_t *               : fr_table_ordered_str_by_num,                  \
+        fr_table_ptr_sorted_t const *          : fr_table_sorted_str_by_ptr,                   \
+        fr_table_ptr_ordered_t const *         : fr_table_ordered_str_by_ptr,                  \
+        fr_table_ptr_sorted_t *                : fr_table_sorted_str_by_ptr,                   \
+        fr_table_ptr_ordered_t *               : fr_table_ordered_str_by_ptr,                  \
+        fr_table_num_indexed_bit_pos_t *       : fr_table_indexed_str_by_bit_field,            \
+        fr_table_num_indexed_bit_pos_t const * : fr_table_indexed_str_by_bit_field             \
 )(_table, _table ## _len, _number, _def)
 
 #ifdef __cplusplus