diff options
author | shennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-11-20 08:31:41 +0000 |
---|---|---|
committer | shennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-11-20 08:31:41 +0000 |
commit | f8b4fc65481df7c8c3d831677763387d7effb863 (patch) | |
tree | 410d75d065ecd6f46e92c5c4cc435c8314dd139e | |
parent | 8adeaff2469269a8579337067c94de28c1c5623c (diff) | |
download | hercules-f8b4fc65481df7c8c3d831677763387d7effb863.tar.gz hercules-f8b4fc65481df7c8c3d831677763387d7effb863.tar.bz2 hercules-f8b4fc65481df7c8c3d831677763387d7effb863.tar.xz hercules-f8b4fc65481df7c8c3d831677763387d7effb863.zip |
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
-rw-r--r-- | src/map/guild.c | 101 | ||||
-rw-r--r-- | src/map/guild.h | 4 | ||||
-rw-r--r-- | src/map/npc.c | 5 |
3 files changed, 86 insertions, 24 deletions
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 */ } diff --git a/src/map/guild.h b/src/map/guild.h index 0773063ef..3e7b98f59 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -100,6 +100,10 @@ void guild_agit_end(void); void guild_agit2_start(void); void guild_agit2_end(void); +/* guild flag cachin */ +void guild_flag_add(struct npc_data *nd); +void guild_flag_remove(struct npc_data *nd); +void guild_flags_clear(void); void guild_guildaura_refresh(struct map_session_data *sd, int skill_num, int skill_lv); diff --git a/src/map/npc.c b/src/map/npc.c index f3a939c2c..189ae953f 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1838,6 +1838,8 @@ int npc_unload(struct npc_data* nd, bool single) { nd->u.scr.label_list_num = 0; } } + if( nd->u.scr.guild_id ) + guild_flag_remove(nd); } script_stop_sleeptimers(nd->bl.id); @@ -3594,6 +3596,9 @@ int npc_reload(void) { struct s_mapiterator* iter; struct block_list* bl; + /* clear guild flag cache */ + guild_flags_clear(); + npc_clear_pathlist(); db_clear(npc_path_db); |