Commit eb9826bd authored by Jonathan Jenkins's avatar Jonathan Jenkins
Browse files

rework config storage to a much tighter format

should do good things for codes-mapping lookup performance
parent 62e1153b
...@@ -16,26 +16,34 @@ ...@@ -16,26 +16,34 @@
#define CONFIGURATION_MAX_TYPES 10 #define CONFIGURATION_MAX_TYPES 10
#define CONFIGURATION_MAX_ANNOS 10 #define CONFIGURATION_MAX_ANNOS 10
// NOTE: direct offsets are used when first building the structure as we're
// building up one big buffer to hold entity names. Pointers are set after the
// initialization process during configuration_load
typedef union {
char const * ptr;
int offset;
} config_name_u;
typedef struct config_lptype_s typedef struct config_lptype_s
{ {
char name[CONFIGURATION_MAX_NAME]; config_name_u name;
char anno[CONFIGURATION_MAX_NAME]; config_name_u anno;
uint64_t count; int count;
} config_lptype_t; } config_lptype_t;
typedef struct config_lpgroup_s typedef struct config_lpgroup_s
{ {
char name[CONFIGURATION_MAX_NAME]; config_name_u name;
uint64_t repetitions; int repetitions;
int lptypes_count;
config_lptype_t lptypes[CONFIGURATION_MAX_TYPES]; config_lptype_t lptypes[CONFIGURATION_MAX_TYPES];
uint64_t lptypes_count;
} config_lpgroup_t; } config_lpgroup_t;
// mapping of lp type to the list of annotations used. Used for convenience when // mapping of lp type to the list of annotations used. Used for convenience when
// models are performing configuraiton code // models are performing configuraiton code
typedef struct config_anno_map_s typedef struct config_anno_map_s
{ {
char lp_name[CONFIGURATION_MAX_NAME]; config_name_u lp_name;
// only explicit annotations tracked here - use a flag to indicate a // only explicit annotations tracked here - use a flag to indicate a
// non-annotated LP type // non-annotated LP type
int has_unanno_lp; int has_unanno_lp;
...@@ -43,10 +51,10 @@ typedef struct config_anno_map_s ...@@ -43,10 +51,10 @@ typedef struct config_anno_map_s
// (annotation-ignoring) lookup semantics, provide a flag to determine if // (annotation-ignoring) lookup semantics, provide a flag to determine if
// the unannotated lp type is first // the unannotated lp type is first
int is_unanno_first; int is_unanno_first;
uint64_t num_annos; int num_annos;
// maintain the number of lps that have the particular annotation // maintain the number of lps that have the particular annotation
uint64_t num_anno_lps[CONFIGURATION_MAX_ANNOS]; int num_anno_lps[CONFIGURATION_MAX_ANNOS];
char * annotations[CONFIGURATION_MAX_ANNOS]; config_name_u annotations[CONFIGURATION_MAX_ANNOS];
} config_anno_map_t; } config_anno_map_t;
typedef struct config_lpgroups_s typedef struct config_lpgroups_s
......
...@@ -280,17 +280,17 @@ int configuration_get_value_double (ConfigHandle *handle, ...@@ -280,17 +280,17 @@ int configuration_get_value_double (ConfigHandle *handle,
} }
static void check_add_anno( static void check_add_anno(
const char *anno, int anno_offset,
config_anno_map_t *map){ config_anno_map_t *map){
if (anno[0] == '\0'){ if (anno_offset == -1) {
map->has_unanno_lp = 1; map->has_unanno_lp = 1;
if (!map->num_annos) if (!map->num_annos)
map->is_unanno_first = 1; map->is_unanno_first = 1;
} }
else{ else{
uint64_t a = 0; int a = 0;
for (; a < map->num_annos; a++){ for (; a < map->num_annos; a++){
if (strcmp(map->annotations[a], anno) == 0){ if (map->annotations[a].offset == anno_offset) {
map->num_anno_lps[a]++; map->num_anno_lps[a]++;
break; break;
} }
...@@ -298,21 +298,21 @@ static void check_add_anno( ...@@ -298,21 +298,21 @@ static void check_add_anno(
if (a == map->num_annos){ if (a == map->num_annos){
// we have a new anno! // we have a new anno!
assert(a < CONFIGURATION_MAX_ANNOS); assert(a < CONFIGURATION_MAX_ANNOS);
map->annotations[a] = strdup(anno); map->annotations[a].offset = anno_offset;
map->num_annos++; map->num_annos++;
map->num_anno_lps[a] = 1; map->num_anno_lps[a] = 1;
} // else anno was already there, do nothing } // else anno was already there, do nothing
} }
} }
static void check_add_lp_type_anno( static void check_add_lp_type_anno(
const char *lp_name, int lp_name_offset,
const char *anno, int anno_offset,
config_lpgroups_t *lpgroups){ config_lpgroups_t *lpgroups){
uint64_t lpt_anno = 0; uint64_t lpt_anno = 0;
for (; lpt_anno < lpgroups->lpannos_count; lpt_anno++){ for (; lpt_anno < lpgroups->lpannos_count; lpt_anno++){
config_anno_map_t *map = &lpgroups->lpannos[lpt_anno]; config_anno_map_t *map = &lpgroups->lpannos[lpt_anno];
if (strcmp(map->lp_name, lp_name) == 0){ if (map->lp_name.offset == lp_name_offset){
check_add_anno(anno, map); check_add_anno(anno_offset, map);
break; break;
} }
} }
...@@ -321,13 +321,13 @@ static void check_add_lp_type_anno( ...@@ -321,13 +321,13 @@ static void check_add_lp_type_anno(
assert(lpt_anno < CONFIGURATION_MAX_TYPES); assert(lpt_anno < CONFIGURATION_MAX_TYPES);
config_anno_map_t *map = &lpgroups->lpannos[lpt_anno]; config_anno_map_t *map = &lpgroups->lpannos[lpt_anno];
// initialize this annotation map // initialize this annotation map
strcpy(map->lp_name, lp_name); map->lp_name.offset = lp_name_offset;
map->num_annos = 0; map->num_annos = 0;
map->has_unanno_lp = 0; map->has_unanno_lp = 0;
map->is_unanno_first = 0; map->is_unanno_first = 0;
memset(map->num_anno_lps, 0, memset(map->num_anno_lps, 0,
CONFIGURATION_MAX_ANNOS*sizeof(*map->num_anno_lps)); CONFIGURATION_MAX_ANNOS*sizeof(*map->num_anno_lps));
check_add_anno(anno, map); check_add_anno(anno_offset, map);
lpgroups->lpannos_count++; lpgroups->lpannos_count++;
} }
} }
...@@ -342,11 +342,11 @@ static void check_add_lp_type_anno( ...@@ -342,11 +342,11 @@ static void check_add_lp_type_anno(
} while (0) } while (0)
/* helper for setting up the canonical name mapping */ /* helper for setting up the canonical name mapping */
static void check_add_uniq_str( static int check_add_uniq_str(
char const *** str_array_ref, int ** offset_array,
char ** str_buf, char ** str_buf,
int * num_strs, int * num_strs,
int * str_array_cap, // buffer capacity for resizing int * offset_array_cap, // buffer capacity for resizing
int * str_buf_len, int * str_buf_len,
int * str_buf_cap, // buffer capacity for resizing int * str_buf_cap, // buffer capacity for resizing
char const * str) char const * str)
...@@ -354,20 +354,21 @@ static void check_add_uniq_str( ...@@ -354,20 +354,21 @@ static void check_add_uniq_str(
int slen = strlen(str); int slen = strlen(str);
for (int i = 0; i < *num_strs; i++) { for (int i = 0; i < *num_strs; i++) {
char const * b = (*str_array_ref)[i]; char const * b = (*str_buf) + (*offset_array)[i];
int blen = strlen(b); int blen = strlen(b);
if (slen == blen && memcmp(b, str, blen) == 0) if (slen == blen && memcmp(b, str, blen) == 0)
return; return i;
} }
REALLOC_IF(*str_array_cap, *num_strs, *str_array_ref); REALLOC_IF(*offset_array_cap, *num_strs, *offset_array);
REALLOC_IF(*str_buf_cap, *str_buf_len + slen + 1, *str_buf); REALLOC_IF(*str_buf_cap, *str_buf_len + slen + 1, *str_buf);
// include null char // include null char
memcpy(*str_buf + *str_buf_len, str, slen+1); memcpy(*str_buf + *str_buf_len, str, slen+1);
(*str_array_ref)[*num_strs] = *str_buf + *str_buf_len; (*offset_array)[*num_strs] = *str_buf_len;
*num_strs += 1; *num_strs += 1;
*str_buf_len += slen+1; *str_buf_len += slen+1;
return *num_strs-1;
} }
int configuration_get_lpgroups (ConfigHandle *handle, int configuration_get_lpgroups (ConfigHandle *handle,
...@@ -382,6 +383,7 @@ int configuration_get_lpgroups (ConfigHandle *handle, ...@@ -382,6 +383,7 @@ int configuration_get_lpgroups (ConfigHandle *handle,
size_t subse_count = 10; size_t subse_count = 10;
int i, j, lpt; int i, j, lpt;
char data[256]; char data[256];
// buffer mgmt vars
int num_uniq_group_names = 0; int num_uniq_group_names = 0;
int group_names_buf_len = 0; int group_names_buf_len = 0;
int lp_names_buf_len = 0; int lp_names_buf_len = 0;
...@@ -392,24 +394,25 @@ int configuration_get_lpgroups (ConfigHandle *handle, ...@@ -392,24 +394,25 @@ int configuration_get_lpgroups (ConfigHandle *handle,
int group_names_buf_cap = 1; int group_names_buf_cap = 1;
int lp_names_buf_cap = 1; int lp_names_buf_cap = 1;
int anno_names_buf_cap = 1; int anno_names_buf_cap = 1;
int name_pos;
memset (lpgroups, 0, sizeof(*lpgroups)); memset (lpgroups, 0, sizeof(*lpgroups));
lpgroups->group_names = int *group_names_offsets =
malloc(sizeof(*lpgroups->group_names) * group_names_cap); malloc(sizeof(*group_names_offsets) * group_names_cap);
lpgroups->lp_names = int *lp_names_offsets =
malloc(sizeof(*lpgroups->lp_names) * lp_names_cap); malloc(sizeof(*lp_names_offsets) * lp_names_cap);
lpgroups->anno_names = int *anno_names_offsets =
malloc(sizeof(*lpgroups->anno_names) * anno_names_cap); malloc(sizeof(*anno_names_offsets) * anno_names_cap);
lpgroups->group_names_buf = lpgroups->group_names_buf =
malloc(sizeof(*lpgroups->group_names_buf) * group_names_buf_cap); malloc(sizeof(*lpgroups->group_names_buf) * group_names_buf_cap);
lpgroups->lp_names_buf = lpgroups->lp_names_buf =
malloc(sizeof(*lpgroups->lp_names_buf) * lp_names_buf_cap); malloc(sizeof(*lpgroups->lp_names_buf) * lp_names_buf_cap);
lpgroups->anno_names_buf = lpgroups->anno_names_buf =
malloc(sizeof(*lpgroups->anno_names_buf) * anno_names_buf_cap); malloc(sizeof(*lpgroups->anno_names_buf) * anno_names_buf_cap);
assert(lpgroups->group_names != NULL); assert(group_names_offsets != NULL);
assert(lpgroups->lp_names != NULL); assert(lp_names_offsets != NULL);
assert(lpgroups->anno_names != NULL); assert(anno_names_offsets != NULL);
assert(lpgroups->group_names_buf != NULL); assert(lpgroups->group_names_buf != NULL);
assert(lpgroups->lp_names_buf != NULL); assert(lpgroups->lp_names_buf != NULL);
assert(lpgroups->anno_names_buf != NULL); assert(lpgroups->anno_names_buf != NULL);
...@@ -438,12 +441,11 @@ int configuration_get_lpgroups (ConfigHandle *handle, ...@@ -438,12 +441,11 @@ int configuration_get_lpgroups (ConfigHandle *handle,
subse_count = 10; subse_count = 10;
cf_openSection(*handle, sh, se[i].name, &subsh); cf_openSection(*handle, sh, se[i].name, &subsh);
cf_listSection(*handle, subsh, subse, &subse_count); cf_listSection(*handle, subsh, subse, &subse_count);
check_add_uniq_str(&lpgroups->group_names, name_pos = check_add_uniq_str(&group_names_offsets,
&lpgroups->group_names_buf, &num_uniq_group_names, &lpgroups->group_names_buf, &num_uniq_group_names,
&group_names_cap, &group_names_buf_len, &group_names_cap, &group_names_buf_len,
&group_names_buf_cap, se[i].name); &group_names_buf_cap, se[i].name);
strncpy(lpgroups->lpgroups[i].name, se[i].name, lpgroups->lpgroups[i].name.offset = group_names_offsets[name_pos];
CONFIGURATION_MAX_NAME);
lpgroups->lpgroups[i].repetitions = 1; lpgroups->lpgroups[i].repetitions = 1;
lpgroups->lpgroups_count++; lpgroups->lpgroups_count++;
if (num_uniq_group_names != lpgroups->lpgroups_count) if (num_uniq_group_names != lpgroups->lpgroups_count)
...@@ -464,43 +466,47 @@ int configuration_get_lpgroups (ConfigHandle *handle, ...@@ -464,43 +466,47 @@ int configuration_get_lpgroups (ConfigHandle *handle,
} }
else else
{ {
size_t s = sizeof(lpgroups->lpgroups[i].lptypes[lpt].name); // to avoid copy, find a possible annotation, change the
char *nm = lpgroups->lpgroups[i].lptypes[lpt].name; // string in the config structure itself, then change
char *anno = lpgroups->lpgroups[i].lptypes[lpt].anno; // back for posterity
// assume these are lptypes and counts char *c = strchr(subse[j].name, '@');
strncpy(nm, subse[j].name, s-1); if (c != NULL) {
lpgroups->lpgroups[i].lptypes[lpt].name[s-1] = '\0';
char *c = strchr(nm, '@');
if (c) {
strcpy(anno, c+1);
*c = '\0'; *c = '\0';
check_add_uniq_str( name_pos = check_add_uniq_str(
&lpgroups->anno_names, &anno_names_offsets,
&lpgroups->anno_names_buf, &lpgroups->anno_names_buf,
&lpgroups->num_uniq_annos, &lpgroups->num_uniq_annos,
&anno_names_cap, &anno_names_cap,
&anno_names_buf_len, &anno_names_buf_len,
&anno_names_buf_cap, &anno_names_buf_cap,
c+1); c+1);
} lpgroups->lpgroups[i].lptypes[lpt].anno.offset =
else { anno_names_offsets[name_pos];
anno[0] = '\0';
} }
else
lpgroups->lpgroups[i].lptypes[lpt].anno.offset = -1;
check_add_uniq_str( name_pos = check_add_uniq_str(
&lpgroups->lp_names, &lp_names_offsets,
&lpgroups->lp_names_buf, &lpgroups->lp_names_buf,
&lpgroups->num_uniq_lptypes, &lpgroups->num_uniq_lptypes,
&lp_names_cap, &lp_names_cap,
&lp_names_buf_len, &lp_names_buf_len,
&lp_names_buf_cap, &lp_names_buf_cap,
nm); subse[j].name);
lpgroups->lpgroups[i].lptypes[lpt].name.offset =
lp_names_offsets[name_pos];
if (c != NULL)
*c = '@';
// add to anno map // add to anno map
check_add_lp_type_anno(nm, anno, lpgroups); check_add_lp_type_anno(
lpgroups->lpgroups[i].lptypes[lpt].name.offset,
lpgroups->lpgroups[i].lptypes[lpt].anno.offset,
lpgroups);
CHECKED_STRTOL(lpgroups->lpgroups[i].lptypes[lpt].count, CHECKED_STRTOL(lpgroups->lpgroups[i].lptypes[lpt].count,
nm, data); lpgroups->lpgroups[i].lptypes[lpt].name, data);
lpgroups->lpgroups[i].lptypes_count++; lpgroups->lpgroups[i].lptypes_count++;
lpt++; lpt++;
} }
...@@ -510,15 +516,68 @@ int configuration_get_lpgroups (ConfigHandle *handle, ...@@ -510,15 +516,68 @@ int configuration_get_lpgroups (ConfigHandle *handle,
} }
} }
if (lpgroups->lpannos_count == 0) { // set up the string pointers
free(lpgroups->anno_names); lpgroups->group_names =
malloc(lpgroups->lpgroups_count * sizeof(*lpgroups->group_names));
lpgroups->lp_names =
malloc(lpgroups->num_uniq_lptypes * sizeof(*lpgroups->lp_names));
assert(lpgroups->group_names);
assert(lpgroups->lp_names);
for (int i = 0; i < lpgroups->lpgroups_count; i++) {
lpgroups->group_names[i] = lpgroups->group_names_buf +
group_names_offsets[i];
}
for (int i = 0; i < lpgroups->num_uniq_lptypes; i++) {
lpgroups->lp_names[i] = lpgroups->lp_names_buf +
lp_names_offsets[i];
}
if (lpgroups->num_uniq_annos == 0) {
free(lpgroups->anno_names_buf); free(lpgroups->anno_names_buf);
lpgroups->anno_names = NULL; lpgroups->anno_names = NULL;
lpgroups->anno_names_buf = NULL; lpgroups->anno_names_buf = NULL;
} }
else {
lpgroups->anno_names =
malloc(lpgroups->num_uniq_annos * sizeof(*lpgroups->anno_names));
assert(lpgroups->anno_names);
for (int i = 0; i < lpgroups->num_uniq_annos; i++) {
lpgroups->anno_names[i] = lpgroups->anno_names_buf +
anno_names_offsets[i];
}
}
// everything is set up in offset mode, now make a second pass and convert
// to pointers
for (int g = 0; g < lpgroups->lpgroups_count; g++) {
config_lpgroup_t *lpg = &lpgroups->lpgroups[g];
lpg->name.ptr = lpgroups->group_names_buf + lpg->name.offset;
for (int t = 0; t < lpg->lptypes_count; t++) {
config_lptype_t *lpt = &lpg->lptypes[t];
lpt->name.ptr = lpgroups->lp_names_buf + lpt->name.offset;
lpt->anno.ptr =
(lpt->anno.offset == -1)
? NULL
: lpgroups->anno_names_buf + lpt->anno.offset;
}
}
for (int m = 0; m < lpgroups->lpannos_count; m++) {
config_anno_map_t *map = &lpgroups->lpannos[m];
map->lp_name.ptr = lpgroups->lp_names_buf + map->lp_name.offset;
for (int a = 0; a < map->num_annos; a++) {
map->annotations[a].ptr =
(map->annotations[a].offset == -1)
? NULL
: lpgroups->anno_names_buf + map->annotations[a].offset;
}
}
cf_closeSection(*handle, sh); cf_closeSection(*handle, sh);
free(group_names_offsets);
free(lp_names_offsets);
free(anno_names_offsets);
return 0; return 0;
} }
...@@ -533,7 +592,7 @@ int configuration_get_annotation_index(const char * anno, ...@@ -533,7 +592,7 @@ int configuration_get_annotation_index(const char * anno,
const config_anno_map_t * anno_map){ const config_anno_map_t * anno_map){
if (anno == NULL) return -1; if (anno == NULL) return -1;
for (uint64_t i = 0; i < anno_map->num_annos; i++){ for (uint64_t i = 0; i < anno_map->num_annos; i++){
if (!strcmp(anno, anno_map->annotations[i])){ if (!strcmp(anno, anno_map->annotations[i].ptr)){
return (int)i; return (int)i;
} }
} }
......
...@@ -24,8 +24,9 @@ static int mini(int a, int b){ return a < b ? a : b; } ...@@ -24,8 +24,9 @@ static int mini(int a, int b){ return a < b ? a : b; }
// compare passed in annotation strings (NULL or nonempty) against annotation // compare passed in annotation strings (NULL or nonempty) against annotation
// strings in the config (empty or nonempty) // strings in the config (empty or nonempty)
static int cmp_anno(const char * anno_user, const char * anno_config){ static int cmp_anno(const char * anno_user, const char * anno_config){
return anno_user == NULL ? anno_config[0]=='\0' return anno_user == NULL ? anno_config == NULL
: !strcmp(anno_user, anno_config); : (anno_config != NULL
&& !strcmp(anno_user, anno_config));
} }
...@@ -91,7 +92,7 @@ int codes_mapping_get_group_reps(const char* group_name) ...@@ -91,7 +92,7 @@ int codes_mapping_get_group_reps(const char* group_name)
int grp; int grp;
for(grp = 0; grp < lpconf.lpgroups_count; grp++) for(grp = 0; grp < lpconf.lpgroups_count; grp++)
{ {
if(strcmp(lpconf.lpgroups[grp].name, group_name) == 0) if(strcmp(lpconf.lpgroups[grp].name.ptr, group_name) == 0)
return lpconf.lpgroups[grp].repetitions; return lpconf.lpgroups[grp].repetitions;
} }
return -1; return -1;
...@@ -113,14 +114,14 @@ int codes_mapping_get_lp_count( ...@@ -113,14 +114,14 @@ int codes_mapping_get_lp_count(
const config_lpgroup_t *lpg = &lpconf.lpgroups[g]; const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
// iterate over the lps if the group is null (count across all groups) // iterate over the lps if the group is null (count across all groups)
// or if the group names match // or if the group names match
if (group_name == NULL || strcmp(lpg->name, group_name) == 0){ if (group_name == NULL || strcmp(lpg->name.ptr, group_name) == 0){
for (int l = 0; l < lpg->lptypes_count; l++){ for (int l = 0; l < lpg->lptypes_count; l++){
const config_lptype_t *lpt = &lpg->lptypes[l]; const config_lptype_t *lpt = &lpg->lptypes[l];
if (strcmp(lp_type_name, lpt->name) == 0){ if (strcmp(lp_type_name, lpt->name.ptr) == 0){
// increment the count if we are ignoring annotations, // increment the count if we are ignoring annotations,
// query and entry are both unannotated, or if the // query and entry are both unannotated, or if the
// annotations match // annotations match
if (ignore_annos || cmp_anno(annotation, lpt->anno)){ if (ignore_annos || cmp_anno(annotation, lpt->anno.ptr)){
if (ignore_repetitions) if (ignore_repetitions)
lp_type_ct_total += lpt->count; lp_type_ct_total += lpt->count;
else else
...@@ -158,15 +159,15 @@ void codes_mapping_get_lp_id( ...@@ -158,15 +159,15 @@ void codes_mapping_get_lp_id(
rep_count += lpg->lptypes[l].count; rep_count += lpg->lptypes[l].count;
} }
// does group name match? // does group name match?
if (strcmp(lpg->name, group_name) == 0){ if (strcmp(lpg->name.ptr, group_name) == 0){
tw_lpid local_lp_count = 0; tw_lpid local_lp_count = 0;
// for each lp type // for each lp type
for (int l = 0; l < lpg->lptypes_count; l++){ for (int l = 0; l < lpg->lptypes_count; l++){
const config_lptype_t *lpt = &lpg->lptypes[l]; const config_lptype_t *lpt = &lpg->lptypes[l];
// does lp name match? // does lp name match?
if (strcmp(lpt->name, lp_type_name) == 0){ if (strcmp(lpt->name.ptr, lp_type_name) == 0){
// does annotation match (or are we ignoring annotations?) // does annotation match (or are we ignoring annotations?)
if (ignore_anno || cmp_anno(annotation, lpt->anno)){ if (ignore_anno || cmp_anno(annotation, lpt->anno.ptr)){
// return if sane offset // return if sane offset
if (offset >= (int) lpt->count){ if (offset >= (int) lpt->count){
goto ERROR; goto ERROR;
...@@ -210,18 +211,18 @@ int codes_mapping_get_lp_relative_id( ...@@ -210,18 +211,18 @@ int codes_mapping_get_lp_relative_id(
local_lp_name, &lp_type_index, local_annotation, &rep_id, &offset); local_lp_name, &lp_type_index, local_annotation, &rep_id, &offset);
const char * anno = (local_annotation[0]=='\0') ? NULL : local_annotation; const char * anno = (local_annotation[0]=='\0') ? NULL : local_annotation;
uint64_t group_lp_count = 0; int group_lp_count = 0;
// if not group_specific, then count up LPs of all preceding groups // if not group_specific, then count up LPs of all preceding groups
if (!group_wise){ if (!group_wise){
for (int g = 0; g < group_index; g++){ for (int g = 0; g < group_index; g++){
uint64_t lp_count = 0; int lp_count = 0;
const config_lpgroup_t *lpg = &lpconf.lpgroups[g]; const config_lpgroup_t *lpg = &lpconf.lpgroups[g];
for (int l = 0; l < lpg->lptypes_count; l++){ for (int l = 0; l < lpg->lptypes_count; l++){
const config_lptype_t *lpt = &lpg->lptypes[l]; const config_lptype_t *lpt = &lpg->lptypes[l];
if (strcmp(local_lp_name, lpt->name) == 0){ if (strcmp(local_lp_name, lpt->name.ptr) == 0){
// increment the count if we are ignoring annotations, // increment the count if we are ignoring annotations,
// both LPs are unannotated, or if the annotations match // both LPs are unannotated, or if the annotations match
if (!annotation_wise || cmp_anno(anno, lpt->anno)){ if (!annotation_wise || cmp_anno(anno, lpt->anno.ptr)){
lp_count += lpt->count; lp_count += lpt->count;
}