Author: akhaldi
Date: Sun Jul 28 20:37:51 2013
New Revision: 59593
URL:
http://svn.reactos.org/svn/reactos?rev=59593&view=rev
Log:
[RSYM]
* Speedup FindOrAddString(). Brought to you by Art Yerkes (arty).
Modified:
trunk/reactos/tools/rsym/rsym.c
Modified: trunk/reactos/tools/rsym/rsym.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/rsym/rsym.c?rev=5959…
==============================================================================
--- trunk/reactos/tools/rsym/rsym.c [iso-8859-1] (original)
+++ trunk/reactos/tools/rsym/rsym.c [iso-8859-1] Sun Jul 28 20:37:51 2013
@@ -33,6 +33,83 @@
#define MAX_PATH 260
#define MAX_SYM_NAME 2000
+struct StringEntry
+{
+ struct StringEntry *Next;
+ ULONG Offset;
+ char *String;
+};
+
+struct StringHashTable
+{
+ ULONG TableSize;
+ struct StringEntry **Table;
+};
+
+/* This is the famous DJB hash */
+static unsigned int
+ComputeDJBHash(const char *name)
+{
+ unsigned int val = 5381;
+ int i = 0;
+
+ for (i = 0; name[i]; i++)
+ {
+ val = (33 * val) + name[i];
+ }
+
+ return val;
+}
+
+static void
+AddStringToHash(struct StringHashTable *StringTable,
+ unsigned int hash,
+ ULONG Offset,
+ char *StringPtr)
+{
+ struct StringEntry *entry = calloc(1, sizeof(struct StringEntry));
+ entry->Offset = Offset;
+ entry->String = StringPtr;
+ entry->Next = StringTable->Table[hash];
+ StringTable->Table[hash] = entry;
+}
+
+static void
+StringHashTableInit(struct StringHashTable *StringTable,
+ ULONG StringsLength,
+ char *StringsBase)
+{
+ char *Start = StringsBase;
+ char *End = StringsBase + StringsLength;
+ StringTable->TableSize = 1024;
+ StringTable->Table = calloc(1024, sizeof(struct StringEntry *));
+ while (Start < End)
+ {
+ AddStringToHash(StringTable,
+ ComputeDJBHash(Start) % StringTable->TableSize,
+ Start - StringsBase,
+ Start);
+ Start += strlen(Start) + 1;
+ }
+}
+
+static void
+StringHashTableFree(struct StringHashTable *StringTable)
+{
+ int i;
+ struct StringEntry *entry;
+ for (i = 0; i < StringTable->TableSize; i++)
+ {
+ while ((entry = StringTable->Table[i]))
+ {
+ entry = entry->Next;
+ free(StringTable->Table[i]);
+ StringTable->Table[i] = entry;
+ }
+ }
+ free(StringTable->Table);
+}
+
static int
CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2)
{
@@ -112,26 +189,32 @@
}
static ULONG
-FindOrAddString(char *StringToFind, ULONG *StringsLength, void *StringsBase)
-{
- char *Search, *End;
-
- Search = (char *)StringsBase;
- End = Search + *StringsLength;
-
- while (Search < End)
- {
- if (strcmp(Search, StringToFind) == 0)
- {
- return Search - (char *)StringsBase;
- }
- Search += strlen(Search) + 1;
- }
-
- strcpy(Search, StringToFind);
- *StringsLength += strlen(StringToFind) + 1;
-
- return Search - (char *)StringsBase;
+FindOrAddString(struct StringHashTable *StringTable,
+ char *StringToFind,
+ ULONG *StringsLength,
+ void *StringsBase)
+{
+ unsigned int hash = ComputeDJBHash(StringToFind) % StringTable->TableSize;
+ struct StringEntry *entry = StringTable->Table[hash];
+
+ while (entry && strcmp(entry->String, StringToFind))
+ entry = entry->Next;
+
+ if (entry)
+ {
+ return entry->Offset;
+ }
+ else
+ {
+ char *End = (char *)StringsBase + *StringsLength;
+
+ strcpy(End, StringToFind);
+ *StringsLength += strlen(StringToFind) + 1;
+
+ AddStringToHash(StringTable, hash, End - (char *)StringsBase, End);
+
+ return End - (char *)StringsBase;
+ }
}
static int
@@ -150,6 +233,7 @@
ULONG NameLen;
char FuncName[256];
PROSSYM_ENTRY Current;
+ struct StringHashTable StringHash;
StabEntry = StabSymbolsBase;
Count = StabSymbolsLength / sizeof(STAB_ENTRY);
@@ -170,6 +254,8 @@
}
Current = *SymbolsBase;
memset(Current, 0, sizeof(*Current));
+
+ StringHashTableInit(&StringHash, *StringsLength, (char *)StringsBase);
LastFunctionAddress = 0;
for (i = 0; i < Count; i++)
@@ -206,8 +292,8 @@
First = 0;
Current->Address = Address;
}
- Current->FileOffset = FindOrAddString((char *)StabStringsBase
- + StabEntry[i].n_strx,
+ Current->FileOffset = FindOrAddString(&StringHash,
+ (char *)StabStringsBase +
StabEntry[i].n_strx,
StringsLength,
StringsBase);
break;
@@ -236,7 +322,8 @@
}
memcpy(FuncName, Name, NameLen);
FuncName[NameLen] = '\0';
- Current->FunctionOffset = FindOrAddString(FuncName,
+ Current->FunctionOffset = FindOrAddString(&StringHash,
+ FuncName,
StringsLength,
StringsBase);
Current->SourceLine = 0;
@@ -265,6 +352,8 @@
qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const
void *)) CompareSymEntry);
+ StringHashTableFree(&StringHash);
+
return 0;
}
@@ -281,6 +370,7 @@
char FuncName[256], FileName[1024];
char *p;
PROSSYM_ENTRY Current;
+ struct StringHashTable StringHash;
CoffEntry = (PCOFF_SYMENT) CoffSymbolsBase;
Count = CoffSymbolsLength / sizeof(COFF_SYMENT);
@@ -293,6 +383,8 @@
}
*SymbolsCount = 0;
Current = *SymbolsBase;
+
+ StringHashTableInit(&StringHash, *StringsLength, (char*)StringsBase);
for (i = 0; i < Count; i++)
{
@@ -319,6 +411,7 @@
{
free(*SymbolsBase);
fprintf(stderr, "Function name too long\n");
+ StringHashTableFree(&StringHash);
return 1;
}
strcpy(FuncName, (char *) CoffStringsBase + CoffEntry[i].e.e.e_offset);
@@ -336,7 +429,8 @@
*p = '\0';
}
p = ('_' == FuncName[0] || '@' == FuncName[0] ? FuncName + 1
: FuncName);
- Current->FunctionOffset = FindOrAddString(p,
+ Current->FunctionOffset = FindOrAddString(&StringHash,
+ p,
StringsLength,
StringsBase);
Current->SourceLine = 0;
@@ -348,6 +442,8 @@
*SymbolsCount = (Current - *SymbolsBase + 1);
qsort(*SymbolsBase, *SymbolsCount, sizeof(ROSSYM_ENTRY), (int (*)(const void *, const
void *)) CompareSymEntry);
+
+ StringHashTableFree(&StringHash);
return 0;
}
@@ -370,21 +466,6 @@
DWORD module_base;
struct DbgHelpLineEntry *lastLineEntry;
};
-
-/* This is the famous DJB hash */
-static unsigned int
-ComputeDJBHash(const char *name)
-{
- unsigned int val = 5381;
- int i = 0;
-
- for (i = 0; name[i]; i++)
- {
- val = (33 * val) + name[i];
- }
-
- return val;
-}
static struct DbgHelpLineEntry*
DbgHelpAddLineEntry(struct DbgHelpStringTab *tab)