# HG changeset patch # User Guido Berhoerster # Date 1486242375 -3600 # Node ID 1cc98a5677d9e444e85faebc3e909c004e186615 # Parent 5cd0debdb7d89e939b4b99cd29b2f02ccee3a643 Refactor the creation of the record and group list Simplify the list allocation. diff -r 5cd0debdb7d8 -r 1cc98a5677d9 pwfile.c --- a/pwfile.c Sat Feb 04 21:04:47 2017 +0100 +++ b/pwfile.c Sat Feb 04 22:06:15 2017 +0100 @@ -38,8 +38,6 @@ #include "pwfile.h" #include "util.h" -#define MIN_ARRAY_SIZE 1024 - struct record_id_entry { RB_ENTRY(record_id_entry) record_id_entry; unsigned int id; @@ -166,9 +164,8 @@ pwfile_read_file(struct pwm_ctx *ctx, FILE *fp) { struct pws3_record *pws3_record; + size_t record_list_len = 0; struct pws3_record **pws3_record_list; - size_t record_list_size = MIN_ARRAY_SIZE; - size_t record_list_len = 0; size_t i; struct pws3_field *uuid_field; const unsigned char *uuid; @@ -183,20 +180,20 @@ record_id_tree_clear(ctx->record_id_tree); /* sort records by group and title */ + for (pws3_record = pws3_file_first_record(ctx->file); + pws3_record != NULL; + pws3_record = pws3_file_next_record(ctx->file, pws3_record)) { + record_list_len++; + } pws3_record_list = xmalloc(sizeof (struct pws3_record *) * - record_list_size); - for (pws3_record = pws3_file_first_record(ctx->file); - pws3_record != NULL; pws3_record = pws3_file_next_record(ctx->file, - pws3_record)) { - if (record_list_len == record_list_size) { - record_list_size *= 2; - pws3_record_list = xrealloc(pws3_record_list, - sizeof (struct pws3_record *) * record_list_size); - } - pws3_record_list[record_list_len++] = pws3_record; + record_list_len); + for (pws3_record = pws3_file_first_record(ctx->file), i = 0; + pws3_record != NULL; + pws3_record = pws3_file_next_record(ctx->file, pws3_record)) { + pws3_record_list[i++] = pws3_record; } - qsort(pws3_record_list, record_list_len, sizeof (struct pws3_record *), - pws_record_cmp); + qsort(pws3_record_list, record_list_len, + sizeof (struct pws3_record *), pws_record_cmp); /* build the tree of record IDs */ for (i = 0; i < record_list_len; i++) { @@ -409,31 +406,34 @@ pwfile_create_list(struct pwm_ctx *ctx) { union list_item **list; - size_t list_size = MIN_ARRAY_SIZE; - size_t list_len = 0; struct record_id_entry *entry; - union list_item *item; + size_t list_capacity = 0; + struct pws3_field *empty_group_field; struct pws3_record *pws3_record; struct pws3_field *group_field; const char *group; struct pws3_field *title_field; const char *title; + union list_item *item; + size_t list_len = 0; size_t i; - size_t records_len; - const char *prev_group = ""; - struct pws3_field *empty_group_field; - - list = xmalloc(sizeof (union list_item *) * list_size); - list[0] = NULL; + size_t j; + const char *prev_group = NULL; - /* build list of records and sort it by group and title */ RB_FOREACH(entry, record_id_tree, ctx->record_id_tree) { - if (list_len == list_size - 1) { - list_size *= 2; - list = xrealloc(list, sizeof (union list_item *) * - list_size); - } + list_capacity++; + } + list_capacity *= 2; /* maximum number of group items */ + for (empty_group_field = pws3_file_first_empty_group(ctx->file); + empty_group_field != NULL; + empty_group_field = pws3_file_next_empty_group(ctx->file, + empty_group_field)) { + list_capacity++; + } + list_capacity++; /* terminating NULL */ + list = xmalloc(sizeof (union list_item *) * list_capacity); + RB_FOREACH(entry, record_id_tree, ctx->record_id_tree) { pws3_record = pws3_file_get_record(ctx->file, entry->uuid); group_field = pws3_record_get_field(pws3_record, PWS3_RECORD_FIELD_GROUP); @@ -453,56 +453,43 @@ sizeof (item->record.uuid)); list[list_len++] = item; - list[list_len] = NULL; } + /* sort records by group and title in order to find unqiue groups */ qsort(list, list_len, sizeof (union list_item *), list_item_cmp); - /* build list of groups by comparing the groups of the sorted records */ - for (i = 0, records_len = list_len; i < records_len; i++) { - if (list_len == list_size - 1) { - list_size *= 1.5; - list = xrealloc(list, sizeof (union list_item *) * - list_size); - } - - group = (list[i]->record.group != NULL) ? - list[i]->record.group : ""; - if (strcmp(prev_group, group) != 0) { + /* add groups based on the sorted records */ + for (i = 0, j = list_len; i < list_len; i++) { + group = list[i]->record.group; + if ((group != NULL) && ((prev_group == NULL) || + (strcmp(prev_group, group) != 0))) { item = xmalloc(sizeof (union list_item)); - item->record.type = ITEM_TYPE_GROUP; - item->record.group = (group != NULL) ? xstrdup(group) : + item->group.type = ITEM_TYPE_GROUP; + item->group.group = (group != NULL) ? xstrdup(group) : NULL; - - list[list_len++] = item; - list[list_len] = NULL; - + list[j++] = item; prev_group = group; } } + list_len = j; /* add empty groups to the list */ for (empty_group_field = pws3_file_first_empty_group(ctx->file); empty_group_field != NULL; empty_group_field = pws3_file_next_empty_group(ctx->file, empty_group_field)) { - if (list_len == list_size - 1) { - list_size *= 1.5; - list = xrealloc(list, sizeof (union list_item *) * - list_size); - } - group = pws3_field_get_text(empty_group_field); item = xmalloc(sizeof (union list_item)); - item->record.type = ITEM_TYPE_GROUP; - item->record.group = xstrdup(group); + item->group.type = ITEM_TYPE_GROUP; + item->group.group = xstrdup(group); list[list_len++] = item; - list[list_len] = NULL; } - list_size = list_len + 2; - list = xrealloc(list, sizeof (union list_item *) * list_size); + /* terminate the list */ + list[list_len] = NULL; + list = xrealloc(list, sizeof (union list_item *) * (list_len + 1)); + /* sort the final list by group and title */ qsort(list, list_len, sizeof (union list_item *), list_item_cmp);