From e2fb3305752b3a9a8d995b474291b3c3d271688a Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Wed, 22 Aug 2012 18:57:13 -0500 Subject: [PATCH] avoid fixed sized hash tables. --- C/qlyr.c | 16 +++++------ C/qlyw.c | 78 ++++++++++++++++++++++++++++++++++++++--------------- H/hlocals.h | 2 +- H/qly.h | 1 - misc/LOCALS | 2 +- 5 files changed, 67 insertions(+), 32 deletions(-) diff --git a/C/qlyr.c b/C/qlyr.c index 2f9412460..4bd13f121 100644 --- a/C/qlyr.c +++ b/C/qlyr.c @@ -320,16 +320,8 @@ static void InitHash(void) { CACHE_REGS - LOCAL_ImportFunctorHashTableSize = EXPORT_FUNCTOR_TABLE_SIZE; - LOCAL_ImportFunctorHashChain = (import_functor_hash_entry_t **)calloc(1, sizeof(import_functor_hash_entry_t *)* LOCAL_ImportFunctorHashTableSize); - LOCAL_ImportAtomHashTableSize = EXPORT_ATOM_TABLE_SIZE; - LOCAL_ImportAtomHashChain = (import_atom_hash_entry_t **)calloc(1, sizeof(import_atom_hash_entry_t *)* LOCAL_ImportAtomHashTableSize); LOCAL_ImportOPCODEHashTableSize = EXPORT_OPCODE_TABLE_SIZE; LOCAL_ImportOPCODEHashChain = (import_opcode_hash_entry_t **)calloc(1, sizeof(import_opcode_hash_entry_t *)* LOCAL_ImportOPCODEHashTableSize); - LOCAL_ImportPredEntryHashTableSize = EXPORT_PRED_ENTRY_TABLE_SIZE; - LOCAL_ImportPredEntryHashChain = (import_pred_entry_hash_entry_t **)calloc(1, sizeof(import_pred_entry_hash_entry_t *)* LOCAL_ImportPredEntryHashTableSize); - LOCAL_ImportDBRefHashTableSize = EXPORT_DBREF_TABLE_SIZE; - LOCAL_ImportDBRefHashChain = (import_dbref_hash_entry_t **)calloc(1, sizeof(import_dbref_hash_entry_t *)* LOCAL_ImportDBRefHashTableSize); } static void @@ -694,6 +686,8 @@ ReadHash(IOSTREAM *stream) } RCHECK(read_tag(stream) == QLY_START_ATOMS); LOCAL_ImportAtomHashTableNum = read_uint(stream); + LOCAL_ImportAtomHashTableSize = LOCAL_ImportAtomHashTableNum*2; + LOCAL_ImportAtomHashChain = (import_atom_hash_entry_t **)calloc(1, sizeof(import_atom_hash_entry_t *)* LOCAL_ImportAtomHashTableSize); for (i = 0; i < LOCAL_ImportAtomHashTableNum; i++) { Atom oat = (Atom)read_uint(stream); Atom at; @@ -734,6 +728,8 @@ ReadHash(IOSTREAM *stream) /* functors */ RCHECK(read_tag(stream) == QLY_START_FUNCTORS); LOCAL_ImportFunctorHashTableNum = read_uint(stream); + LOCAL_ImportFunctorHashTableSize = 2*LOCAL_ImportFunctorHashTableNum; + LOCAL_ImportFunctorHashChain = (import_functor_hash_entry_t **)calloc(1, sizeof(import_functor_hash_entry_t *)* LOCAL_ImportFunctorHashTableSize); for (i = 0; i < LOCAL_ImportFunctorHashTableNum; i++) { Functor of = (Functor)read_uint(stream); UInt arity = read_uint(stream); @@ -749,6 +745,8 @@ ReadHash(IOSTREAM *stream) } RCHECK(read_tag(stream) == QLY_START_PRED_ENTRIES); LOCAL_ImportPredEntryHashTableNum = read_uint(stream); + LOCAL_ImportPredEntryHashTableSize = 2*LOCAL_ImportPredEntryHashTableNum; + LOCAL_ImportPredEntryHashChain = (import_pred_entry_hash_entry_t **)calloc(1, sizeof(import_pred_entry_hash_entry_t *)* LOCAL_ImportPredEntryHashTableSize); for (i = 0; i < LOCAL_ImportPredEntryHashTableNum; i++) { PredEntry *ope = (PredEntry *)read_uint(stream), *pe; UInt arity = read_uint(stream); @@ -795,6 +793,8 @@ ReadHash(IOSTREAM *stream) } RCHECK(read_tag(stream) == QLY_START_DBREFS); LOCAL_ImportDBRefHashTableNum = read_uint(stream); + LOCAL_ImportDBRefHashTableSize = 2*LOCAL_ImportDBRefHashTableNum; + LOCAL_ImportDBRefHashChain = (import_dbref_hash_entry_t **)calloc(1, sizeof(import_dbref_hash_entry_t *)* LOCAL_ImportDBRefHashTableSize); for (i = 0; i < LOCAL_ImportDBRefHashTableNum; i++) { LogUpdClause *ocl = (LogUpdClause *)read_uint(stream); UInt sz = read_uint(stream); diff --git a/C/qlyw.c b/C/qlyw.c index 15d5a65e3..1f8e41dca 100644 --- a/C/qlyw.c +++ b/C/qlyw.c @@ -86,24 +86,57 @@ LookupFunctor(Functor fun) LOCAL_ExportFunctorHashTableNum++; } +static void +GrowPredTable(void) { + UInt size = LOCAL_ExportPredEntryHashTableSize; + export_pred_entry_hash_entry_t *p, *newt, *oldt = LOCAL_ExportPredEntryHashChain; + UInt new_size = size + (size > 1024 ? size : 1024); + UInt i; + + newt = (export_pred_entry_hash_entry_t *)calloc(new_size,sizeof(export_pred_entry_hash_entry_t)); + if (!newt) { + return; + } + p = oldt; + for (i = 0 ; i < size ; p++,i++) { + PredEntry *pe = p->val; + export_pred_entry_hash_entry_t *newp; + CELL hash; + + if (!pe) continue; + hash = ((CELL)(pe))/(2*sizeof(CELL)) % new_size; + newp = newt+hash; + while (newp->val) { + newp++; + if (newp == newt+new_size) + newp = newt; + } + newp->val = p->val; + newp->arity = p->arity; + newp->u.f = p->u.f; + newp->module = p->module; + } + LOCAL_ExportPredEntryHashChain = newt; + LOCAL_ExportPredEntryHashTableSize = new_size; + free(oldt); +} + static void LookupPredEntry(PredEntry *pe) { CACHE_REGS - CELL hash = (CELL)(pe) % LOCAL_ExportPredEntryHashTableSize; + CELL hash = (((CELL)(pe))/(2*sizeof(CELL))) % LOCAL_ExportPredEntryHashTableSize; export_pred_entry_hash_entry_t *p; UInt arity = pe->ArityOfPE; - p = LOCAL_ExportPredEntryHashChain[hash]; - while (p) { + p = LOCAL_ExportPredEntryHashChain+hash; + while (p->val) { if (p->val == pe) { return; } - p = p->next; - } - p = (export_pred_entry_hash_entry_t *)malloc(sizeof(export_pred_entry_hash_entry_t)); - if (!p) { - return; + p++; + if (p == LOCAL_ExportPredEntryHashChain+LOCAL_ExportPredEntryHashTableSize) + p = LOCAL_ExportPredEntryHashChain; } p->arity = arity; p->val = pe; @@ -134,9 +167,15 @@ LookupPredEntry(PredEntry *pe) p->module = AtomProlog; } LookupAtom(p->module); - p->next = LOCAL_ExportPredEntryHashChain[hash]; - LOCAL_ExportPredEntryHashChain[hash] = p; LOCAL_ExportPredEntryHashTableNum++; + if (LOCAL_ExportPredEntryHashTableNum > + LOCAL_ExportPredEntryHashTableSize/2 + ) { + GrowPredTable(); + if (!LOCAL_ExportPredEntryHashChain) { + return; + } + } } static void @@ -178,7 +217,7 @@ InitHash(void) LOCAL_ExportAtomHashChain = (export_atom_hash_entry_t **)calloc(1, sizeof(export_atom_hash_entry_t *)* LOCAL_ExportAtomHashTableSize); LOCAL_ExportPredEntryHashTableNum = 0; LOCAL_ExportPredEntryHashTableSize = EXPORT_PRED_ENTRY_TABLE_SIZE; - LOCAL_ExportPredEntryHashChain = (export_pred_entry_hash_entry_t **)calloc(1, sizeof(export_pred_entry_hash_entry_t *)* LOCAL_ExportPredEntryHashTableSize); + LOCAL_ExportPredEntryHashChain = (export_pred_entry_hash_entry_t *)calloc(LOCAL_ExportPredEntryHashTableSize, sizeof(export_pred_entry_hash_entry_t)); LOCAL_ExportDBRefHashTableNum = 0; LOCAL_ExportDBRefHashTableSize = EXPORT_DBREF_TABLE_SIZE; LOCAL_ExportDBRefHashChain = (export_dbref_hash_entry_t **)calloc(1, sizeof(export_dbref_hash_entry_t *)* LOCAL_ExportDBRefHashTableSize); @@ -444,16 +483,13 @@ SaveHash(IOSTREAM *stream) save_tag(stream, QLY_START_PRED_ENTRIES); save_uint(stream, LOCAL_ExportPredEntryHashTableNum); for (i = 0; i < LOCAL_ExportPredEntryHashTableSize; i++) { - export_pred_entry_hash_entry_t *p = LOCAL_ExportPredEntryHashChain[i]; - while (p) { - export_pred_entry_hash_entry_t *p0 = p; - CHECK(save_uint(stream, (UInt)(p->val))); - CHECK(save_uint(stream, p->arity)); - CHECK(save_uint(stream, (UInt)p->module)); - CHECK(save_uint(stream, (UInt)p->u.f)); - p = p->next; - free(p0); - } + export_pred_entry_hash_entry_t *p = LOCAL_ExportPredEntryHashChain+i; + if (!(p->val)) + continue; + CHECK(save_uint(stream, (UInt)(p->val))); + CHECK(save_uint(stream, p->arity)); + CHECK(save_uint(stream, (UInt)p->module)); + CHECK(save_uint(stream, (UInt)p->u.f)); } save_tag(stream, QLY_START_DBREFS); save_uint(stream, LOCAL_ExportDBRefHashTableNum); diff --git a/H/hlocals.h b/H/hlocals.h index c55a5e4f9..92243152b 100644 --- a/H/hlocals.h +++ b/H/hlocals.h @@ -202,7 +202,7 @@ typedef struct worker_local { struct export_functor_hash_entry_struct **ExportFunctorHashChain_; UInt ExportFunctorHashTableSize_; UInt ExportFunctorHashTableNum_; - struct export_pred_entry_hash_entry_struct **ExportPredEntryHashChain_; + struct export_pred_entry_hash_entry_struct *ExportPredEntryHashChain_; UInt ExportPredEntryHashTableSize_; UInt ExportPredEntryHashTableNum_; struct export_dbref_hash_entry_struct **ExportDBRefHashChain_; diff --git a/H/qly.h b/H/qly.h index f4d0fffe8..a004719e0 100644 --- a/H/qly.h +++ b/H/qly.h @@ -61,7 +61,6 @@ typedef struct export_pred_entry_hash_entry_struct { } u; Atom module; UInt arity; - struct export_pred_entry_hash_entry_struct *next; } export_pred_entry_hash_entry_t; typedef struct import_pred_entry_hash_entry_struct { diff --git a/misc/LOCALS b/misc/LOCALS index dacd39c32..2d162c9b9 100644 --- a/misc/LOCALS +++ b/misc/LOCALS @@ -229,7 +229,7 @@ UInt ExportAtomHashTableNum =0 struct export_functor_hash_entry_struct **ExportFunctorHashChain =NULL UInt ExportFunctorHashTableSize =0 UInt ExportFunctorHashTableNum =0 -struct export_pred_entry_hash_entry_struct **ExportPredEntryHashChain =NULL +struct export_pred_entry_hash_entry_struct *ExportPredEntryHashChain =NULL UInt ExportPredEntryHashTableSize =0 UInt ExportPredEntryHashTableNum =0 struct export_dbref_hash_entry_struct **ExportDBRefHashChain =NULL