diff --git a/src/object.c b/src/object.c index fc547dfc..a9119a4b 100644 --- a/src/object.c +++ b/src/object.c @@ -172,6 +172,8 @@ uint32_t krk_unicodeCodepoint(KrkString * string, size_t index) { } } +extern int krk_tableSetExact(KrkTable * table, KrkValue key, KrkValue value); + static KrkString * allocateString(char * chars, size_t length, uint32_t hash) { size_t codesLength = 0; int type = checkString(chars,length,&codesLength); @@ -187,7 +189,7 @@ static KrkString * allocateString(char * chars, size_t length, uint32_t hash) { string->codes = NULL; if (type == KRK_OBJ_FLAGS_STRING_ASCII) string->codes = string->chars; krk_push(OBJECT_VAL(string)); - krk_tableSet(&vm.strings, OBJECT_VAL(string), NONE_VAL()); + krk_tableSetExact(&vm.strings, OBJECT_VAL(string), NONE_VAL()); krk_pop(); _release_lock(_stringLock); return string; @@ -253,7 +255,7 @@ KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength string->codes = NULL; if (type == KRK_OBJ_FLAGS_STRING_ASCII) string->codes = string->chars; krk_push(OBJECT_VAL(string)); - krk_tableSet(&vm.strings, OBJECT_VAL(string), NONE_VAL()); + krk_tableSetExact(&vm.strings, OBJECT_VAL(string), NONE_VAL()); krk_pop(); _release_lock(_stringLock); return string; diff --git a/src/table.c b/src/table.c index 571fec37..c0c024f8 100644 --- a/src/table.c +++ b/src/table.c @@ -168,6 +168,29 @@ int krk_tableSet(KrkTable * table, KrkValue key, KrkValue value) { return isNew; } +int krk_tableSetExact(KrkTable * table, KrkValue key, KrkValue value) { + if (table->used + 1 > table->capacity * TABLE_MAX_LOAD) { + size_t capacity = KRK_GROW_CAPACITY(table->capacity); + krk_tableAdjustCapacity(table, capacity); + } + + ssize_t index = krk_tableIndexKeyExact(table->entries, table->indexes, table->capacity, key); + if (index < 0) return 0; + KrkTableEntry * entry; + int isNew = table->indexes[index] < 0; + if (isNew) { + table->indexes[index] = table->used; + entry = &table->entries[table->used]; + entry->key = key; + table->used++; + table->count++; + } else { + entry = &table->entries[table->indexes[index]]; + } + entry->value = value; + return isNew; +} + int krk_tableSetIfExists(KrkTable * table, KrkValue key, KrkValue value) { if (table->count == 0) return 0; ssize_t index = krk_tableIndexKey(table->entries, table->indexes, table->capacity, key);