Commit 2af73182 authored by Nikias Bassen's avatar Nikias Bassen

bplist: Speed up plist_to_bin conversion for large plists

Using a better hashing algorithm and a larger hash table the conversion
is A LOT faster when processing large plists. Thanks to Xiao Deng for
reporting this issue and suggesting a fix.
parent 6ab7e301
...@@ -735,7 +735,7 @@ static unsigned int plist_data_hash(const void* key) ...@@ -735,7 +735,7 @@ static unsigned int plist_data_hash(const void* key)
case PLIST_KEY: case PLIST_KEY:
case PLIST_STRING: case PLIST_STRING:
buff = data->strval; buff = data->strval;
size = strlen(buff); size = data->length;
break; break;
case PLIST_DATA: case PLIST_DATA:
case PLIST_ARRAY: case PLIST_ARRAY:
...@@ -752,9 +752,12 @@ static unsigned int plist_data_hash(const void* key) ...@@ -752,9 +752,12 @@ static unsigned int plist_data_hash(const void* key)
break; break;
} }
//now perform hash // now perform hash using djb2 hashing algorithm
for (i = 0; i < size; buff++, i++) // see: http://www.cse.yorku.ca/~oz/hash.html
hash = hash << 7 ^ (*buff); hash += 5381;
for (i = 0; i < size; buff++, i++) {
hash = ((hash << 5) + hash) + *buff;
}
return hash; return hash;
} }
......
...@@ -24,7 +24,7 @@ hashtable_t* hash_table_new(hash_func_t hash_func, compare_func_t compare_func) ...@@ -24,7 +24,7 @@ hashtable_t* hash_table_new(hash_func_t hash_func, compare_func_t compare_func)
{ {
hashtable_t* ht = (hashtable_t*)malloc(sizeof(hashtable_t)); hashtable_t* ht = (hashtable_t*)malloc(sizeof(hashtable_t));
int i; int i;
for (i = 0; i < 256; i++) { for (i = 0; i < 4096; i++) {
ht->entries[i] = NULL; ht->entries[i] = NULL;
} }
ht->count = 0; ht->count = 0;
...@@ -38,7 +38,7 @@ void hash_table_destroy(hashtable_t *ht) ...@@ -38,7 +38,7 @@ void hash_table_destroy(hashtable_t *ht)
if (!ht) return; if (!ht) return;
int i = 0; int i = 0;
for (i = 0; i < 256; i++) { for (i = 0; i < 4096; i++) {
if (ht->entries[i]) { if (ht->entries[i]) {
hashentry_t* e = ht->entries[i]; hashentry_t* e = ht->entries[i];
while (e) { while (e) {
...@@ -58,7 +58,7 @@ void hash_table_insert(hashtable_t* ht, void *key, void *value) ...@@ -58,7 +58,7 @@ void hash_table_insert(hashtable_t* ht, void *key, void *value)
unsigned int hash = ht->hash_func(key); unsigned int hash = ht->hash_func(key);
int idx0 = hash & 0xFF; int idx0 = hash & 0xFFF;
// get the idx0 list // get the idx0 list
hashentry_t* e = ht->entries[idx0]; hashentry_t* e = ht->entries[idx0];
...@@ -93,7 +93,7 @@ void* hash_table_lookup(hashtable_t* ht, void *key) ...@@ -93,7 +93,7 @@ void* hash_table_lookup(hashtable_t* ht, void *key)
if (!ht || !key) return NULL; if (!ht || !key) return NULL;
unsigned int hash = ht->hash_func(key); unsigned int hash = ht->hash_func(key);
int idx0 = hash & 0xFF; int idx0 = hash & 0xFFF;
hashentry_t* e = ht->entries[idx0]; hashentry_t* e = ht->entries[idx0];
while (e) { while (e) {
......
...@@ -32,7 +32,7 @@ typedef unsigned int(*hash_func_t)(const void* key); ...@@ -32,7 +32,7 @@ typedef unsigned int(*hash_func_t)(const void* key);
typedef int (*compare_func_t)(const void *a, const void *b); typedef int (*compare_func_t)(const void *a, const void *b);
typedef struct hashtable_t { typedef struct hashtable_t {
hashentry_t *entries[256]; hashentry_t *entries[4096];
size_t count; size_t count;
hash_func_t hash_func; hash_func_t hash_func;
compare_func_t compare_func; compare_func_t compare_func;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment