void deleteSymbolHTable(Table ht, Symbol s) { int v; Symbol *h; TableEnum e; LOCK_TABLE(ht); v = (int)pointerHashValue(s->name, ht->buckets); h = &ht->entries[v]; for( e=ht->enumerators; e; e = e->next ) { if ( e->current == s ) rawAdvanceTableEnum(e); } for( ; *h; h = &(*h)->next ) { if ( *h == s ) { *h = (*h)->next; s->next = NULL; /* force crash */ s->name = NULL; s->value = NULL; freeHeap(s, sizeof(struct symbol)); ht->size--; break; } } UNLOCK_TABLE(ht); }
functor_t isCurrentFunctor(atom_t atom, size_t arity) { GET_LD unsigned int v; int buckets; FunctorDef *table; FunctorDef f; functor_t rc = 0; redo: acquire_functor_table(table, buckets); v = (unsigned int)pointerHashValue(atom, buckets); for(f = table[v]; f; f = f->next) { if ( FUNCTOR_IS_VALID(f->flags) && atom == f->name && f->arity == arity ) { release_functor_table(); rc = f->functor; break; } } release_functor_table(); if ( !rc && functorDefTable->buckets * 2 < GD->statistics.functors ) { LOCK(); rehashFunctors(); UNLOCK(); } if ( table != functorDefTable->table ) goto redo; return rc; }
Symbol addHTable(Table ht, void *name, void *value) { Symbol s; int v; LOCK_TABLE(ht); v = (int)pointerHashValue(name, ht->buckets); if ( lookupHTable(ht, name) ) { UNLOCK_TABLE(ht); return NULL; } s = allocHeapOrHalt(sizeof(struct symbol)); s->name = name; s->value = value; s->next = ht->entries[v]; ht->entries[v] = s; ht->size++; DEBUG(9, Sdprintf("addHTable(0x%x, 0x%x, 0x%x) --> size = %d\n", ht, name, value, ht->size)); if ( ht->buckets * 2 < ht->size && !ht->enumerators ) s = rehashHTable(ht, s); UNLOCK_TABLE(ht); DEBUG(1, checkHTable(ht)); return s; }
functor_t lookupFunctorDef(atom_t atom, size_t arity) { GET_LD int v; FunctorDef *table; int buckets; FunctorDef f, head; redo: acquire_functor_table(table, buckets); v = (int)pointerHashValue(atom, buckets); head = table[v]; DEBUG(9, Sdprintf("Lookup functor %s/%d = ", stringAtom(atom), arity)); for(f = table[v]; f; f = f->next) { if (atom == f->name && f->arity == arity) { DEBUG(9, Sdprintf("%p (old)\n", f)); if ( !FUNCTOR_IS_VALID(f->flags) ) { goto redo; } release_functor_table(); return f->functor; } } if ( functorDefTable->buckets * 2 < GD->statistics.functors ) { LOCK(); rehashFunctors(); UNLOCK(); } if ( !( head == table[v] && table == functorDefTable->table ) ) goto redo; f = (FunctorDef) allocHeapOrHalt(sizeof(struct functorDef)); f->functor = 0L; f->name = atom; f->arity = arity; f->flags = 0; f->next = table[v]; if ( !( COMPARE_AND_SWAP(&table[v], head, f) && table == functorDefTable->table) ) { PL_free(f); goto redo; } registerFunctor(f); ATOMIC_INC(&GD->statistics.functors); PL_register_atom(atom); DEBUG(9, Sdprintf("%p (new)\n", f)); release_functor_table(); return f->functor; }
Symbol lookupHTable(Table ht, void *name) { Symbol s = ht->entries[pointerHashValue(name, ht->buckets)]; DEBUG(MSG_HASH_STAT, lookups++); for( ; s; s = s->next) { DEBUG(MSG_HASH_STAT, cmps++); if ( s->name == name ) return s; } return NULL; }
functor_t isCurrentFunctor(atom_t atom, unsigned int arity) { unsigned int v; FunctorDef f; LOCK(); v = (unsigned int)pointerHashValue(atom, functor_buckets); for(f = functorDefTable[v]; f; f = f->next) { if ( atom == f->name && f->arity == arity ) { UNLOCK(); return f->functor; } } UNLOCK(); return 0; }
static void registerBuiltinFunctors(void) { int size = sizeof(functors)/sizeof(builtin_functor) - 1; FunctorDef f = allocHeapOrHalt(size * sizeof(struct functorDef)); const builtin_functor *d; GD->statistics.functors = size; for(d = functors; d->name; d++, f++) { size_t v = pointerHashValue(d->name, functor_buckets); f->name = d->name; f->arity = d->arity; f->flags = 0; f->next = functorDefTable[v]; functorDefTable[v] = f; registerFunctor(f); } }
static void rehashFunctors(void) { FunctorTable newtab; size_t index; int i, last = FALSE; if ( functorDefTable->buckets * 2 >= GD->statistics.functors ) return; newtab = allocHeapOrHalt(sizeof(*newtab)); newtab->buckets = functorDefTable->buckets * 2; newtab->table = allocHeapOrHalt(newtab->buckets * sizeof(FunctorDef)); memset(newtab->table, 0, newtab->buckets * sizeof(FunctorDef)); newtab->prev = functorDefTable; DEBUG(MSG_HASH_STAT, Sdprintf("Rehashing functor-table (%d --> %d)\n", functorDefTable->buckets, newtab->buckets)); for(index=1, i=0; !last; i++) { size_t upto = (size_t)2<<i; FunctorDef *b = GD->functors.array.blocks[i]; if ( upto >= GD->functors.highest ) { upto = GD->functors.highest; last = TRUE; } for(; index<upto; index++) { FunctorDef f = b[index]; if ( FUNCTOR_IS_VALID(f->flags) ) { size_t v = pointerHashValue(f->name, newtab->buckets); f->next = newtab->table[v]; newtab->table[v] = f; } } } functorDefTable = newtab; maybe_free_functor_tables(); }
functor_t lookupFunctorDef(atom_t atom, unsigned int arity) { int v; FunctorDef f; LOCK(); v = (int)pointerHashValue(atom, functor_buckets); DEBUG(9, Sdprintf("Lookup functor %s/%d = ", stringAtom(atom), arity)); for(f = functorDefTable[v]; f; f = f->next) { if (atom == f->name && f->arity == arity) { DEBUG(9, Sdprintf("%p (old)\n", f)); UNLOCK(); return f->functor; } } f = (FunctorDef) allocHeapOrHalt(sizeof(struct functorDef)); f->functor = 0L; f->name = atom; f->arity = arity; if ( atom == ATOM_call && arity > 8 ) f->flags = CONTROL_F; else f->flags = 0; f->next = functorDefTable[v]; functorDefTable[v] = f; registerFunctor(f); GD->statistics.functors++; PL_register_atom(atom); DEBUG(9, Sdprintf("%p (new)\n", f)); if ( functor_buckets * 2 < GD->statistics.functors ) rehashFunctors(); UNLOCK(); return f->functor; }
static void rehashFunctors(void) { FunctorDef *oldtab = functorDefTable; int oldbucks = functor_buckets; size_t index; int i, last = FALSE; functor_buckets *= 2; allocFunctorTable(); DEBUG(MSG_HASH_STAT, Sdprintf("Rehashing functor-table to %d entries\n", functor_buckets)); for(index=1, i=0; !last; i++) { size_t upto = (size_t)2<<i; FunctorDef *b = GD->functors.array.blocks[i]; if ( upto >= GD->functors.highest ) { upto = GD->functors.highest; last = TRUE; } for(; index<upto; index++) { FunctorDef f = b[index]; if ( f ) { size_t v = pointerHashValue(f->name, functor_buckets); f->next = functorDefTable[v]; functorDefTable[v] = f; } } } freeHeap(oldtab, oldbucks * sizeof(FunctorDef)); }
static Symbol rehashHTable(Table ht, Symbol map) { Symbol *newentries, *oldentries; int newbuckets, oldbuckets; int i; int safe_copy = (ht->mutex != NULL); newbuckets = ht->buckets*2; newentries = allocHTableEntries(newbuckets); DEBUG(MSG_HASH_STAT, Sdprintf("Rehashing table %p to %d entries\n", ht, ht->buckets)); for(i=0; i<ht->buckets; i++) { Symbol s, n; if ( safe_copy ) { for(s=ht->entries[i]; s; s = n) { int v = (int)pointerHashValue(s->name, newbuckets); Symbol s2 = allocHeapOrHalt(sizeof(*s2)); n = s->next; if ( s == map ) map = s2; *s2 = *s; s2->next = newentries[v]; newentries[v] = s2; } } else { for(s=ht->entries[i]; s; s = n) { int v = (int)pointerHashValue(s->name, newbuckets); n = s->next; s->next = newentries[v]; newentries[v] = s; } } } oldentries = ht->entries; oldbuckets = ht->buckets; ht->entries = newentries; ht->buckets = newbuckets; if ( safe_copy ) { /* Here we should be waiting until */ /* active lookup are finished */ for(i=0; i<oldbuckets; i++) { Symbol s, n; for(s=oldentries[i]; s; s = n) { n = s->next; s->next = NULL; /* that causes old readers to stop */ freeHeap(s, sizeof(*s)); } } } freeHeap(oldentries, oldbuckets * sizeof(Symbol)); DEBUG(CHK_SECURE, checkHTable(ht)); return map; }