Skip to content

Commit

Permalink
hostlist_find: refine allocation-free case
Browse files Browse the repository at this point in the history
problem: we still use strlen and parse integers significantly more than
we need to

solution: use the existing lengths in more places, and instead of
re-parsing the suffix find the power of 10 matching the length of the
string, and mod by that to chop off the extra digit in the recursive
case
  • Loading branch information
trws committed Sep 5, 2024
1 parent f41129d commit 56497ff
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 18 deletions.
32 changes: 19 additions & 13 deletions src/common/libhostlist/hostname.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <string.h>

Expand Down Expand Up @@ -46,14 +47,13 @@ static int host_prefix_end (const char *hostname, int len)
static int hostname_len (const char *hostname)
{
int len = strlen (hostname);
for (int i = 0; i < len; i++)
if (memchr (INVALID_CHARS, sizeof(INVALID_CHARS) - 1, hostname[i]))
return -1;
if (len != strcspn (hostname, INVALID_CHARS))
return -1;
return len;
}

struct stack_hostname * hostname_stack_create_with_suffix (struct stack_hostname *hn,
const char *hostname, unsigned long len, int idx) {
const char *hostname, int len, int idx) {
if (!hostname || !hn || len < 0) {
errno = EINVAL;
return NULL;
Expand All @@ -74,30 +74,36 @@ struct stack_hostname * hostname_stack_create_with_suffix (struct stack_hostname
errno = EINVAL;
return NULL;
}
hn->width = strlen(hn->suffix);
hn->width = hn->len - hn->len_prefix;
return hn;
}

struct stack_hostname * hostname_stack_copy_with_suffix (struct stack_hostname *dst,
struct stack_hostname *src, int idx) {
struct stack_hostname * hostname_stack_copy_one_less_digit (struct stack_hostname *dst,
struct stack_hostname *src) {
if (!dst || !src) {
errno = EINVAL;
return NULL;
}
*dst = *src;
dst->len_prefix = idx + 1;
if (idx == dst->len - 1) {
dst->len_prefix = src->len_prefix + 1;
if (src->len_prefix == dst->len - 1) {
return dst;
}
dst->suffix = dst->hostname + dst->len_prefix;

char *p = NULL;
dst->num = strtoul (dst->suffix, &p, 10);
if (p == dst->suffix && dst->num == 0) {
dst->width = dst->len - dst->len_prefix;
if (dst->width < 0 || dst->width > 10){

Check warning

Code scanning / CodeQL

Comparison result is always the same Warning

Comparison is always false because width >= 0.
errno = EINVAL;
return NULL;
}
dst->width = strlen(dst->suffix);

// remove the most significant decimal digit without reparsing
// lookup table because pow is slow
static const int pow10[10] = {
1, 10, 100, 1000, 10000,
100000, 1000000, 10000000, 100000000, 1000000000
};
dst->num = src->num % pow10[dst->width];
return dst;
}

Expand Down
6 changes: 3 additions & 3 deletions src/common/libhostlist/hostname.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ struct hostname * hostname_create (const char *s);
struct hostname * hostname_create_with_suffix (const char *s, int i);
struct stack_hostname * hostname_stack_create (struct stack_hostname *hn, const char *hostname);
struct stack_hostname * hostname_stack_create_with_suffix (struct stack_hostname *hn,
const char *hostname, unsigned long len, int idx);
struct stack_hostname * hostname_stack_copy_with_suffix (struct stack_hostname *dst,
struct stack_hostname *src, int idx);
const char *hostname, int len, int idx);
struct stack_hostname * hostname_stack_copy_one_less_digit (struct stack_hostname *dst,
struct stack_hostname *src);
void hostname_destroy (struct hostname *hn);

int hostname_suffix_is_valid (struct hostname *hn);
Expand Down
3 changes: 1 addition & 2 deletions src/common/libhostlist/hostrange.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,7 @@ int hostrange_hn_within (struct hostrange * hr, struct stack_hostname * hn)
* Create new hostname object with its prefix offset by one
*/
struct stack_hostname shn;
struct stack_hostname * h = hostname_stack_copy_with_suffix (&shn,
hn, hn->len_prefix);
struct stack_hostname * h = hostname_stack_copy_one_less_digit (&shn, hn);
/*
* Recursive call :-o
*/
Expand Down

0 comments on commit 56497ff

Please sign in to comment.