}
unsigned int crc32_add_string(unsigned int checksum, const char*s)
{
+ if(!crc32)
+ crc32_init();
if(!s)
return checksum;
while(*s) {
- checksum = crc32_add_byte(checksum, *s);
+ checksum = checksum>>8 ^ crc32[(*s^checksum)&0xff];
s++;
}
return checksum;
return h->num;
}
-void* dict_lookup(dict_t*h, const void*key)
+static inline dictentry_t* dict_do_lookup(dict_t*h, const void*key)
{
- if(!h->num)
+ if(!h->num) {
return 0;
+ }
unsigned int ohash = h->key_type->hash(key);
unsigned int hash = ohash % h->hashsize;
/* check first entry for match */
dictentry_t*e = h->slots[hash];
if(e && h->key_type->equals(e->key, key)) {
- return e->data;
+ return e;
} else if(e) {
e = e->next;
}
dict_expand(h, newsize);
hash = ohash % h->hashsize;
e = h->slots[hash];
+ if(e && h->key_type->equals(e->key, key)) {
+ // omit move to front
+ return e;
+ } else if(e) {
+ e = e->next;
+ }
}
/* check subsequent entries for a match */
+ dictentry_t*last = h->slots[hash];
while(e) {
if(h->key_type->equals(e->key, key)) {
- return e->data;
+ /* move to front- makes a difference of about 10% in most applications */
+ last->next = e->next;
+ e->next = h->slots[hash];
+ h->slots[hash] = e;
+ return e;
}
+ last=e;
e = e->next;
}
return 0;
}
+void* dict_lookup(dict_t*h, const void*key)
+{
+ dictentry_t*e = dict_do_lookup(h, key);
+ if(e)
+ return e->data;
+ return 0;
+}
+char dict_contains(dict_t*h, const void*key)
+{
+ dictentry_t*e = dict_do_lookup(h, key);
+ return !!e;
+}
+
char dict_del(dict_t*h, const void*key)
{
if(!h->num)
}
}
-void dict_free_all(dict_t*h, void (*freeFunction)(void*))
+void dict_free_all(dict_t*h, char free_keys, void (*free_data_function)(void*))
{
int t;
for(t=0;t<h->hashsize;t++) {
dictentry_t*e = h->slots[t];
while(e) {
dictentry_t*next = e->next;
- h->key_type->free(e->key);
- if(freeFunction) {
- freeFunction(e->data);
+ if(free_keys) {
+ h->key_type->free(e->key);
+ }
+ if(free_data_function) {
+ free_data_function(e->data);
}
memset(e, 0, sizeof(dictentry_t));
rfx_free(e);
memset(h, 0, sizeof(dict_t));
}
+void dict_clear_shallow(dict_t*h)
+{
+ dict_free_all(h, 0, 0);
+}
+
void dict_clear(dict_t*h)
{
- dict_free_all(h, 0);
+ dict_free_all(h, 1, 0);
+}
+
+void dict_destroy_shallow(dict_t*dict)
+{
+ dict_clear_shallow(dict);
+ rfx_free(dict);
}
void dict_destroy(dict_t*dict)
void map_clear(map_t*map)
{
map_internal_t*m = (map_internal_t*)map->internal;
- dict_free_all(&m->d, freestring);
+ dict_free_all(&m->d, 1, freestring);
rfx_free(m);
}
void map_destroy(map_t*map)
return 0;
return l->info[0].size;
}
+void list_concat_(void*_l1, void*_l2)
+{
+ commonlist_t**l1 = (commonlist_t**)_l1;
+ commonlist_t**l2 = (commonlist_t**)_l2;
+
+ if(!*l1) {
+ *l1 = *l2;
+ } else if(*l2) {
+ (*l1)->info[0].last->next = *l2;
+ (*l1)->info[0].last = (*l2)->info[0].last;
+ (*l1)->info[0].size += (*l2)->info[0].size;
+ }
+ *l2 = 0;
+}
void list_append_(void*_list, void*entry)
{
commonlist_t**list = (commonlist_t**)_list;