projects/pwm

changeset 3:1cc98a5677d9

Refactor the creation of the record and group list

Simplify the list allocation.
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Sat Feb 04 22:06:15 2017 +0100 (2017-02-04)
parents 5cd0debdb7d8
children b5c4267a7182
files pwfile.c
line diff
     1.1 --- a/pwfile.c	Sat Feb 04 21:04:47 2017 +0100
     1.2 +++ b/pwfile.c	Sat Feb 04 22:06:15 2017 +0100
     1.3 @@ -38,8 +38,6 @@
     1.4  #include "pwfile.h"
     1.5  #include "util.h"
     1.6  
     1.7 -#define	MIN_ARRAY_SIZE	1024
     1.8 -
     1.9  struct record_id_entry {
    1.10  	RB_ENTRY(record_id_entry) record_id_entry;
    1.11  	unsigned int	id;
    1.12 @@ -166,9 +164,8 @@
    1.13  pwfile_read_file(struct pwm_ctx *ctx, FILE *fp)
    1.14  {
    1.15  	struct pws3_record *pws3_record;
    1.16 +	size_t		record_list_len = 0;
    1.17  	struct pws3_record **pws3_record_list;
    1.18 -	size_t		record_list_size = MIN_ARRAY_SIZE;
    1.19 -	size_t		record_list_len = 0;
    1.20  	size_t		i;
    1.21  	struct pws3_field *uuid_field;
    1.22  	const unsigned char *uuid;
    1.23 @@ -183,20 +180,20 @@
    1.24  	record_id_tree_clear(ctx->record_id_tree);
    1.25  
    1.26  	/* sort records by group and title */
    1.27 +	for (pws3_record = pws3_file_first_record(ctx->file);
    1.28 +	    pws3_record != NULL;
    1.29 +	    pws3_record = pws3_file_next_record(ctx->file, pws3_record)) {
    1.30 +		record_list_len++;
    1.31 +	}
    1.32  	pws3_record_list = xmalloc(sizeof (struct pws3_record *) *
    1.33 -	    record_list_size);
    1.34 -	for (pws3_record = pws3_file_first_record(ctx->file);
    1.35 -	    pws3_record != NULL; pws3_record = pws3_file_next_record(ctx->file,
    1.36 -	    pws3_record)) {
    1.37 -		if (record_list_len == record_list_size) {
    1.38 -			record_list_size *= 2;
    1.39 -			pws3_record_list = xrealloc(pws3_record_list,
    1.40 -			    sizeof (struct pws3_record *) * record_list_size);
    1.41 -		}
    1.42 -		pws3_record_list[record_list_len++] = pws3_record;
    1.43 +	    record_list_len);
    1.44 +	for (pws3_record = pws3_file_first_record(ctx->file), i = 0;
    1.45 +	    pws3_record != NULL;
    1.46 +	    pws3_record = pws3_file_next_record(ctx->file, pws3_record)) {
    1.47 +		pws3_record_list[i++] = pws3_record;
    1.48  	}
    1.49 -	qsort(pws3_record_list, record_list_len, sizeof (struct pws3_record *),
    1.50 -	    pws_record_cmp);
    1.51 +	qsort(pws3_record_list, record_list_len,
    1.52 +	    sizeof (struct pws3_record *), pws_record_cmp);
    1.53  
    1.54  	/* build the tree of record IDs */
    1.55  	for (i = 0; i < record_list_len; i++) {
    1.56 @@ -409,31 +406,34 @@
    1.57  pwfile_create_list(struct pwm_ctx *ctx)
    1.58  {
    1.59  	union list_item	**list;
    1.60 -	size_t		list_size = MIN_ARRAY_SIZE;
    1.61 -	size_t		list_len = 0;
    1.62  	struct record_id_entry *entry;
    1.63 -	union list_item	*item;
    1.64 +	size_t		list_capacity = 0;
    1.65 +	struct pws3_field *empty_group_field;
    1.66  	struct pws3_record *pws3_record;
    1.67  	struct pws3_field *group_field;
    1.68  	const char	*group;
    1.69  	struct pws3_field *title_field;
    1.70  	const char	*title;
    1.71 +	union list_item	*item;
    1.72 +	size_t		list_len = 0;
    1.73  	size_t		i;
    1.74 -	size_t		records_len;
    1.75 -	const char	*prev_group = "";
    1.76 -	struct pws3_field *empty_group_field;
    1.77 +	size_t		j;
    1.78 +	const char	*prev_group = NULL;
    1.79  
    1.80 -	list = xmalloc(sizeof (union list_item *) * list_size);
    1.81 -	list[0] = NULL;
    1.82 +	RB_FOREACH(entry, record_id_tree, ctx->record_id_tree) {
    1.83 +		list_capacity++;
    1.84 +	}
    1.85 +	list_capacity *= 2; /* maximum number of group items */
    1.86 +	for (empty_group_field = pws3_file_first_empty_group(ctx->file);
    1.87 +	    empty_group_field != NULL;
    1.88 +	    empty_group_field = pws3_file_next_empty_group(ctx->file,
    1.89 +	    empty_group_field)) {
    1.90 +		list_capacity++;
    1.91 +	}
    1.92 +	list_capacity++; /* terminating NULL */
    1.93 +	list = xmalloc(sizeof (union list_item *) * list_capacity);
    1.94  
    1.95 -	/* build list of records and sort it by group and title */
    1.96  	RB_FOREACH(entry, record_id_tree, ctx->record_id_tree) {
    1.97 -		if (list_len == list_size - 1) {
    1.98 -			list_size *= 2;
    1.99 -			list = xrealloc(list, sizeof (union list_item *) *
   1.100 -			    list_size);
   1.101 -		}
   1.102 -
   1.103  		pws3_record = pws3_file_get_record(ctx->file, entry->uuid);
   1.104  		group_field = pws3_record_get_field(pws3_record,
   1.105  		    PWS3_RECORD_FIELD_GROUP);
   1.106 @@ -453,56 +453,43 @@
   1.107  		    sizeof (item->record.uuid));
   1.108  
   1.109  		list[list_len++] = item;
   1.110 -		list[list_len] = NULL;
   1.111  	}
   1.112 +	/* sort records by group and title in order to find unqiue groups */
   1.113  	qsort(list, list_len, sizeof (union list_item *), list_item_cmp);
   1.114  
   1.115 -	/* build list of groups by comparing the groups of the sorted records */
   1.116 -	for (i = 0, records_len = list_len; i < records_len; i++) {
   1.117 -		if (list_len == list_size - 1) {
   1.118 -			list_size *= 1.5;
   1.119 -			list = xrealloc(list, sizeof (union list_item *) *
   1.120 -			    list_size);
   1.121 -		}
   1.122 -
   1.123 -		group = (list[i]->record.group != NULL) ?
   1.124 -		    list[i]->record.group : "";
   1.125 -		if (strcmp(prev_group, group) != 0) {
   1.126 +	/* add groups based on the sorted records */
   1.127 +	for (i = 0, j = list_len; i < list_len; i++) {
   1.128 +		group = list[i]->record.group;
   1.129 +		if ((group != NULL) && ((prev_group == NULL) ||
   1.130 +		    (strcmp(prev_group, group) != 0))) {
   1.131  			item = xmalloc(sizeof (union list_item));
   1.132 -			item->record.type = ITEM_TYPE_GROUP;
   1.133 -			item->record.group = (group != NULL) ? xstrdup(group) :
   1.134 +			item->group.type = ITEM_TYPE_GROUP;
   1.135 +			item->group.group = (group != NULL) ? xstrdup(group) :
   1.136  			    NULL;
   1.137 -
   1.138 -			list[list_len++] = item;
   1.139 -			list[list_len] = NULL;
   1.140 -
   1.141 +			list[j++] = item;
   1.142  			prev_group = group;
   1.143  		}
   1.144  	}
   1.145 +	list_len = j;
   1.146  
   1.147  	/* add empty groups to the list */
   1.148  	for (empty_group_field = pws3_file_first_empty_group(ctx->file);
   1.149  	    empty_group_field != NULL;
   1.150  	    empty_group_field = pws3_file_next_empty_group(ctx->file,
   1.151  	    empty_group_field)) {
   1.152 -		if (list_len == list_size - 1) {
   1.153 -			list_size *= 1.5;
   1.154 -			list = xrealloc(list, sizeof (union list_item *) *
   1.155 -			    list_size);
   1.156 -		}
   1.157 -
   1.158  		group = pws3_field_get_text(empty_group_field);
   1.159  
   1.160  		item = xmalloc(sizeof (union list_item));
   1.161 -		item->record.type = ITEM_TYPE_GROUP;
   1.162 -		item->record.group = xstrdup(group);
   1.163 +		item->group.type = ITEM_TYPE_GROUP;
   1.164 +		item->group.group = xstrdup(group);
   1.165  
   1.166  		list[list_len++] = item;
   1.167 -		list[list_len] = NULL;
   1.168  	}
   1.169  
   1.170 -	list_size = list_len + 2;
   1.171 -	list = xrealloc(list, sizeof (union list_item *) * list_size);
   1.172 +	/* terminate the list */
   1.173 +	list[list_len] = NULL;
   1.174 +	list = xrealloc(list, sizeof (union list_item *) * (list_len + 1));
   1.175 +
   1.176  	/* sort the final list by group and title */
   1.177  	qsort(list, list_len, sizeof (union list_item *), list_item_cmp);
   1.178