From f8b4fc65481df7c8c3d831677763387d7effb863 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Tue, 20 Nov 2012 08:31:41 +0000 Subject: Minor performance improvement; created guild flag cache to replace the inefficient npcdb lookup, in perspective: Before: whenever a guild emblem was changed it'd loop through all npcs looking for flags belongin to that guild Now: whenever a guild emblem is changed it'll loop through a very small list which contains all guild flags, and from there it'll update the flags accordingly. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16935 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/guild.c | 101 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 24 deletions(-) (limited to 'src/map/guild.c') diff --git a/src/map/guild.c b/src/map/guild.c index e639301f9..9eeae7cf1 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -65,6 +65,10 @@ struct{ int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data); static int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data); +/* guild flags cache */ +struct npc_data **guild_flags; +unsigned short guild_flags_count; + /*========================================== * Retrieves and validates the sd pointer for this guild member [Skotlex] *------------------------------------------*/ @@ -1153,16 +1157,11 @@ int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data) dbi_destroy(iter); } {// update npcs (flags or other npcs that used flagemblem to attach to this guild) - // TODO this is not efficient [FlavioJS] - struct s_mapiterator* iter = mapit_geteachnpc(); - TBL_NPC* nd; - for( nd = (TBL_NPC*)mapit_first(iter) ; mapit_exists(iter); nd = (TBL_NPC*)mapit_next(iter) ) - { - if( nd->subtype != SCRIPT || nd->u.scr.guild_id != guild_id ) - continue; - clif_guild_emblem_area(&nd->bl); + for( i = 0; i < guild_flags_count; i++ ) { + if( guild_flags[i] && guild_flags[i]->u.scr.guild_id == guild_id ) { + clif_guild_emblem_area(&guild_flags[i]->bl); + } } - mapit_free(iter); } return 0; } @@ -2029,11 +2028,53 @@ bool guild_isallied(int guild_id, int guild_id2) return( i < MAX_GUILDALLIANCE && g->alliance[i].opposition == 0 ); } +void guild_flag_add(struct npc_data *nd) { + int i; + + /* check */ + for( i = 0; i < guild_flags_count; i++ ) { + if( guild_flags[i] && guild_flags[i]->bl.id == nd->bl.id ) { + return;/* exists, most likely updated the id. */ + } + } + + i = guild_flags_count;/* save the current slot */ + /* add */ + RECREATE(guild_flags,struct npc_data*,++guild_flags_count); + /* save */ + guild_flags[i] = nd; +} + +void guild_flag_remove(struct npc_data *nd) { + int i, cursor; + if( guild_flags_count == 0 ) + return; + /* find it */ + for( i = 0; i < guild_flags_count; i++ ) { + if( guild_flags[i] && guild_flags[i]->bl.id == nd->bl.id ) {/* found */ + guild_flags[i] = NULL; + break; + } + } + + /* compact list */ + for( i = 0, cursor = 0; i < guild_flags_count; i++ ) { + if( guild_flags[i] == NULL ) + continue; + + if( cursor != i ) { + memmove(&guild_flags[cursor], &guild_flags[i], sizeof(struct npc_data*)); + } + + cursor++; + } + +} + /** * @see DBApply */ -static int eventlist_db_final(DBKey key, DBData *data, va_list ap) -{ +static int eventlist_db_final(DBKey key, DBData *data, va_list ap) { struct eventlist *next = NULL; struct eventlist *current = db_data2ptr(data); while (current != NULL) { @@ -2047,8 +2088,7 @@ static int eventlist_db_final(DBKey key, DBData *data, va_list ap) /** * @see DBApply */ -static int guild_expcache_db_final(DBKey key, DBData *data, va_list ap) -{ +static int guild_expcache_db_final(DBKey key, DBData *data, va_list ap) { ers_free(expcache_ers, db_data2ptr(data)); return 0; } @@ -2056,8 +2096,7 @@ static int guild_expcache_db_final(DBKey key, DBData *data, va_list ap) /** * @see DBApply */ -static int guild_castle_db_final(DBKey key, DBData *data, va_list ap) -{ +static int guild_castle_db_final(DBKey key, DBData *data, va_list ap) { struct guild_castle* gc = db_data2ptr(data); if( gc->temp_guardians ) aFree(gc->temp_guardians); @@ -2065,14 +2104,26 @@ static int guild_castle_db_final(DBKey key, DBData *data, va_list ap) return 0; } -void do_init_guild(void) -{ - guild_db=idb_alloc(DB_OPT_RELEASE_DATA); - castle_db=idb_alloc(DB_OPT_BASE); - guild_expcache_db=idb_alloc(DB_OPT_BASE); - guild_infoevent_db=idb_alloc(DB_OPT_BASE); - expcache_ers = ers_new(sizeof(struct guild_expcache),"guild.c::expcache_ers",ERS_OPT_NONE); +/* called when scripts are reloaded/unloaded */ +void guild_flags_clear(void) { + int i; + for( i = 0; i < guild_flags_count; i++ ) { + if( guild_flags[i] ) + guild_flags[i] = NULL; + } + + guild_flags_count = 0; +} +void do_init_guild(void) { + guild_db = idb_alloc(DB_OPT_RELEASE_DATA); + castle_db = idb_alloc(DB_OPT_BASE); + guild_expcache_db = idb_alloc(DB_OPT_BASE); + guild_infoevent_db = idb_alloc(DB_OPT_BASE); + expcache_ers = ers_new(sizeof(struct guild_expcache),"guild.c::expcache_ers",ERS_OPT_NONE); + + guild_flags_count = 0; + sv_readdb(db_path, "castle_db.txt", ',', 4, 5, -1, &guild_read_castledb); memset(guild_skill_tree,0,sizeof(guild_skill_tree)); @@ -2084,11 +2135,13 @@ void do_init_guild(void) add_timer_interval(gettick()+GUILD_SEND_XY_INVERVAL,guild_send_xy_timer,0,0,GUILD_SEND_XY_INVERVAL); } -void do_final_guild(void) -{ +void do_final_guild(void) { + db_destroy(guild_db); castle_db->destroy(castle_db,guild_castle_db_final); guild_expcache_db->destroy(guild_expcache_db,guild_expcache_db_final); guild_infoevent_db->destroy(guild_infoevent_db,eventlist_db_final); ers_destroy(expcache_ers); + + aFree(guild_flags);/* never empty; created on boot */ } -- cgit v1.2.3-60-g2f50