فهرست منبع

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://svn.code.sf.net/p/rathena/svn/trunk@16935 54d463be-8e91-2dee-dedb-b68131a5f0ec

shennetsind 12 سال پیش
والد
کامیت
0c992d9e23
3فایلهای تغییر یافته به همراه86 افزوده شده و 24 حذف شده
  1. 77 24
      src/map/guild.c
  2. 4 0
      src/map/guild.h
  3. 5 0
      src/map/npc.c

+ 77 - 24
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 */
 }

+ 4 - 0
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);
 

+ 5 - 0
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);