summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-11-20 08:31:41 +0000
committershennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-11-20 08:31:41 +0000
commitf8b4fc65481df7c8c3d831677763387d7effb863 (patch)
tree410d75d065ecd6f46e92c5c4cc435c8314dd139e
parent8adeaff2469269a8579337067c94de28c1c5623c (diff)
downloadhercules-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.c101
-rw-r--r--src/map/guild.h4
-rw-r--r--src/map/npc.c5
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);