// start looking in the table at the following hash position
const UInt hash = HashString(name);
#ifdef HPCGAP
LockSymbolTableForReading(symtab); // try a read lock first
#endif
// look through the table until we find a free slot or the global
sizeTable = LEN_PLIST(symtab->table);
pos = (hash % sizeTable) + 1;
while (
(id = ELM_PLIST(symtab->table, pos)) != 0 &&
strcmp(CONST_CSTR_STRING(symtab->nameFunc(INT_INTOBJ(id))), name)) {
pos = (pos % sizeTable) + 1;
}
if (id != 0) {
#ifdef HPCGAP
UnlockSymbolTable(symtab);
#endif
return INT_INTOBJ(id);
}
#ifdef HPCGAP
if (!PreThreadCreation) {
// switch to a write lock
UnlockSymbolTable(symtab);
LockSymbolTableForWriting(symtab);
// when we switched to a write lock, another thread might have
// modified the symbol table; so repeat the lookup
sizeTable = LEN_PLIST(symtab->table);
pos = (hash % sizeTable) + 1;
while ((id = ELM_PLIST(symtab->table, pos)) != 0 &&
strcmp(CONST_CSTR_STRING(symtab->nameFunc(INT_INTOBJ(id))),
name)) {
pos = (pos % sizeTable) + 1;
}
if (id != 0) {
UnlockSymbolTable(symtab);
return INT_INTOBJ(id);
}
}
#endif
// if we did not find the global variable, make a new one and enter it
// (copy the name first, to avoid a stale pointer in case of a GC)
strxcpy(namx, name, sizeof(namx));
string = MakeImmString(namx);
// store the id
GAP_ASSERT(id == 0);
symtab->count = id = INTOBJ_INT(INT_INTOBJ(symtab->count) + 1);
SET_ELM_PLIST(symtab->table, pos, id);
// notify about the new entry
symtab->newSymbolFunc(symtab, INT_INTOBJ(id), string);
// if the table is too crowded, make a larger one, rehash the names
if (sizeTable < 3 * INT_INTOBJ(id) / 2) {
table = symtab->table;
sizeTable = 2 * sizeTable + 1;
symtab->table = NEW_PLIST(T_PLIST, sizeTable);
SET_LEN_PLIST(symtab->table, sizeTable);
#ifdef HPCGAP
// The list is briefly non-public, but this is safe, because
// the mutex protects it from being accessed by other threads.
MakeBagPublic(symtab->table);
#endif
for (i = 1; i <= (sizeTable - 1) / 2; i++) {
Obj id2 = ELM_PLIST(table, i);
if (id2 == 0)
continue;
string = symtab->nameFunc(INT_INTOBJ(id2));
pos = HashString(CONST_CSTR_STRING(string));
pos = (pos % sizeTable) + 1;
while (ELM_PLIST(symtab->table, pos) != 0) {
pos = (pos % sizeTable) + 1;
}
SET_ELM_PLIST(symtab->table, pos, id2);
}
}
#ifdef HPCGAP
UnlockSymbolTable(symtab);
#endif
// if we did not find the global variable, make a new one and enter it // (copy the name first, to avoid a stale pointer in case of a GC)
strxcpy(namx, name, sizeof(namx));
string = MakeImmString(namx);
// store the id
GAP_ASSERT(id == 0);
symtab->count = id = INTOBJ_INT(INT_INTOBJ(symtab->count) + 1);
SET_ELM_PLIST(symtab->table, pos, id);
// notify about the new entry
symtab->newSymbolFunc(symtab, INT_INTOBJ(id), string);
// if the table is too crowded, make a larger one, rehash the names if (sizeTable < 3 * INT_INTOBJ(id) / 2) {
table = symtab->table;
sizeTable = 2 * sizeTable + 1;
symtab->table = NEW_PLIST(T_PLIST, sizeTable);
SET_LEN_PLIST(symtab->table, sizeTable); #ifdef HPCGAP // The list is briefly non-public, but this is safe, because // the mutex protects it from being accessed by other threads.
MakeBagPublic(symtab->table); #endif for (i = 1; i <= (sizeTable - 1) / 2; i++) {
Obj id2 = ELM_PLIST(table, i); if (id2 == 0) continue;
string = symtab->nameFunc(INT_INTOBJ(id2));
pos = HashString(CONST_CSTR_STRING(string));
pos = (pos % sizeTable) + 1; while (ELM_PLIST(symtab->table, pos) != 0) {
pos = (pos % sizeTable) + 1;
}
SET_ELM_PLIST(symtab->table, pos, id2);
}
} #ifdef HPCGAP
UnlockSymbolTable(symtab); #endif
// return the symbol id return INT_INTOBJ(id);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-10-13)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.