194 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| commit 6b907e90c74fce82d6b712493d8b362bdd1a1ec1
 | |
| Author: Nathan Scott <nathans@redhat.com>
 | |
| Date:   Tue Dec 14 08:54:14 2021 +1100
 | |
| 
 | |
|     pmlogconf: switch to the bulk pmLookupDescs(3) interface
 | |
|     
 | |
|     No functional change, all existing regression tests pass.
 | |
|     
 | |
|     Related to Red Hat BZ #1973833.
 | |
| 
 | |
| diff --git a/src/pmlogconf/pmlogconf.c b/src/pmlogconf/pmlogconf.c
 | |
| index fa1156859d..ef4fc08bbd 100644
 | |
| --- a/src/pmlogconf/pmlogconf.c
 | |
| +++ b/src/pmlogconf/pmlogconf.c
 | |
| @@ -473,13 +473,19 @@ fetch_groups(void)
 | |
|  {
 | |
|      static pmResult	*result;
 | |
|      const char		**names;
 | |
| +    pmDesc		*descs;
 | |
|      pmID		*pmids;
 | |
| -    int			i, n, sts;
 | |
| +    int			i, n, sts, count;
 | |
|  
 | |
| -    /* prepare arrays of names and identifiers for PMAPI metric lookup */
 | |
| +    /* prepare arrays of names, descriptors and IDs for PMAPI metric lookup */
 | |
|      if ((names = calloc(ngroups, sizeof(char *))) == NULL)
 | |
|  	return -ENOMEM;
 | |
| +    if ((descs = calloc(ngroups, sizeof(pmDesc))) == NULL) {
 | |
| +	free(names);
 | |
| +	return -ENOMEM;
 | |
| +    }
 | |
|      if ((pmids = calloc(ngroups, sizeof(pmID))) == NULL) {
 | |
| +	free(descs);
 | |
|  	free(names);
 | |
|  	return -ENOMEM;
 | |
|      }
 | |
| @@ -490,15 +496,16 @@ fetch_groups(void)
 | |
|  	    continue;
 | |
|  	names[n++] = (const char *)groups[i].metric;
 | |
|      }
 | |
| +    count = n;
 | |
|  
 | |
