Improve hashtable entry removal performance

isolation_bkp/dynres
Dominik Madarász 2021-10-28 16:05:17 +02:00
parent a589845065
commit 296857df71
9 changed files with 18600 additions and 18562 deletions

View File

@ -90,7 +90,6 @@ static debug_item items[] = {
{ .kind = DITEM_TEXT, .name = "delta time", .proc = DrawDeltaTime },
{ .kind = DITEM_TEXT, .name = "pos", .proc = DrawCameraPos },
{ .kind = DITEM_TEXT, .name = "zoom", .proc = DrawZoom },
{ .kind = DITEM_SLIDER, .name = "slider", .slider = { .min = 0.0f, .max = 1.0f, .val = 0.5f } },
{ .kind = DITEM_END },
}
}
@ -180,6 +179,7 @@ static debug_item items[] = {
{ .kind = DITEM_END },
},
.is_sp_only = true,
.is_collapsed = true,
}
},
{

View File

@ -226,9 +226,7 @@ void
ActDespawnDemoNPCs(void) {
if (!demo_npcs) return;
for (uint32_t i = 0; i < zpl_array_count(demo_npcs); i++) {
entity_despawn(demo_npcs[i]);
}
entity_batch_despawn(demo_npcs, zpl_array_count(demo_npcs));
zpl_array_free(demo_npcs);
demo_npcs = 0;

View File

@ -12,19 +12,20 @@
uint64_t entity_spawn(uint16_t class_id) {
ecs_entity_t e = ecs_new(world_ecs(), 0);
ecs_set(world_ecs(), e, Velocity, {0});
ecs_set(world_ecs(), e, Classify, { .id = class_id });
if (class_id != EKIND_SERVER) {
ecs_set(world_ecs(), e, Velocity, {0});
ecs_add(world_ecs(), e, Walking);
Position *pos = ecs_get_mut(world_ecs(), e, Position, NULL);
#if 1
pos->x=rand() % world_dim();
pos->y=rand() % world_dim();
pos->x=(float)(rand() % world_dim());
pos->y=(float)(rand() % world_dim());
#else
pos->x=350;
pos->y=88;
pos->x=350.0f;
pos->y=88.0f;
#endif
if (class_id != EKIND_SERVER) {
librg_entity_track(world_tracker(), e);
librg_entity_chunk_set(world_tracker(), e, librg_chunk_from_realpos(world_tracker(), pos->x, pos->y, 0));
librg_entity_owner_set(world_tracker(), e, (int64_t)e);
@ -33,6 +34,13 @@ uint64_t entity_spawn(uint16_t class_id) {
return (uint64_t)e;
}
void entity_batch_despawn(uint64_t *ids, size_t num_ids) {
for (size_t i = 0; i < num_ids; i++ ) {
librg_entity_untrack(world_tracker(), ids[i]);
ecs_delete(world_ecs(), ids[i]);
}
}
void entity_despawn(uint64_t ent_id) {
librg_entity_untrack(world_tracker(), ent_id);
ecs_delete(world_ecs(), ent_id);

View File

@ -92,8 +92,8 @@ void HurtOnHazardBlock(ecs_iter_t *it) {
for (int i = 0; i < it->count; i++) {
world_block_lookup l = world_block_from_realpos(p[i].x, p[i].y);
if (blocks_get_flags(l.block_id) & BLOCK_FLAG_HAZARD) {
if (h->pain_time < game_time()) {
h->pain_time = game_time() + HAZARD_BLOCK_TIME;
if (h->pain_time < 0.0f) {
h->pain_time = HAZARD_BLOCK_TIME;
h->hp -= HAZARD_BLOCK_DMG;
h->hp = zpl_max(0.0f, h->hp);
}
@ -109,12 +109,16 @@ void RegenerateHP(ecs_iter_t *it) {
Health *h = ecs_column(it, Health, 1);
for (int i = 0; i < it->count; i++) {
if (h->pain_time < game_time() - HP_REGEN_PAIN_COOLDOWN) {
if (h->heal_time < game_time() && h->hp < h->max_hp) {
h->heal_time = game_time() + HP_REGEN_TIME;
h->hp += HP_REGEN_RECOVERY;
h->hp = zpl_min(h->max_hp, h->hp);
if (h[i].pain_time < 0.0f) {
if (h[i].heal_time < 0.0f && h[i].hp < h[i].max_hp) {
h[i].heal_time = HP_REGEN_TIME;
h[i].hp += HP_REGEN_RECOVERY;
h[i].hp = zpl_min(h[i].max_hp, h[i].hp);
} else {
h[i].heal_time -= safe_dt(it);
}
} else {
h[i].pain_time -= safe_dt(it);
}
}
}

View File

@ -6,7 +6,7 @@ void DemoNPCMoveAround(ecs_iter_t *it) {
Velocity *v = ecs_column(it, Velocity, 1);
for (int i = 0; i < it->count; i++) {
float d = zpl_quake_rsqrt(v[i].x*v[i].x + v[i].y*v[i].y);
v[i].x += (v[i].x*d*DEMO_NPC_MOVE_SPEED*it->delta_time + zpl_cos(zpl_to_radians(rand()%360))*DEMO_NPC_STEER_SPEED*it->delta_time);
v[i].y += (v[i].y*d*DEMO_NPC_MOVE_SPEED*it->delta_time + zpl_sin(zpl_to_radians(rand()%360))*DEMO_NPC_STEER_SPEED*it->delta_time);
v[i].x += (v[i].x*d*DEMO_NPC_MOVE_SPEED*safe_dt(it) + zpl_cos(zpl_to_radians(rand()%360))*DEMO_NPC_STEER_SPEED*safe_dt(it));
v[i].y += (v[i].y*d*DEMO_NPC_MOVE_SPEED*safe_dt(it) + zpl_sin(zpl_to_radians(rand()%360))*DEMO_NPC_STEER_SPEED*safe_dt(it));
}
}

42
code/vendors/zpl.h vendored
View File

@ -4296,12 +4296,15 @@ zpl_array(ZPL_JOIN2(NAME, Entry)) entries;
PREFIX void ZPL_JOIN2(FUNC, init)(NAME * h, zpl_allocator a); \
PREFIX void ZPL_JOIN2(FUNC, destroy)(NAME * h); \
PREFIX VALUE *ZPL_JOIN2(FUNC, get)(NAME * h, zpl_u64 key); \
PREFIX zpl_isize ZPL_JOIN2(FUNC, slot)(NAME * h, zpl_u64 key); \
PREFIX void ZPL_JOIN2(FUNC, set)(NAME * h, zpl_u64 key, VALUE value); \
PREFIX void ZPL_JOIN2(FUNC, grow)(NAME * h); \
PREFIX void ZPL_JOIN2(FUNC, rehash)(NAME * h, zpl_isize new_count); \
PREFIX void ZPL_JOIN2(FUNC, rehash_fast)(NAME * h); \
PREFIX void ZPL_JOIN2(FUNC, map)(NAME * h, void (*map_proc)(zpl_u64 key, VALUE value)); \
PREFIX void ZPL_JOIN2(FUNC, map_mut)(NAME * h, void (*map_proc)(zpl_u64 key, VALUE * value)); \
PREFIX void ZPL_JOIN2(FUNC, remove)(NAME * h, zpl_u64 key);
PREFIX void ZPL_JOIN2(FUNC, remove)(NAME * h, zpl_u64 key); \
PREFIX void ZPL_JOIN2(FUNC, remove_entry)(NAME * h, zpl_isize idx);
#define ZPL_TABLE_DEFINE(NAME, FUNC, VALUE) \
void ZPL_JOIN2(FUNC, init)(NAME * h, zpl_allocator a) { \
@ -4314,6 +4317,15 @@ if (h->entries) zpl_array_free(h->entries);
if (h->hashes) zpl_array_free(h->hashes); \
} \
\
zpl_isize ZPL_JOIN2(FUNC, slot)(NAME * h, zpl_u64 key) { \
for (zpl_isize i = 0; i < zpl_array_count(h->entries); i++) {\
if (h->entries[i].key == key) {\
return i; \
} \
}\
return -1;\
}\
\
zpl_internal zpl_isize ZPL_JOIN2(FUNC, _add_entry)(NAME * h, zpl_u64 key) { \
zpl_isize index; \
ZPL_JOIN2(NAME, Entry) e = { 0 }; \
@ -4373,6 +4385,22 @@ h->hashes = nh.hashes;
h->entries = nh.entries; \
} \
\
void ZPL_JOIN2(FUNC, rehash_fast)(NAME * h) { \
zpl_isize i; \
for (i = 0; i < zpl_array_count(h->entries); i++) h->entries[i].next = -1; \
for (i = 0; i < zpl_array_count(h->hashes); i++) h->hashes[i] = -1; \
for (i = 0; i < zpl_array_count(h->entries); i++) { \
ZPL_JOIN2(NAME, Entry) * e; \
zpl_hash_table_find_result fr; \
e = &h->entries[i]; \
fr = ZPL_JOIN2(FUNC, _find)(h, e->key); \
if (fr.entry_prev < 0) \
h->hashes[fr.hash_index] = i; \
else \
h->entries[fr.entry_prev].next = i; \
} \
} \
\
VALUE *ZPL_JOIN2(FUNC, get)(NAME * h, zpl_u64 key) { \
zpl_isize index = ZPL_JOIN2(FUNC, _find)(h, key).entry_index; \
if (index >= 0) return &h->entries[index].value; \
@ -4380,16 +4408,16 @@ return NULL;
} \
\
void ZPL_JOIN2(FUNC, remove)(NAME * h, zpl_u64 key) { \
zpl_isize i; \
zpl_hash_table_find_result fr = ZPL_JOIN2(FUNC, _find)(h, key); \
if (fr.entry_index >= 0) { \
if (fr.entry_prev >= 0) { \
h->entries[fr.entry_prev].next = h->entries[fr.entry_index].next; \
} else { \
h->hashes[fr.hash_index] = fr.entry_index; \
} \
zpl_array_remove_at(h->entries, fr.entry_index); \
ZPL_JOIN2(FUNC, rehash_fast)(h); \
} \
ZPL_JOIN2(FUNC, rehash)(h, zpl_array_count(h->entries)); \
} \
\
void ZPL_JOIN2(FUNC, remove_entry)(NAME * h, size_t idx) { \
zpl_array_remove_at(h->entries, idx); \
} \
\
void ZPL_JOIN2(FUNC, map)(NAME * h, void (*map_proc)(zpl_u64 key, VALUE value)) { \