]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Efficient table lookups, phase 2
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 14 Aug 2019 21:28:44 +0000 (17:28 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 14 Aug 2019 22:02:01 +0000 (18:02 -0400)
src/lib/eap/tls.h
src/lib/server/tmpl.h
src/lib/server/xlat_func.c
src/lib/unlang/interpret.c
src/lib/util/dict.c
src/lib/util/log.h
src/lib/util/table.c
src/lib/util/table.h
src/lib/util/token.c
src/lib/util/token.h
src/lib/util/value.h

index d671e6f0b3afe04abdd8f5c8a31792f43a597646..6e26b68229c65e5206dc3099c9eae9df99932fde 100644 (file)
@@ -148,7 +148,7 @@ typedef struct {
        size_t                  record_in_recvd_len;    //!< How much of the record we've received so far.
 } eap_tls_session_t;
 
-extern fr_table_t const eap_tls_status_table[];
+extern fr_table_ordered_t const eap_tls_status_table[];
 extern size_t eap_tls_status_table_len;
 
 /*
index 4d62c272a12e7acf6c4d4c558058ff2377609cf9..b25b98c768c723c33bfbd9cf1d7b2985fd80540d 100644 (file)
@@ -94,7 +94,7 @@ typedef enum pair_list_e {
        PAIR_LIST_UNKNOWN               //!< Unknown list.
 } pair_list_t;
 
-extern fr_table_t const pair_list_table[];
+extern fr_table_ordered_t const pair_list_table[];
 extern size_t pair_list_table_len;
 
 typedef enum requests_ref_e {
index 0332eabf1d40d54e75f10828c3d62e8b98a9fc25..bfefa1c6aa0ae13b34d9de7410fcb578dfb1a057 100644 (file)
@@ -465,8 +465,8 @@ static ssize_t xlat_func_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED char **out, U
        for (vp = tmpl_cursor_init(NULL, &cursor, request, vpt);
             vp;
             vp = fr_cursor_next(&cursor)) {
-               fr_dict_vendor_t const  *vendor;
-               fr_table_t const        *type;
+               fr_dict_vendor_t const          *vendor;
+               fr_table_ordered_t const        *type;
 
                if (vp->da->flags.has_tag) {
                        RIDEBUG2("&%s:%s:%i %s %pV",
index 6af5b50af86d10bc0c2fc655493a4019b3de7512..0e89fae5cdce99b412c4718c4963051d127bdd79 100644 (file)
@@ -33,7 +33,7 @@ RCSID("$Id$")
 #include "parallel_priv.h"
 #include "module_priv.h"
 
-static fr_table_t unlang_action_table[] = {
+static fr_table_t const unlang_action_table[] = {
        { "break",              UNLANG_ACTION_BREAK },
        { "calculate-result",   UNLANG_ACTION_CALCULATE_RESULT },
        { "next",               UNLANG_ACTION_EXECUTE_NEXT },
index 6d764f0ab05a17274f37d17c112cbdae27d2c33c..0fddcabe138e014134639919b2b8f653cbf1c905 100644 (file)
@@ -5615,8 +5615,8 @@ int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir)
         *      that function does too many checks.
         */
        for (i = 0; i < fr_value_box_type_table_len; i++) {
-               fr_dict_attr_t          *n;
-               fr_table_t const        *p = &fr_value_box_type_table[i];
+               fr_dict_attr_t                  *n;
+               fr_table_ordered_t const        *p = &fr_value_box_type_table[i];
 
                type_name = talloc_typed_asprintf(NULL, "Tmp-Cast-%s", p->name);
 
index 6f88204b51ddd17d061a183cc4c9214ca3207089..7309e18ec208f0d2b346952a202776c7e79e6c8b 100644 (file)
@@ -46,7 +46,7 @@ void          fr_canonicalize_error(TALLOC_CTX *ctx, char **spaces, char **text, ssize_t
 extern int     fr_debug_lvl;   /* 0 = no debugging information */
 extern bool    log_dates_utc;
 
-extern fr_table_t const fr_log_levels[];
+extern fr_table_ordered_t const fr_log_levels[];
 extern size_t fr_log_levels_len;
 
 typedef enum {
index 5d4eb2275476ae74c753d96dea4d1c96fb40ea5b..59aa951c85566853a4da977bcfd9d4c8b18057cd 100644 (file)
@@ -27,31 +27,108 @@ RCSID("$Id$")
 
 #include <string.h>
 
-/** Convert a string to an integer
+
+/** Convert a string to an integer using a lexicographically sorted table
+ *
+ * @param[in] table            to search in.
+ * @param[in] table_len                The number of elements in the table.
+ * @param[in] name             to resolve to a number.
+ * @param[in] def              Default value if no entry matched.
+ * @return
+ *     - num value of matching entry.
+ *      - def if no matching entries.
+ */
+int fr_table_sorted_num_by_str(fr_table_t const *table, size_t table_len,
+                              char const *name, int def)
+{
+       ssize_t start = 0;
+       ssize_t end = table_len - 1;
+       ssize_t mid;
+
+       int     ret;
+
+       if (!name) return def;
+
+       while (start <= end) {
+               mid = start + ((end - start) / 2);      /* Avoid overflow */
+
+               ret = strcasecmp(name, table[mid].name);
+               if (ret == 0) return table[mid].number;
+
+               if (ret < 0) {
+                       end = mid - 1;
+               } else {
+                       start = mid + 1;
+               }
+       }
+
+       return def;
+}
+
+/** Convert a string to an integer using an arbitrarily ordered table
+ *
+ * @param[in] table            to search in.
+ * @param[in] table_len                The number of elements in the table.
+ * @param[in] name             to resolve to a number.
+ * @param[in] def              Default value if no entry matched.
+ * @return
+ *     - num value of matching entry.
+ *      - def if no matching entries.
+ */
+int fr_table_ordered_num_by_str(fr_table_ordered_t const *table, size_t table_len,
+                               char const *name, int def)
+{
+       size_t          i;
+
+       if (!name) return def;
+
+       for (i = 0; i < table_len; i++) if (strcasecmp(name, table[i].name) == 0) return table[i].number;
+
+       return def;
+}
+
+/** Convert a string matching part of name to an integer using a lexicographically sorted table
  *
  * @param[in] table            to search in.
  * @param[in] table_len                The number of elements in the table.
  * @param[in] name             to locate.
+ * @param[in] name_len         the maximum amount of name that should be matched.
  * @param[in] def              Value to return if there are no matches.
  * @return
  *     - num value of matching entry.
  *      - def if no matching entries.
  */
-int _fr_table_num_by_str(fr_table_t const *table, size_t table_len,
-                        char const *name, int def)
+int fr_table_sorted_num_by_substr(fr_table_t const *table, size_t table_len,
+                                 char const *name, size_t name_len, int def)
 {
-       size_t          i;
+       ssize_t start = 0;
+       ssize_t end = table_len - 1;
+       ssize_t mid;
+
+       int     ret;
 
        if (!name) return def;
 
-       for (i = 0; i < table_len; i++) {
-               if (strcasecmp(table[i].name, name) == 0) return table[i].number;
+       while (start <= end) {
+               mid = start + ((end - start) / 2);      /* Avoid overflow */
+
+               /*
+                *      Match up to the length of the table entry if len is < 0.
+                */
+               ret = strncasecmp(name, table[mid].name, (name_len < 0) ?  strlen(table[mid].name) : name_len);
+               if (ret == 0) return table[mid].number;
+
+               if (ret < 0) {
+                       end = mid - 1;
+               } else {
+                       start = mid + 1;
+               }
        }
 
        return def;
 }
 
-/** Convert a string matching part of name to an integer
+/** Convert a string matching part of name to an integer using an arbitrarily ordered table
  *
  * @param[in] table            to search in.
  * @param[in] table_len                The number of elements in the table.
@@ -62,11 +139,10 @@ int _fr_table_num_by_str(fr_table_t const *table, size_t table_len,
  *     - num value of matching entry.
  *      - def if no matching entries.
  */
-int _fr_table_num_by_substr(fr_table_t const *table, size_t table_len,
-                           char const *name, ssize_t name_len, int def)
+int fr_table_ordered_num_by_substr(fr_table_ordered_t const *table, size_t table_len,
+                                  char const *name, ssize_t name_len, int def)
 {
        size_t          i;
-       size_t          max;
 
        if (!name) return def;
 
@@ -83,9 +159,7 @@ int _fr_table_num_by_substr(fr_table_t const *table, size_t table_len,
                /*
                 *      Match up to the length of the table entry if len is < 0.
                 */
-               max = (name_len < 0) ? tlen : (unsigned)name_len;
-
-               if (strncasecmp(table[i].name, name, max) == 0) return table[i].number;
+               if (strncasecmp(name, table[i].name, (name_len < 0) ? tlen : name_len) == 0) return table[i].number;
        }
 
        return def;
@@ -109,20 +183,22 @@ int _fr_table_num_by_substr(fr_table_t const *table, size_t table_len,
  *     - num value of matching entry.
  *      - def if no matching entries.
  */
-int _fr_table_lex_num_by_longest_prefix(fr_table_t const *table, size_t table_len,
+int _fr_table_sorted_num_by_longest_prefix(fr_table_t const *table, size_t table_len,
                                        char const *name, size_t name_len, int def)
 {
-       size_t  start = 0;
-       size_t  end = table_len - 1;
-       size_t  mid;
+       ssize_t start = 0;
+       ssize_t end = table_len - 1;
+       ssize_t mid;
 
        int     ret;
        int     num = def;
 
+       if (!name) return def;
+
        while (start <= end) {
                mid = start + ((end - start) / 2);      /* Avoid overflow */
 
-               ret = strncasecmp(table[mid].name, name, name_len);
+               ret = strncasecmp(name, table[mid].name, name_len);
                if (ret == 0) {
                        size_t tlen;
 
@@ -155,42 +231,6 @@ int _fr_table_lex_num_by_longest_prefix(fr_table_t const *table, size_t table_le
        return num;
 }
 
-/** Efficient string lookup in lexicographically sorted fr_table_t table
- *
- * @param[in] table            to search in.
- * @param[in] table_len                The number of elements in the table.
- * @param[in] name             to locate.
- * @param[in] name_len         the maximum amount of name that should be matched.
- * @param[in] def              Value to return if there are no matches.
- * @return
- *     - num value of matching entry.
- *      - def if no matching entries.
- */
-int _fr_table_lex_num_by_str(fr_table_t const *table, size_t table_len,
-                            char const *name, size_t name_len, int def)
-{
-       size_t  start = 0;
-       size_t  end = table_len - 1;
-       size_t  mid;
-
-       int     ret;
-
-       while (start <= end) {
-               mid = start + ((end - start) / 2);      /* Avoid overflow */
-
-               ret = strncasecmp(table[mid].name, name, name_len);
-               if (ret == 0) return table[mid].number;
-
-               if (ret < 0) {
-                       end = mid - 1;
-               } else {
-                       start = mid + 1;
-               }
-       }
-
-       return def;
-}
-
 /** Convert an integer to a string
  *
  * @param[in] table            to search in.
@@ -201,7 +241,7 @@ int _fr_table_lex_num_by_str(fr_table_t const *table, size_t table_len,
  *     - string value of matching entry.
  *      - def if no matching entries.
  */
-char const *_fr_table_str_by_num(fr_table_t const *table, size_t table_len,
+char const *_fr_table_str_by_num(fr_table_ordered_t const *table, size_t table_len,
                                 int number, char const *def)
 {
        size_t i;
index 732913934ede5a715b3a88a80a67997be3da4fab..d0fffc00d5463c636639c7a2a0f9043a3ea88ca0 100644 (file)
@@ -34,69 +34,100 @@ extern "C" {
 #include <stdint.h>
 #include <sys/types.h>
 
-struct fr_table_s {
+typedef struct {
        char const      *name;
        int32_t         number;
-};
+} fr_table_t;
 
-typedef struct fr_table_s fr_table_t;
-typedef struct fr_table_s fr_table_ordered_t;
+typedef struct {
+       char const      *name;
+       int32_t         number;
+} fr_table_ordered_t;
 
 /** Macro to use as dflt
  *
  */
 #define NAME_NUMBER_NOT_FOUND  INT32_MIN
 
-int            _fr_table_num_by_str(fr_table_t const *table, size_t table_len,
-                                    char const *name, int def);
-
-int            _fr_table_num_by_substr(fr_table_t const *table, size_t table_len,
-                                       char const *name, ssize_t name_len, int def);
-
-int            _fr_table_lex_num_by_longest_prefix(fr_table_t const *table, size_t table_len,
-                                                   char const *name, size_t name_len, int def);
-
-int            _fr_table_lex_num_by_str(fr_table_t const *table, size_t table_len,
-                                        char const *name, size_t name_len, int def);
 
-char const     *_fr_table_str_by_num(fr_table_t const *table, size_t table_len,
-                                     int number, char const *def);
+int            fr_table_sorted_num_by_str(fr_table_t const *table, size_t table_len,
+                                          char const *name, int def);
 
+int            fr_table_ordered_num_by_str(fr_table_ordered_t const *table, size_t table_len,
+                                           char const *name, int def);
 
-/** Convert a string to an integer
+/** Convert a string to an integer using a sorted or ordered table
  *
- * @copybrief _fr_table_num_by_str
+ * @param[in] _table   to search in.
+ * @param[in] _name    to resolve to a number.
+ * @param[in] _def     Default value if no entry matched.
+ * @return
+ *     - _def if name matched no entries in the table.
+ *     - the numeric value of the matching entry.
  */
-#define                fr_table_num_by_str(_table, _name, _def) \
-               _fr_table_num_by_str(_table, _table ## _len, _name, _def)
+#define fr_table_num_by_str(_table, _name, _def) \
+_Generic((_table), \
+        fr_table_t const *             :       fr_table_sorted_num_by_str,     \
+        fr_table_ordered_t const *     :       fr_table_ordered_num_by_str,    \
+        fr_table_t *                   :       fr_table_sorted_num_by_str,     \
+        fr_table_ordered_t *           :       fr_table_ordered_num_by_str     \
+)(_table, _table ## _len, _name, _def)
+
+int            fr_table_sorted_num_by_substr(fr_table_t const *table, size_t table_len,
+                                             char const *name, size_t name_len, int def);
 
-/** Convert a string matching part of name to an integer
+int            fr_table_ordered_num_by_substr(fr_table_ordered_t const *table, size_t table_len,
+                                              char const *name, ssize_t name_len, int def);
+
+/** Convert a partial string to an integer using an ordered or sorted table
  *
- * @copybrief _fr_table_num_by_substr
+ * @param[in] _table   to search in.
+ * @param[in] _name    to resolve to a number.
+ * @param[in] _name_len        The amount of name to match.
+ * @param[in] _def     Default value if no entry matched.
+ * @return
+ *     - _def if name matched no entries in the table.
+ *     - the numeric value of the matching entry.
  */
-#define                fr_table_num_by_substr(_table, _name, _name_len, _def) \
-               _fr_table_num_by_substr(_table, _table ## _len, _name, _name_len, _def)
+#define fr_table_num_by_substr(_table, _name, _name_len, _def) \
+_Generic((_table), \
+        fr_table_t const *             :       fr_table_sorted_num_by_substr,  \
+        fr_table_ordered_t const *     :       fr_table_ordered_num_by_substr, \
+        fr_table_t *                   :       fr_table_sorted_num_by_substr,  \
+        fr_table_ordered_t *           :       fr_table_ordered_num_by_substr  \
+)(_table, _table ## _len, _name, _name_len, _def)
+
+int            _fr_table_sorted_num_by_longest_prefix(fr_table_t const *table, size_t table_len,
+                                                   char const *name, size_t name_len, int def);
 
 /** Find the longest string match in a lexicographically sorted fr_table_t table
  *
- * @copybrief _fr_table_lex_num_by_longest_prefix
+ * @copybrief _fr_table_sorted_num_by_longest_prefix
  */
-#define                fr_table_lex_num_by_longest_prefix(_table, _name, _name_len, _def) \
-               _fr_table_lex_num_by_longest_prefix(_table, _table ## _len, _name, _name_len, _def)
+#define                fr_table_sorted_num_by_longest_prefix(_table, _name, _name_len, _def) \
+               _fr_table_sorted_num_by_longest_prefix(_table, , _name, _name_len, _def)
 
-/** Efficient string lookup in lexicographically sorted fr_table_t table
- *
- * @copybrief _fr_table_lex_num_by_str
- */
-#define                fr_table_lex_num_by_str(_table, _name, _name_len, _def) \
-               _fr_table_lex_num_by_str(_table, _table ## _len, _name, _name_len, _def)
+
+char const     *_fr_table_str_by_num(fr_table_ordered_t const *table, size_t table_len,
+                                     int number, char const *def);
 
 /** Convert an integer to a string
  *
- * @copybrief _fr_table_str_from_int
+ * @param[in] _table           to search in.
+ * @param[in] _number          to resolve to a string.
+ * @param[in] _def             Default string to return if there's no match.
+ * @return
+ *     - _def if _number name matched no entries in the table.
+ *     - the string value of the matching entry.
  */
-#define                fr_table_str_by_num(_table, _number, _def) \
-               _fr_table_str_by_num(_table, _table ## _len, _number, _def)
+#define fr_table_str_by_num(_table, _number, _def) \
+_Generic((_table), \
+        fr_table_t const *             :       _fr_table_str_by_num,   \
+        fr_table_ordered_t const *     :       _fr_table_str_by_num,   \
+        fr_table_t *                   :       _fr_table_str_by_num,   \
+        fr_table_ordered_t *           :       _fr_table_str_by_num    \
+)((fr_table_ordered_t const *)_table, _table ## _len, _number, _def)
+
 #ifdef __cplusplus
 }
 #endif
index 4a921fc2e375c80d9a3360f665c2d697996ccc05..7eb0eb721074e10c78d32349e19f2cc6e0a4e4fa 100644 (file)
@@ -254,7 +254,7 @@ const bool fr_str_tok[] = {
  *     Returns 0 or special token value.
  */
 static FR_TOKEN getthing(char const **ptr, char *buf, int buflen, bool tok,
-                        fr_table_t const *tokenlist, size_t tokenlist_len, bool unescape)
+                        fr_table_ordered_t const *tokenlist, size_t tokenlist_len, bool unescape)
 {
        char                    *s;
        char const              *p;
index 53d67af6676e5f46615ece1e86aea58abda5f123..899a6c5c14e218cd9bbc0aa3458885562cdc7262 100644 (file)
@@ -76,7 +76,7 @@ typedef enum fr_token {
  */
 #define FR_TABLE_NOT_FOUND     INT32_MIN
 
-extern fr_table_t const fr_tokens_table[];
+extern fr_table_ordered_t const fr_tokens_table[];
 extern size_t fr_tokens_table_len;
 extern fr_table_t const fr_token_quotes_table[];
 extern size_t fr_token_quotes_table_len;
index a1bed7ec2e59efeceafa120d8c988b7447c2972a..57f9d1781e4439a62fbd73f0e58d0843ebcc9af5 100644 (file)
@@ -51,7 +51,7 @@ typedef struct value_box fr_value_box_t;
 extern "C" {
 #endif
 
-extern fr_table_t const fr_value_box_type_table[];
+extern fr_table_ordered_t const fr_value_box_type_table[];
 extern size_t fr_value_box_type_table_len;
 
 extern size_t const fr_value_box_field_sizes[];