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 = "delta time", .proc = DrawDeltaTime },
{ .kind = DITEM_TEXT, .name = "pos", .proc = DrawCameraPos }, { .kind = DITEM_TEXT, .name = "pos", .proc = DrawCameraPos },
{ .kind = DITEM_TEXT, .name = "zoom", .proc = DrawZoom }, { .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 }, { .kind = DITEM_END },
} }
} }
@ -180,6 +179,7 @@ static debug_item items[] = {
{ .kind = DITEM_END }, { .kind = DITEM_END },
}, },
.is_sp_only = true, .is_sp_only = true,
.is_collapsed = true,
} }
}, },
{ {

View File

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

View File

@ -12,19 +12,20 @@
uint64_t entity_spawn(uint16_t class_id) { uint64_t entity_spawn(uint16_t class_id) {
ecs_entity_t e = ecs_new(world_ecs(), 0); 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 }); ecs_set(world_ecs(), e, Classify, { .id = class_id });
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();
#else
pos->x=350;
pos->y=88;
#endif
if (class_id != EKIND_SERVER) { 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=(float)(rand() % world_dim());
pos->y=(float)(rand() % world_dim());
#else
pos->x=350.0f;
pos->y=88.0f;
#endif
librg_entity_track(world_tracker(), e); 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_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); 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; 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) { void entity_despawn(uint64_t ent_id) {
librg_entity_untrack(world_tracker(), ent_id); librg_entity_untrack(world_tracker(), ent_id);
ecs_delete(world_ecs(), 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++) { for (int i = 0; i < it->count; i++) {
world_block_lookup l = world_block_from_realpos(p[i].x, p[i].y); 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 (blocks_get_flags(l.block_id) & BLOCK_FLAG_HAZARD) {
if (h->pain_time < game_time()) { if (h->pain_time < 0.0f) {
h->pain_time = game_time() + HAZARD_BLOCK_TIME; h->pain_time = HAZARD_BLOCK_TIME;
h->hp -= HAZARD_BLOCK_DMG; h->hp -= HAZARD_BLOCK_DMG;
h->hp = zpl_max(0.0f, h->hp); 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); Health *h = ecs_column(it, Health, 1);
for (int i = 0; i < it->count; i++) { for (int i = 0; i < it->count; i++) {
if (h->pain_time < game_time() - HP_REGEN_PAIN_COOLDOWN) { if (h[i].pain_time < 0.0f) {
if (h->heal_time < game_time() && h->hp < h->max_hp) { if (h[i].heal_time < 0.0f && h[i].hp < h[i].max_hp) {
h->heal_time = game_time() + HP_REGEN_TIME; h[i].heal_time = HP_REGEN_TIME;
h->hp += HP_REGEN_RECOVERY; h[i].hp += HP_REGEN_RECOVERY;
h->hp = zpl_min(h->max_hp, h->hp); 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); Velocity *v = ecs_column(it, Velocity, 1);
for (int i = 0; i < it->count; i++) { 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); 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].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*it->delta_time + zpl_sin(zpl_to_radians(rand()%360))*DEMO_NPC_STEER_SPEED*it->delta_time); 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));
} }
} }

54
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, init)(NAME * h, zpl_allocator a); \
PREFIX void ZPL_JOIN2(FUNC, destroy)(NAME * h); \ PREFIX void ZPL_JOIN2(FUNC, destroy)(NAME * h); \
PREFIX VALUE *ZPL_JOIN2(FUNC, get)(NAME * h, zpl_u64 key); \ 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, set)(NAME * h, zpl_u64 key, VALUE value); \
PREFIX void ZPL_JOIN2(FUNC, grow)(NAME * h); \ 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)(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)(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, 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) \ #define ZPL_TABLE_DEFINE(NAME, FUNC, VALUE) \
void ZPL_JOIN2(FUNC, init)(NAME * h, zpl_allocator a) { \ 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); \ 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_internal zpl_isize ZPL_JOIN2(FUNC, _add_entry)(NAME * h, zpl_u64 key) { \
zpl_isize index; \ zpl_isize index; \
ZPL_JOIN2(NAME, Entry) e = { 0 }; \ ZPL_JOIN2(NAME, Entry) e = { 0 }; \
@ -4373,6 +4385,22 @@ h->hashes = nh.hashes;
h->entries = nh.entries; \ 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) { \ VALUE *ZPL_JOIN2(FUNC, get)(NAME * h, zpl_u64 key) { \
zpl_isize index = ZPL_JOIN2(FUNC, _find)(h, key).entry_index; \ zpl_isize index = ZPL_JOIN2(FUNC, _find)(h, key).entry_index; \
if (index >= 0) return &h->entries[index].value; \ if (index >= 0) return &h->entries[index].value; \
@ -4380,16 +4408,16 @@ return NULL;
} \ } \
\ \
void ZPL_JOIN2(FUNC, remove)(NAME * h, zpl_u64 key) { \ 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); \ zpl_hash_table_find_result fr = ZPL_JOIN2(FUNC, _find)(h, key); \
if (fr.entry_index >= 0) { \ 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_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)) { \ void ZPL_JOIN2(FUNC, map)(NAME * h, void (*map_proc)(zpl_u64 key, VALUE value)) { \
@ -5850,14 +5878,14 @@ ZPL_IMPL_INLINE zpl_u16 zpl_endian_swap16(zpl_u16 i) {
ZPL_IMPL_INLINE zpl_u32 zpl_endian_swap32(zpl_u32 i) { ZPL_IMPL_INLINE zpl_u32 zpl_endian_swap32(zpl_u32 i) {
return (i>>24) |(i<<24) | return (i>>24) |(i<<24) |
((i&0x00ff0000u)>>8) | ((i&0x0000ff00u)<<8); ((i&0x00ff0000u)>>8) | ((i&0x0000ff00u)<<8);
} }
ZPL_IMPL_INLINE zpl_u64 zpl_endian_swap64(zpl_u64 i) { ZPL_IMPL_INLINE zpl_u64 zpl_endian_swap64(zpl_u64 i) {
return (i>>56) | (i<<56) | return (i>>56) | (i<<56) |
((i&0x00ff000000000000ull)>>40) | ((i&0x000000000000ff00ull)<<40) | ((i&0x00ff000000000000ull)>>40) | ((i&0x000000000000ff00ull)<<40) |
((i&0x0000ff0000000000ull)>>24) | ((i&0x0000000000ff0000ull)<<24) | ((i&0x0000ff0000000000ull)>>24) | ((i&0x0000000000ff0000ull)<<24) |
((i&0x000000ff00000000ull)>>8) | ((i&0x00000000ff000000ull)<<8); ((i&0x000000ff00000000ull)>>8) | ((i&0x00000000ff000000ull)<<8);
} }
ZPL_IMPL_INLINE zpl_i32 zpl_next_pow2(zpl_i32 x) { ZPL_IMPL_INLINE zpl_i32 zpl_next_pow2(zpl_i32 x) {
@ -9160,7 +9188,7 @@ zpl_isize zpl_utf8_decode(zpl_u8 const *str, zpl_isize str_len, zpl_rune *codepo
if (!zpl_is_between(b3, 0x80, 0xbf)) goto invalid_codepoint; if (!zpl_is_between(b3, 0x80, 0xbf)) goto invalid_codepoint;
codepoint = (cast(zpl_rune) s0 & 0x07) << 18 | (cast(zpl_rune) b1 & 0x3f) << 12 | (cast(zpl_rune) b2 & 0x3f) << 6 | codepoint = (cast(zpl_rune) s0 & 0x07) << 18 | (cast(zpl_rune) b1 & 0x3f) << 12 | (cast(zpl_rune) b2 & 0x3f) << 6 |
(cast(zpl_rune) b3 & 0x3f); (cast(zpl_rune) b3 & 0x3f);
width = 4; width = 4;
goto end; goto end;