DECLARE_TEST( hashmap, erase ) { hashmap_t* map = hashmap_allocate( 0, 0 ); void* prev = 0; EXPECT_EQ( hashmap_lookup( map, 0 ), 0 ); EXPECT_EQ( hashmap_size( map ), 0 ); prev = hashmap_insert( map, 0, map ); EXPECT_EQ( prev, 0 ); EXPECT_EQ( hashmap_size( map ), 1 ); EXPECT_TRUE( hashmap_has_key( map, 0 ) ); prev = hashmap_erase( map, 0 ); EXPECT_EQ( prev, map ); EXPECT_EQ( hashmap_size( map ), 0 ); EXPECT_FALSE( hashmap_has_key( map, 0 ) ); prev = hashmap_erase( map, 0 ); EXPECT_EQ( prev, 0 ); EXPECT_EQ( hashmap_size( map ), 0 ); EXPECT_FALSE( hashmap_has_key( map, 0 ) ); prev = hashmap_erase( map, (hash_t)(uintptr_t)map ); EXPECT_EQ( prev, 0 ); EXPECT_EQ( hashmap_size( map ), 0 ); EXPECT_FALSE( hashmap_has_key( map, (hash_t)(uintptr_t)map ) ); hashmap_deallocate( map ); return 0; }
DECLARE_TEST( hashmap, lookup ) { hashmap_t* map = hashmap_allocate( 31, 0 ); char* value = (void*)(uintptr_t)1234; hash_t key = (hash_t)4321; unsigned int ikey = 0; for( ; ikey < 1024; ++ikey, ++key, ++value ) { void* prev = hashmap_insert( map, key, value ); EXPECT_EQ( prev, 0 ); } for( ikey = 0, key = (hash_t)4321, value = (void*)(uintptr_t)1234; ikey < 1024; ++ikey, ++key, ++value ) { void* prev = hashmap_lookup( map, key ); EXPECT_EQ( prev, value ); EXPECT_TRUE( hashmap_has_key( map, key ) ); hashmap_erase( map, key ); EXPECT_FALSE( hashmap_has_key( map, key ) ); } hashmap_deallocate( map ); return 0; }
//This is our custom callback point from luajit lj_clib resolver void* lj_clib_getsym_registry(lua_State* state, const char* sym, size_t length) { hash_t symhash = hash(sym, length); void* fn = hashmap_lookup(_lua_symbols, symhash); FOUNDATION_UNUSED(state); //log_debugf(HASH_LUA, STRING_CONST("Built-in lookup: %.*s -> %p", (int)length, sym, fn); return fn; }
DECLARE_TEST(hashmap, allocation) { hashmap_t* map = hashmap_allocate(0, 0); EXPECT_EQ(hashmap_size(map), 0); EXPECT_EQ(hashmap_lookup(map, 0), 0); EXPECT_EQ(hashmap_lookup(map, (hash_t)(uintptr_t)map), 0); hashmap_deallocate(map); map = hashmap_allocate(13, 127); EXPECT_EQ(hashmap_size(map), 0); EXPECT_EQ(hashmap_lookup(map, 0), 0); EXPECT_EQ(hashmap_lookup(map, (hash_t)(uintptr_t)map), 0); hashmap_deallocate(map); return 0; }
FtableEntry ftable_lookup_by_name(Ftable ftable, char *name) { HEX_ASSERT(ftable); HEX_ASSERT(name); FtableEntry entry = (FtableEntry)hashmap_lookup( ftable->hashmap, _ftable_lookup_by_name, name ); return entry; }
VtableEntry vtable_lookup(Vtable vtable, char *name, unsigned int indent_level) { HEX_ASSERT(vtable); HEX_ASSERT(name); struct HexVtableLookupArg arg = { .name = name, .indent_level = indent_level }; VtableEntry entry = (VtableEntry)hashmap_lookup(vtable->hashmap, _vtable_lookup, &arg); return entry; }
DECLARE_TEST( hashmap, insert ) { hashmap_t* map = hashmap_allocate( 0, 0 ); void* prev = 0; EXPECT_EQ( hashmap_lookup( map, 0 ), 0 ); prev = hashmap_insert( map, 0, map ); EXPECT_EQ( prev, 0 ); prev = hashmap_insert( map, 0, map ); EXPECT_EQ( prev, map ); prev = hashmap_insert( map, 0, 0 ); EXPECT_EQ( prev, map ); prev = hashmap_insert( map, 0, map ); EXPECT_EQ( prev, 0 ); prev = hashmap_insert( map, (hash_t)(uintptr_t)map, map ); EXPECT_EQ( prev, 0 ); EXPECT_EQ( hashmap_size( map ), 2 ); EXPECT_EQ( hashmap_lookup( map, 0 ), map ); EXPECT_EQ( hashmap_lookup( map, (hash_t)(uintptr_t)map ), map ); hashmap_insert( map, 0, 0 ); hashmap_insert( map, (hash_t)(uintptr_t)map, 0 ); EXPECT_EQ( hashmap_size( map ), 2 ); EXPECT_EQ( hashmap_lookup( map, 0 ), 0 ); EXPECT_EQ( hashmap_lookup( map, (hash_t)(uintptr_t)map ), 0 ); hashmap_deallocate( map ); return 0; }
static ThreadInfo* get_thread_info(pid_t pid) { pthread_mutex_lock_unchecked(&sDbgLock); HashEntry* entry = hashmap_lookup(&sThreadMap, &pid, sizeof(pid), &ThreadInfo_equals); if (entry->data == NULL) { ThreadInfo* thread_info = DbgAllocLocked(sizeof(ThreadInfo), 1); entry->data = thread_info; initThreadInfo(thread_info, pid); } pthread_mutex_unlock_unchecked(&sDbgLock); return (ThreadInfo *)entry->data; }
static MutexInfo* get_mutex_info(pthread_mutex_t *mutex) { pthread_mutex_lock_unchecked(&sDbgLock); HashEntry* entry = hashmap_lookup(&sMutexMap, &mutex, sizeof(mutex), &MutexInfo_equals); if (entry->data == NULL) { MutexInfo* mutex_info = DbgAllocLocked(sizeof(MutexInfo), 1); entry->data = mutex_info; initMutexInfo(mutex_info, mutex); } pthread_mutex_unlock_unchecked(&sDbgLock); return (MutexInfo *)entry->data; }
void lua_module_register(const char* name, size_t length, const uuid_t uuid, lua_fn loader, lua_preload_fn preload) { hash_t namehash = hash(name, length); mutex_lock(_lua_modulemap_lock); lua_modulemap_entry_t* entry = hashmap_lookup(_lua_modulemap, namehash); if (!entry) { entry = memory_allocate(HASH_LUA, sizeof(lua_modulemap_entry_t), 0, MEMORY_PERSISTENT); entry->name = namehash; entry->uuid = uuid; entry->loader = loader; entry->preload = preload; hashmap_insert(_lua_modulemap, hash(name, length), entry); } mutex_unlock(_lua_modulemap_lock); }
//This is our custom callback point from luajit lib_package loader int lj_cf_package_loader_registry(lua_State* state) { size_t length = 0; const char* name = luaL_checklstring(state, 1, &length); mutex_lock(_lua_modulemap_lock); hash_t namehash = hash(name, length); lua_modulemap_entry_t* entry = hashmap_lookup(_lua_modulemap, namehash); mutex_unlock(_lua_modulemap_lock); if (entry) { lua_pushlstring(state, name, length); lua_pushlightuserdata(state, entry); lua_pushcclosure(state, entry->loader, 2); } else { lua_pushfstring(state, "\n\tno modulemap entry '%s'", name); } return 1; }
FtableEntry ftable_lookup(Ftable ftable, char *name, void *paramlist) { HEX_ASSERT(ftable); HEX_ASSERT(name); FtableEntry _entry = HEX_MALLOC(struct HexFtableEntry); HEX_ASSERT(_entry); _entry->name = name; _entry->paramlist = paramlist; char *mingled_name = ftable_mingle_name(_entry); HEX_ASSERT(mingled_name); struct HexFtableLookupArg arg = { .mingled_name = mingled_name }; FtableEntry entry = (FtableEntry)hashmap_lookup(ftable->hashmap, _ftable_lookup, &arg); HEX_FREE(mingled_name); return entry; }