dbghelp: Speed up source string creation (by using rb trees).

This commit is contained in:
Eric Pouech 2011-01-08 14:15:31 +01:00 committed by Alexandre Julliard
parent cbd5811e90
commit c7c8c0dea7
3 changed files with 56 additions and 9 deletions

View File

@ -31,6 +31,7 @@
#include "winnls.h" #include "winnls.h"
#include "wine/list.h" #include "wine/list.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/rbtree.h"
#include "cvconst.h" #include "cvconst.h"
@ -348,6 +349,7 @@ struct module_format
} u; } u;
}; };
extern const struct wine_rb_functions source_rb_functions;
struct module struct module
{ {
struct process* process; struct process* process;
@ -382,6 +384,7 @@ struct module
unsigned sources_used; unsigned sources_used;
unsigned sources_alloc; unsigned sources_alloc;
char* sources; char* sources;
struct wine_rb_tree sources_offsets_tree;
}; };
struct process struct process

View File

@ -189,6 +189,7 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
module->sources_used = 0; module->sources_used = 0;
module->sources_alloc = 0; module->sources_alloc = 0;
module->sources = 0; module->sources = 0;
wine_rb_init(&module->sources_offsets_tree, &source_rb_functions);
return module; return module;
} }
@ -638,6 +639,7 @@ BOOL module_remove(struct process* pcs, struct module* module)
} }
hash_table_destroy(&module->ht_symbols); hash_table_destroy(&module->ht_symbols);
hash_table_destroy(&module->ht_types); hash_table_destroy(&module->ht_types);
wine_rb_destroy(&module->sources_offsets_tree, NULL, NULL);
HeapFree(GetProcessHeap(), 0, module->sources); HeapFree(GetProcessHeap(), 0, module->sources);
HeapFree(GetProcessHeap(), 0, module->addr_sorttab); HeapFree(GetProcessHeap(), 0, module->addr_sorttab);
pool_destroy(&module->pool); pool_destroy(&module->pool);

View File

@ -29,21 +29,55 @@
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
static struct module* rb_module;
struct source_rb
{
struct wine_rb_entry entry;
unsigned source;
};
static void *source_rb_alloc(size_t size)
{
return HeapAlloc(GetProcessHeap(), 0, size);
}
static void *source_rb_realloc(void *ptr, size_t size)
{
return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
}
static void source_rb_free(void *ptr)
{
HeapFree(GetProcessHeap(), 0, ptr);
}
static int source_rb_compare(const void *key, const struct wine_rb_entry *entry)
{
const struct source_rb *t = WINE_RB_ENTRY_VALUE(entry, const struct source_rb, entry);
return strcmp((const char*)key, rb_module->sources + t->source);
}
const struct wine_rb_functions source_rb_functions =
{
source_rb_alloc,
source_rb_realloc,
source_rb_free,
source_rb_compare,
};
/****************************************************************** /******************************************************************
* source_find * source_find
* *
* check whether a source file has already been stored * check whether a source file has already been stored
*/ */
static unsigned source_find(const struct module* module, const char* name) static unsigned source_find(const char* name)
{ {
char* ptr = module->sources; struct wine_rb_entry* e;
while (*ptr) e = wine_rb_get(&rb_module->sources_offsets_tree, name);
{ if (!e) return -1;
if (strcmp(ptr, name) == 0) return ptr - module->sources; return WINE_RB_ENTRY_VALUE(e, struct source_rb, entry)->source;
ptr += strlen(ptr) + 1;
}
return (unsigned)-1;
} }
/****************************************************************** /******************************************************************
@ -71,10 +105,13 @@ unsigned source_new(struct module* module, const char* base, const char* name)
if (tmp[bsz - 1] != '/') tmp[bsz++] = '/'; if (tmp[bsz - 1] != '/') tmp[bsz++] = '/';
strcpy(&tmp[bsz], name); strcpy(&tmp[bsz], name);
} }
if (!module->sources || (ret = source_find(module, full)) == (unsigned)-1) rb_module = module;
if (!module->sources || (ret = source_find(full)) == (unsigned)-1)
{ {
char* new; char* new;
int len = strlen(full) + 1; int len = strlen(full) + 1;
struct source_rb* rb;
if (module->sources_used + len + 1 > module->sources_alloc) if (module->sources_used + len + 1 > module->sources_alloc)
{ {
if (!module->sources) if (!module->sources)
@ -96,6 +133,11 @@ unsigned source_new(struct module* module, const char* base, const char* name)
memcpy(module->sources + module->sources_used, full, len); memcpy(module->sources + module->sources_used, full, len);
module->sources_used += len; module->sources_used += len;
module->sources[module->sources_used] = '\0'; module->sources[module->sources_used] = '\0';
if ((rb = pool_alloc(&module->pool, sizeof(*rb))))
{
rb->source = ret;
wine_rb_put(&module->sources_offsets_tree, full, &rb->entry);
}
} }
done: done:
HeapFree(GetProcessHeap(), 0, tmp); HeapFree(GetProcessHeap(), 0, tmp);