Blame SOURCES/redhat-bugzilla-2030121.patch

f76dca
commit df7b7bf64eb354114e6c519e3e03ffc446afa8ba
f76dca
Author: Nathan Scott <nathans@redhat.com>
f76dca
Date:   Fri Nov 26 09:17:23 2021 +1100
f76dca
f76dca
    libpcp_pmda: add indom cache fast-paths for inst lookup beyond max
f76dca
    
f76dca
    We encountered a situation where indom cache loading consumed vast
f76dca
    CPU resources for an indom of size ~150k instances.  Profiling was
f76dca
    used to identify the insert loop that ensures the inst linked list
f76dca
    within the cache hash tables is sorted - this loop is O(N*2) as we
f76dca
    potentially walk this list from the start on every insert during a
f76dca
    cache load.  Because cache loading happens from a sorted file, the
f76dca
    worst-case scenario happened every time - each new instance insert
f76dca
    occurs beyond the current maximum.  Fortunately we maintain a last
f76dca
    entry pointer, so the new fast path uses that first and falls back
f76dca
    to the original behaviour for an out-of-order insertion.
f76dca
    
f76dca
    A second opportunity for the same optimization was identified when
f76dca
    auditing the rest of cache.c - in the find_inst() routine for inst
f76dca
    identifier lookups beyond the current maximum observed instance.
f76dca
    
f76dca
    Resolves Red Hat BZ #2024648
f76dca
f76dca
diff --git a/src/libpcp_pmda/src/cache.c b/src/libpcp_pmda/src/cache.c
f76dca
index 0e66506d74..196ffc1da9 100644
f76dca
--- a/src/libpcp_pmda/src/cache.c
f76dca
+++ b/src/libpcp_pmda/src/cache.c
f76dca
@@ -328,6 +328,9 @@ find_inst(hdr_t *h, int inst)
f76dca
 {
f76dca
     entry_t	*e;
f76dca
 
f76dca
+    if ((e = h->last) != NULL && e->inst < inst)
f76dca
+	return NULL;
f76dca
+
f76dca
     for (e = h->first; e != NULL; e = e->next) {
f76dca
 	if (e->inst == inst && e->state != PMDA_CACHE_EMPTY)
f76dca
 	    break;
f76dca
@@ -621,7 +624,11 @@ insert_cache(hdr_t *h, const char *name, int inst, int *sts)
f76dca
 	    *sts = PM_ERR_INST;
f76dca
 	    return e;
f76dca
 	}
f76dca
-	for (e = h->first; e != NULL; e = e->next) {
f76dca
+	/* if this entry is beyond the (sorted) list end, avoid linear scan */
f76dca
+	if ((e = h->last) == NULL || e->inst > inst)
f76dca
+	    e = h->first;
f76dca
+	/* linear search over linked list, starting at either first or last */
f76dca
+	for (; e != NULL; e = e->next) {
f76dca
 	    if (e->inst < inst)
f76dca
 		last_e = e;
f76dca
 	    else if (e->inst > inst)