@@ -77,6 +77,12 @@ struct vine_file_replica *vine_file_replica_table_lookup(struct vine_worker_info
7777 return hash_table_lookup (w -> current_files , cachename );
7878}
7979
80+ // count the number of in-cluster replicas of a file
81+ int vine_file_replica_count (struct vine_manager * m , struct vine_file * f )
82+ {
83+ return set_size (hash_table_lookup (m -> file_worker_table , f -> cached_name ));
84+ }
85+
8086// find a worker (randomly) in posession of a specific file, and is ready to transfer it.
8187struct vine_worker_info * vine_file_replica_table_find_worker (struct vine_manager * q , const char * cachename )
8288{
@@ -124,40 +130,21 @@ struct vine_worker_info *vine_file_replica_table_find_worker(struct vine_manager
124130}
125131
126132// trigger replications of file to satisfy temp_replica_count
127- int vine_file_replica_table_replicate (struct vine_manager * m , struct vine_file * f )
133+ int vine_file_replica_table_replicate (struct vine_manager * m , struct vine_file * f , struct set * sources , int to_find )
128134{
129- /* the number of replicated copies in this round */
130- int round_replication_count = 0 ;
131-
132- if (vine_current_transfers_get_table_size (m ) >= hash_table_size (m -> worker_table ) * m -> worker_source_max_transfers ) {
133- return round_replication_count ;
134- }
135-
136- struct set * sources = hash_table_lookup (m -> file_worker_table , f -> cached_name );
137- if (!sources ) {
138- return round_replication_count ;
139- }
140-
141135 int nsources = set_size (sources );
142- int to_find = MIN (m -> temp_replica_count - nsources , m -> transfer_replica_per_cycle );
143- if (to_find < 1 ) {
144- return round_replication_count ;
145- }
146-
147- debug (D_VINE , "Found %d workers holding %s, %d replicas needed" , nsources , f -> cached_name , to_find );
136+ int round_replication_request_sent = 0 ;
148137
149138 /* get the elements of set so we can insert new replicas to sources */
150139 struct vine_worker_info * * sources_frozen = (struct vine_worker_info * * )set_values (sources );
151140 struct vine_worker_info * source ;
152141
153- int i = 0 ;
154- for (source = sources_frozen [i ]; i < nsources ; i ++ ) {
155- if (round_replication_count >= to_find ) {
156- break ;
157- }
142+ for (int i = 0 ; i < nsources ; i ++ ) {
158143
159- int found_per_source = 0 ;
144+ source = sources_frozen [i ];
145+ int dest_found = 0 ;
160146
147+ // skip if the file on the source is not ready to transfer
161148 struct vine_file_replica * replica = hash_table_lookup (source -> current_files , f -> cached_name );
162149 if (!replica || replica -> state != VINE_FILE_REPLICA_STATE_READY ) {
163150 continue ;
@@ -166,51 +153,60 @@ int vine_file_replica_table_replicate(struct vine_manager *m, struct vine_file *
166153 char * source_addr = string_format ("%s/%s" , source -> transfer_url , f -> cached_name );
167154 int source_in_use = vine_current_transfers_source_in_use (m , source );
168155
156+ // skip if the source is busy with other transfers
157+ if (source_in_use >= m -> worker_source_max_transfers ) {
158+ continue ;
159+ }
160+
169161 char * id ;
170- struct vine_worker_info * peer ;
162+ struct vine_worker_info * dest ;
171163 int offset_bookkeep ;
172- HASH_TABLE_ITERATE_RANDOM_START (m -> worker_table , offset_bookkeep , id , peer )
173- {
174164
175- if (found_per_source >= MIN (m -> file_source_max_transfers , to_find )) {
176- break ;
177- }
178-
179- if (source_in_use >= m -> worker_source_max_transfers ) {
180- break ;
181- }
182-
183- if (!peer -> transfer_port_active ) {
165+ HASH_TABLE_ITERATE_RANDOM_START (m -> worker_table , offset_bookkeep , id , dest )
166+ {
167+ // skip if the source and destination are on the same host
168+ if (set_lookup (sources , dest ) || strcmp (source -> hostname , dest -> hostname ) == 0 ) {
184169 continue ;
185170 }
186171
187- if (set_lookup (sources , peer )) {
172+ // skip if the destination is not ready to transfer
173+ if (!dest -> transfer_port_active ) {
188174 continue ;
189175 }
190176
191- if (vine_current_transfers_dest_in_use (m , peer ) >= m -> worker_source_max_transfers ) {
177+ // skip if the destination is busy with other transfers
178+ if (vine_current_transfers_dest_in_use (m , dest ) >= m -> worker_source_max_transfers ) {
192179 continue ;
193180 }
194181
195- if (strcmp (source -> hostname , peer -> hostname ) == 0 ) {
196- continue ;
197- }
182+ debug (D_VINE , "replicating %s from %s to %s" , f -> cached_name , source -> addrport , dest -> addrport );
198183
199- debug ( D_VINE , "replicating %s from %s to %s" , f -> cached_name , source -> addrport , peer -> addrport );
184+ vine_manager_put_url_now ( m , dest , source_addr , f );
200185
201- vine_manager_put_url_now ( m , peer , source_addr , f ) ;
186+ round_replication_request_sent ++ ;
202187
203- source_in_use ++ ;
204- found_per_source ++ ;
205- round_replication_count ++ ;
188+ // break if we have found enough destinations for this source
189+ if (++ dest_found >= MIN (m -> file_source_max_transfers , to_find )) {
190+ break ;
191+ }
192+
193+ // break if the source becomes busy with transfers
194+ if (++ source_in_use >= m -> worker_source_max_transfers ) {
195+ break ;
196+ }
206197 }
207198
208199 free (source_addr );
200+
201+ // break if we have sent enough replication requests for this file
202+ if (round_replication_request_sent >= to_find ) {
203+ break ;
204+ }
209205 }
210206
211207 free (sources_frozen );
212208
213- return round_replication_count ;
209+ return round_replication_request_sent ;
214210}
215211
216212/*
0 commit comments