Skip to content

Commit

Permalink
hostlist: add hostlist_find_hostname and support
Browse files Browse the repository at this point in the history
problem: each time we search for a hostname in a hostlist, even with the
allocations avoided and so-forth, we have to find its length, parse the
integer at the end, and validate it.  All of this is quite expensive, to
the tune of as much as 60-70% of the search time.

solution: add an interface to do all the prep work and return an opaque
handle to the hostname object hostlist uses internally so a caller can
re-use a pre-built object with the new hostlist_find_hostname interface.
The result comes out a bit over twice as fast as directly using the
allocation-free interface.
  • Loading branch information
trws committed Sep 5, 2024
1 parent e817278 commit 5639cda
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 12 deletions.
43 changes: 34 additions & 9 deletions src/common/libhostlist/hostlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,16 +688,10 @@ int hostlist_count (struct hostlist *hl)
}

static int hostlist_find_host (struct hostlist *hl,
const char *hostname,
struct stack_hostname *hn,
struct current *cur)
{
int i, count, ret = -1;
struct stack_hostname hn_storage;

struct stack_hostname *hn = hostname_stack_create (&hn_storage, hostname);
if (!hn)
return -1;

for (i = 0, count = 0; i < hl->nranges; i++) {
int offset = hostrange_hn_within (hl->hr[i], hn);
if (offset >= 0) {
Expand All @@ -721,7 +715,33 @@ int hostlist_find (struct hostlist *hl, const char *hostname)
errno = EINVAL;
return -1;
}
return hostlist_find_host (hl, hostname, &hl->current);
struct stack_hostname hn_storage;

struct stack_hostname *hn = hostname_stack_create (&hn_storage, hostname);
if (!hn)
return -1;
return hostlist_find_host (hl, hn, &hl->current);
}

int hostlist_find_hostname (struct hostlist *hl, struct hostname *hn)
{
if (!hl || !hn) {
errno = EINVAL;
return -1;
}
struct stack_hostname hn_storage;

struct stack_hostname *shn = hostname_stack_create_from_hostname (&hn_storage, hn);
if (!hn)
return -1;
return hostlist_find_host (hl, shn, &hl->current);
}

struct hostname *hostlist_hostname_create (const char *hn) {
return hostname_create (hn);
}
void hostlist_hostname_destroy (struct hostname *hn) {
hostname_destroy(hn);
}

/* Remove host at cursor 'cur'. If the current real cursor hl->current
Expand Down Expand Up @@ -786,7 +806,12 @@ static int hostlist_remove_at (struct hostlist *hl, struct current *cur)
static int hostlist_delete_host (struct hostlist *hl, const char *hostname)
{
struct current cur = { 0 };
int n = hostlist_find_host (hl, hostname, &cur);
struct stack_hostname hn_storage;

struct stack_hostname *hn = hostname_stack_create (&hn_storage, hostname);
if (!hn)
return -1;
int n = hostlist_find_host (hl, hn, &cur);
if (n < 0)
return errno == ENOENT ? 0 : -1;
return hostlist_remove_at (hl, &cur);
Expand Down
36 changes: 36 additions & 0 deletions src/common/libhostlist/hostlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,42 @@ const char * hostlist_nth (struct hostlist * hl, int n);
*/
int hostlist_find (struct hostlist * hl, const char *hostname);

/*
* Search hostlist hl for the first host matching hostname
* and return position in list if found.
*
* Leaves cursor pointing to the matching host.
*
* Returns -1 if host is not found.
*/
struct hostname *hostlist_hostname_create (const char *);

/*
* Free resources associated with hostname hn.
*/
void hostlist_hostname_destroy (struct hostname *hn);

/*
* Search hostlist hl for the first host matching hn
* and return position in list if found.
*
* Leaves cursor pointing to the matching host.
*
* Returns -1 if host is not found.
*/
int hostlist_find_hostname (struct hostlist *hl, struct hostname *hn);

/*
* Search hostlist hl for the first host matching the current hostname in
* hostlist hl_src and return position in list if found.
*
* Leaves the cursor of hl pointing to the matching host, and hl_src pointing
* to the same value.
*
* Returns -1 if host is not found.
*/
int hostlist_find_current (struct hostlist * hl, struct hostlist *hl_src);

/*
* Delete all hosts in the list represented by `hosts'
*
Expand Down
17 changes: 17 additions & 0 deletions src/common/libhostlist/hostname.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ static int hostname_len (const char *hostname)
return len;
}

struct stack_hostname * hostname_stack_create_from_hostname (struct stack_hostname *hn, struct hostname *src) {
if (!hn || !src) {
errno = EINVAL;
return NULL;
}
hn->hostname = src->hostname;
hn->suffix = src->suffix;
hn->len = src->len;
hn->len_prefix = src->len_prefix;
hn->width = src->width;
hn->num = src->num;
return hn;
}

struct stack_hostname * hostname_stack_create_with_suffix (struct stack_hostname *hn,
const char *hostname, int len, int idx) {
if (!hostname || !hn || len < 0) {
Expand Down Expand Up @@ -128,6 +142,9 @@ struct hostname * hostname_create_with_suffix (const char *hostname,
}

hn->num = 0;
hn->len = len;
hn->len_prefix = idx + 1;
hn->width = hn->len - hn->len_prefix;
hn->prefix = NULL;
hn->suffix = NULL;

Expand Down
6 changes: 5 additions & 1 deletion src/common/libhostlist/hostname.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
struct hostname {
char *hostname; /* cache of initialized hostname */
char *prefix; /* hostname prefix */
int len; /* length minus invalid characters */
int len_prefix; /* length of the prefix */
int width; /* length of the suffix */
unsigned long num; /* numeric suffix */

/* string representation of numeric suffix
Expand All @@ -30,7 +33,7 @@ struct stack_hostname {
int len; /* length minus invalid characters */
int len_prefix; /* length of the prefix */
int width; /* length of the suffix */
int num; /* numeric suffix */
unsigned long num; /* numeric suffix */

/* string representation of numeric suffix
* points into `hostname' */
Expand All @@ -40,6 +43,7 @@ struct stack_hostname {
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_from_hostname (struct stack_hostname *hn, struct hostname* hn_src);
struct stack_hostname * hostname_stack_create_with_suffix (struct stack_hostname *hn,
const char *hostname, int len, int idx);
struct stack_hostname * hostname_stack_copy_one_less_digit (struct stack_hostname *dst,
Expand Down
2 changes: 1 addition & 1 deletion src/common/libhostlist/hostrange.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct hostrange * hostrange_create_single (const char *prefix)

/* Create a hostrange object with a prefix, hi, lo, and format width
*/
struct hostrange * hostrange_create (char *prefix,
struct hostrange * hostrange_create (const char *prefix,
unsigned long lo,
unsigned long hi,
int width)
Expand Down
2 changes: 1 addition & 1 deletion src/common/libhostlist/hostrange.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct hostrange {

struct hostrange * hostrange_create_single (const char *);

struct hostrange * hostrange_create (char *s,
struct hostrange * hostrange_create (const char *s,
unsigned long lo,
unsigned long hi,
int width);
Expand Down

0 comments on commit 5639cda

Please sign in to comment.