Skip to content
Permalink
Browse files

Efficient table lookups, phase 2

  • Loading branch information
arr2036 committed Aug 14, 2019
1 parent 80de8a8 commit 8d3ea334213dfb52fdbcde5b37e655e985c4095f
@@ -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;

/*
@@ -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 {
@@ -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",
@@ -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 },
@@ -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);

@@ -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 {
@@ -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;

0 comments on commit 8d3ea33

Please sign in to comment.
You can’t perform that action at this time.