X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FHash.c;fp=ghc%2Frts%2FHash.c;h=05f2b191b68df77a9eff77913c5ef2fa025bbee9;hb=ed0222d6dcf80ed4b46f1199c0c4e81c58f45e9d;hp=ba0746f4085056dc1502d1f405813847f194dbf6;hpb=74c05fae75e32cd8edab8df16e0405f207351198;p=ghc-hetmet.git diff --git a/ghc/rts/Hash.c b/ghc/rts/Hash.c index ba0746f..05f2b19 100644 --- a/ghc/rts/Hash.c +++ b/ghc/rts/Hash.c @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------- - * $Id: Hash.c,v 1.7 2001/11/26 13:06:49 simonmar Exp $ + * $Id: Hash.c,v 1.8 2002/04/09 12:55:11 simonmar Exp $ * * (c) The AQUA Project, Glasgow University, 1995-1998 * (c) The GHC Team, 1999 @@ -13,7 +13,6 @@ #include "Rts.h" #include "Hash.h" #include "RtsUtils.h" -#include "Arena.h" #define HSEGSIZE 1024 /* Size of a single hash table segment */ /* Also the minimum size of a hash table */ @@ -47,7 +46,6 @@ struct hashtable { HashList **dir[HDIRSIZE]; /* Directory of segments */ HashFunction *hash; /* hash function */ CompareFunction *compare; /* key comparison function */ - Arena *arena; }; /* ----------------------------------------------------------------------------- @@ -121,6 +119,7 @@ allocSegment(HashTable *table, int segment) "allocSegment"); } + /* ----------------------------------------------------------------------------- * Expand the larger hash table by one bucket, and split one bucket * from the smaller table into two parts. Only the bucket referenced @@ -203,6 +202,39 @@ lookupHashTable(HashTable *table, StgWord key) return NULL; } +/* ----------------------------------------------------------------------------- + * We allocate the hashlist cells in large chunks to cut down on malloc + * overhead. Although we keep a free list of hashlist cells, we make + * no effort to actually return the space to the malloc arena. + * -------------------------------------------------------------------------- */ + +static HashList *freeList = NULL; + +static HashList * +allocHashList(void) +{ + HashList *hl, *p; + + if ((hl = freeList) != NULL) { + freeList = hl->next; + } else { + hl = stgMallocBytes(HCHUNK * sizeof(HashList), "allocHashList"); + + freeList = hl + 1; + for (p = freeList; p < hl + HCHUNK - 1; p++) + p->next = p + 1; + p->next = NULL; + } + return hl; +} + +static void +freeHashList(HashList *hl) +{ + hl->next = freeList; + freeList = hl; +} + void insertHashTable(HashTable *table, StgWord key, void *data) { @@ -222,7 +254,7 @@ insertHashTable(HashTable *table, StgWord key, void *data) segment = bucket / HSEGSIZE; index = bucket % HSEGSIZE; - hl = arenaAlloc(table->arena, sizeof(struct hashlist)); + hl = allocHashList(); hl->key = key; hl->data = data; @@ -250,6 +282,7 @@ removeHashTable(HashTable *table, StgWord key, void *data) table->dir[segment][index] = hl->next; else prev->next = hl->next; + freeHashList(hl); table->kcount--; return hl->data; } @@ -268,7 +301,7 @@ removeHashTable(HashTable *table, StgWord key, void *data) * -------------------------------------------------------------------------- */ void -freeHashTable( HashTable *table, void (*freeDataFun)(void *) ) +freeHashTable(HashTable *table, void (*freeDataFun)(void *) ) { long segment; long index; @@ -278,23 +311,21 @@ freeHashTable( HashTable *table, void (*freeDataFun)(void *) ) /* The last bucket with something in it is table->max + table->split - 1 */ segment = (table->max + table->split - 1) / HSEGSIZE; index = (table->max + table->split - 1) % HSEGSIZE; - + while (segment >= 0) { - if (freeDataFun != NULL) { - while (index >= 0) { - for (hl = table->dir[segment][index]; hl != NULL; hl = next) { - next = hl->next; + while (index >= 0) { + for (hl = table->dir[segment][index]; hl != NULL; hl = next) { + next = hl->next; + if (freeDataFun != NULL) (*freeDataFun)(hl->data); - } - index--; + freeHashList(hl); } + index--; } free(table->dir[segment]); segment--; index = HSEGSIZE - 1; } - - arenaFree(table->arena); free(table); } @@ -311,8 +342,6 @@ allocHashTable_(HashFunction *hash, CompareFunction *compare) table = stgMallocBytes(sizeof(HashTable),"allocHashTable"); - table->arena = newArena(); - allocSegment(table, 0); for (hb = table->dir[0]; hb < table->dir[0] + HSEGSIZE; hb++)