make dict with string keys noexcept

This commit is contained in:
blueloveTH 2025-08-28 19:03:46 +08:00
parent 7135e1ce59
commit 5868db1d53
2 changed files with 22 additions and 12 deletions

View File

@ -23,11 +23,10 @@
#define V int #define V int
#define NAME c11_smallmap_v2d #define NAME c11_smallmap_v2d
#define less(a, b) (c11_sv__cmp((a), (b)) < 0) #define less(a, b) (c11_sv__cmp((a), (b)) < 0)
#define equal(a, b) (c11_sv__cmp((a), (b)) == 0) #define equal(a, b) c11__sveq((a), (b))
#include "pocketpy/xmacros/smallmap.h" #include "pocketpy/xmacros/smallmap.h"
#undef SMALLMAP_T__HEADER #undef SMALLMAP_T__HEADER
#define SMALLMAP_T__HEADER #define SMALLMAP_T__HEADER
#define K void* #define K void*
#define V py_i64 #define V py_i64

View File

@ -136,16 +136,17 @@ static void Dict__set_index(Dict* self, uint32_t index, uint32_t value) {
} }
} }
// Dict__probe won't raise exception for string keys
static bool Dict__probe(Dict* self, static bool Dict__probe(Dict* self,
py_TValue* key, py_TValue* key,
uint64_t* p_hash, uint64_t* p_hash,
uint32_t* p_idx, uint32_t* p_idx,
DictEntry** p_entry) { DictEntry** p_entry) {
if(py_isstr(key)) {
*p_hash = c11_sv__hash(py_tosv(key));
} else {
py_i64 h_user; py_i64 h_user;
if(!py_hash(key, &h_user)) return false; if(!py_hash(key, &h_user)) return false;
if(py_isstr(key)) {
*p_hash = (uint64_t)h_user;
} else {
*p_hash = Dict__hash_2nd((uint64_t)h_user); *p_hash = Dict__hash_2nd((uint64_t)h_user);
} }
uint32_t mask = self->capacity - 1; uint32_t mask = self->capacity - 1;
@ -155,6 +156,15 @@ static bool Dict__probe(Dict* self,
if(idx2 == self->null_index_value) break; if(idx2 == self->null_index_value) break;
DictEntry* entry = c11__at(DictEntry, &self->entries, idx2); DictEntry* entry = c11__at(DictEntry, &self->entries, idx2);
if(entry->hash == (*p_hash)) { if(entry->hash == (*p_hash)) {
if(py_isstr(&entry->key) && py_isstr(key)) {
c11_sv lhs = py_tosv(&entry->key);
c11_sv rhs = py_tosv(key);
if(c11__sveq(lhs, rhs)) {
*p_idx = idx;
*p_entry = entry;
return true;
}
} else {
int res = py_equal(&entry->key, key); int res = py_equal(&entry->key, key);
if(res == 1) { if(res == 1) {
*p_idx = idx; *p_idx = idx;
@ -163,6 +173,7 @@ static bool Dict__probe(Dict* self,
} }
if(res == -1) return false; // error if(res == -1) return false; // error
} }
}
// try next index // try next index
idx = Dict__step(idx); idx = Dict__step(idx);
} }