diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/fstree/xattr.c | 17 | ||||
| -rw-r--r-- | lib/util/str_table.c | 46 | 
2 files changed, 61 insertions, 2 deletions
| diff --git a/lib/fstree/xattr.c b/lib/fstree/xattr.c index 38f7703..4597d9d 100644 --- a/lib/fstree/xattr.c +++ b/lib/fstree/xattr.c @@ -102,11 +102,24 @@ static int cmp_u64(const void *lhs, const void *rhs)  void fstree_xattr_reindex(fstree_t *fs)  { +	uint32_t key_idx, value_idx; +	size_t i, index = 0;  	tree_xattr_t *it; -	size_t index = 0; -	for (it = fs->xattr; it != NULL; it = it->next) +	str_table_reset_ref_count(&fs->xattr_keys); +	str_table_reset_ref_count(&fs->xattr_values); + +	for (it = fs->xattr; it != NULL; it = it->next) {  		it->index = index++; + +		for (i = 0; i < it->num_attr; ++i) { +			key_idx = (it->ref[i] >> 32) & 0x00000000FFFFFFFF; +			value_idx = it->ref[i] & 0x00000000FFFFFFFF; + +			str_table_add_ref(&fs->xattr_keys, key_idx); +			str_table_add_ref(&fs->xattr_values, value_idx); +		} +	}  }  void fstree_xattr_deduplicate(fstree_t *fs) diff --git a/lib/util/str_table.c b/lib/util/str_table.c index a9d91e5..72579ce 100644 --- a/lib/util/str_table.c +++ b/lib/util/str_table.c @@ -128,3 +128,49 @@ const char *str_table_get_string(str_table_t *table, size_t index)  	return table->strings[index];  } + +static str_bucket_t *bucket_by_index(str_table_t *table, size_t index) +{ +	str_bucket_t *bucket = NULL; +	uint32_t hash; + +	if (index < table->num_strings) { +		hash = strhash(table->strings[index]); +		bucket = table->buckets[hash % table->num_buckets]; + +		while (bucket != NULL && bucket->index != index) +			bucket = bucket->next; +	} + +	return bucket; +} + +void str_table_reset_ref_count(str_table_t *table) +{ +	str_bucket_t *bucket; +	size_t i; + +	for (i = 0; i < table->num_buckets; ++i) { +		bucket = table->buckets[i]; + +		while (bucket != NULL) { +			bucket->refcount = 0; +			bucket = bucket->next; +		} +	} +} + +void str_table_add_ref(str_table_t *table, size_t index) +{ +	str_bucket_t *bucket = bucket_by_index(table, index); + +	if (bucket != NULL && bucket->refcount < ~((size_t)0)) +		bucket->refcount += 1; +} + +size_t str_table_get_ref_count(str_table_t *table, size_t index) +{ +	str_bucket_t *bucket = bucket_by_index(table, index); + +	return bucket != NULL ? bucket->refcount : 0; +} | 