| -    if ((sts = pmLookupName(n, names, pmids)) < 0) {
 | |
| -	if (n == 1)
 | |
| +    if ((sts = pmLookupName(count, names, pmids)) < 0) {
 | |
| +	if (count == 1)
 | |
|  	    groups[0].pmid = PM_ID_NULL;
 | |
|  	else
 | |
|  	    fprintf(stderr, "%s: cannot lookup metric names: %s\n",
 | |
|  			    pmGetProgname(), pmErrStr(sts));
 | |
|      }
 | |
| -    else if ((sts = pmFetch(n, pmids, &result)) < 0) {
 | |
| +    else if ((sts = pmFetch(count, pmids, &result)) < 0) {
 | |
|  	fprintf(stderr, "%s: cannot fetch metric values: %s\n",
 | |
|  			pmGetProgname(), pmErrStr(sts));
 | |
|      }
 | |
| @@ -510,6 +517,13 @@ fetch_groups(void)
 | |
|  	    else
 | |
|  		groups[i].pmid = pmids[n++];
 | |
|  	}
 | |
| +	/* descriptor lookup, descs_hash handles failure here */
 | |
| +	(void) pmLookupDescs(count, pmids, descs);
 | |
| +
 | |
| +	/* create a hash over the descs for quick PMID lookup */
 | |
| +	if ((sts = descs_hash(count, descs)) < 0)
 | |
| +	    fprintf(stderr, "%s: cannot hash metric descs: %s\n",
 | |
| +			    pmGetProgname(), pmErrStr(sts));
 | |
|  	/* create a hash over the result for quick PMID lookup */
 | |
|  	if ((sts = values_hash(result)) < 0)
 | |
|  	    fprintf(stderr, "%s: cannot hash metric values: %s\n",
 | |
| @@ -806,14 +820,16 @@ evaluate_string_regexp(group_t *group, regex_cmp_t compare)
 | |
|      int			i, found;
 | |
|      pmValueSet		*vsp;
 | |
|      pmValue		*vp;
 | |
| +    pmDesc		*dp;
 | |
|      pmAtomValue		atom;
 | |
|      regex_t		regex;
 | |
|      int			sts, type;
 | |
|  
 | |
| -    if ((vsp = metric_values(group->pmid)) == NULL)
 | |
| +    if ((vsp = metric_values(group->pmid)) == NULL ||
 | |
| +        (dp = metric_desc(group->pmid)) == NULL)
 | |
|  	return 0;
 | |
|  
 | |
| -    type = metric_type(group->pmid);
 | |
| +    type = dp->type;
 | |
|      if (type < 0 || type > PM_TYPE_STRING) {
 | |
|  	fprintf(stderr, "%s: %s uses regular expression on non-scalar metric\n",
 | |
|  		pmGetProgname(), group->tag);
 | |
| @@ -849,11 +865,14 @@ evaluate_string_regexp(group_t *group, regex_cmp_t compare)
 | |
|  static int
 | |
|  evaluate_values(group_t *group, numeric_cmp_t ncmp, string_cmp_t scmp)
 | |
|  {
 | |
| -    int			type = metric_type(group->pmid);
 | |
| +    pmDesc		*dp;
 | |
| +
 | |
| +    if ((dp = metric_desc(group->pmid)) == NULL)
 | |
| +	return 0;
 | |
|  
 | |
| -    if (type == PM_TYPE_STRING)
 | |
| +    if (dp->type == PM_TYPE_STRING)
 | |
|  	return evaluate_string_values(group, scmp);
 | |
| -    return evaluate_number_values(group, type, ncmp);
 | |
| +    return evaluate_number_values(group, dp->type, ncmp);
 | |
|  }
 | |
|  
 | |
|  int
 | |
| diff --git a/src/pmlogconf/util.c b/src/pmlogconf/util.c
 | |
| index d44c2e529a..293eb2eca3 100644
 | |
| --- a/src/pmlogconf/util.c
 | |
| +++ b/src/pmlogconf/util.c
 | |
| @@ -1,5 +1,5 @@
 | |
|  /*
 | |
| - * Copyright (c) 2020 Red Hat.  All Rights Reserved.
 | |
| + * Copyright (c) 2020-2021 Red Hat.  All Rights Reserved.
 | |
|   * 
 | |
|   * This program is free software; you can redistribute it and/or modify it
 | |
|   * under the terms of the GNU General Public License as published by the
 | |
| @@ -14,7 +14,7 @@
 | |
|  #include "util.h"
 | |
|  
 | |
|  static __pmHashCtl	valuesctl;	/* pointers to values in pmResult */
 | |
| -static __pmHashCtl	typesctl;	/* metric types from pmLookupDesc */
 | |
| +static __pmHashCtl	descsctl;	/* metric descs from pmLookupDesc */
 | |
|  
 | |
|  int
 | |
|  values_hash(pmResult *result)
 | |
| @@ -47,27 +47,33 @@ metric_values(pmID pmid)
 | |
|  }
 | |
|  
 | |
|  int
 | |
| -metric_type(pmID pmid)
 | |
| +descs_hash(int numpmid, pmDesc *descs)
 | |
|  {
 | |
| -    __pmHashNode	*node;
 | |
| -    pmDesc		desc;
 | |
| -    int			sts, *data;
 | |
| +    unsigned int	i;
 | |
| +    pmDesc		*dp;
 | |
| +    int			sts;
 | |
|  
 | |
| -    if (pmid == PM_IN_NULL)
 | |
| -	return PM_TYPE_UNKNOWN;
 | |
| -    if ((node = __pmHashSearch(pmid, &typesctl)) == NULL) {
 | |
| -	if ((sts = pmLookupDesc(pmid, &desc)) < 0)
 | |
| -	    return sts;
 | |
| -	if ((data = malloc(sizeof(int))) == NULL)
 | |
| -	    return sts;
 | |
| -	*data = desc.type;
 | |
| -	if ((sts = __pmHashAdd(pmid, data, &typesctl)) < 0) {
 | |
| -	    free(data);
 | |
| +    if ((sts = __pmHashPreAlloc(numpmid, &descsctl)) < 0)
 | |
| +	return sts;
 | |
| +
 | |
| +    for (i = 0; i < numpmid; i++) {
 | |
| +	dp = &descs[i];
 | |
| +	if ((sts = __pmHashAdd(dp->pmid, dp, &descsctl)) < 0)
 | |
|  	    return sts;
 | |
| -	}
 | |
| -	return *data;
 | |
|      }
 | |
| -    return *(int *)node->data;
 | |
| +    return numpmid;
 | |
| +}
 | |
| +
 | |
| +pmDesc *
 | |
| +metric_desc(pmID pmid)
 | |
| +{
 | |
| +    __pmHashNode	*node;
 | |
| +
 | |
| +    if (pmid == PM_IN_NULL)
 | |
| +	return NULL;
 | |
| +    if ((node = __pmHashSearch(pmid, &descsctl)) == NULL)
 | |
| +	return NULL;
 | |
| +    return (pmDesc *)node->data;
 | |
|  }
 | |
|  
 | |
|  int
 | |
| diff --git a/src/pmlogconf/util.h b/src/pmlogconf/util.h
 | |
| index 17d856a0d7..a11350d899 100644
 | |
| --- a/src/pmlogconf/util.h
 | |
| +++ b/src/pmlogconf/util.h
 | |
| @@ -34,7 +34,9 @@ extern void fmt(const char *, char *, size_t, int, int, fmt_t, void *);
 | |
|  
 | |
|  extern int values_hash(pmResult *);
 | |
|  extern pmValueSet *metric_values(pmID);
 | |
| -extern int metric_type(pmID);
 | |
| +
 | |
| +extern int descs_hash(int, pmDesc *);
 | |
| +extern pmDesc *metric_desc(pmID);
 | |
|  
 | |
|  typedef int (*numeric_cmp_t)(double, double);
 | |
|  extern int number_equal(double, double);
 |