Don't request manifests that are already in the fetch queue

This commit is contained in:
Jeremy Lakeman 2013-02-15 09:12:01 +10:30
parent 2193d8fb74
commit e4d6520c46
3 changed files with 28 additions and 2 deletions

View File

@ -361,6 +361,7 @@ int rhizome_ignore_manifest_check(unsigned char *bid_prefix, int prefix_len);
#define MAX_CANDIDATES 16
int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sockaddr_in *peerip,const unsigned char peersid[SID_SIZE]);
rhizome_manifest * rhizome_fetch_search(unsigned char *id, int prefix_length);
typedef struct rhizome_http_request {
struct sched_ent alarm;

View File

@ -1422,8 +1422,13 @@ int rhizome_is_bar_interesting(unsigned char *bar){
DEBUGF("Ignoring %s", id_hex);
return 0;
}
// do we have this bundle [or later]?
// are we already fetching this bundle [or later]?
rhizome_manifest *m=rhizome_fetch_search(&bar[RHIZOME_BAR_PREFIX_OFFSET], RHIZOME_BAR_PREFIX_BYTES);
if (m && m->version >= version)
return 0;
// do we have this bundle [or later]?
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
sqlite3_stmt *statement = sqlite_prepare(&retry,
"SELECT id, version FROM manifests WHERE id like ? and version >= ?");

View File

@ -854,6 +854,26 @@ static void rhizome_start_next_queued_fetches(struct sched_ent *alarm)
rhizome_start_next_queued_fetch(&rhizome_fetch_queues[i].active);
}
/* Search all fetch slots, including active downloads, for a matching manifest */
rhizome_manifest * rhizome_fetch_search(unsigned char *id, int prefix_length){
int i, j;
for (i = 0; i < NQUEUES; ++i) {
struct rhizome_fetch_queue *q = &rhizome_fetch_queues[i];
if (q->active.state != RHIZOME_FETCH_FREE &&
memcmp(id, q->active.manifest->cryptoSignPublic, prefix_length) == 0)
return q->active.manifest;
for (j = 0; j < q->candidate_queue_size; j++) {
struct rhizome_fetch_candidate *c = &q->candidate_queue[j];
if (c->manifest && memcmp(id, c->manifest->cryptoSignPublic, prefix_length) == 0)
return c->manifest;
}
}
return NULL;
}
/* Queue a fetch for the payload of the given manifest. If 'peerip' is not NULL, then it is used as
* the port and IP address of an HTTP server from which the fetch is performed. Otherwise the fetch
* is performed over MDP.