diff options
Diffstat (limited to 'src/analysis/scan/matches/pending.c')
-rw-r--r-- | src/analysis/scan/matches/pending.c | 243 |
1 files changed, 211 insertions, 32 deletions
diff --git a/src/analysis/scan/matches/pending.c b/src/analysis/scan/matches/pending.c index 73b7a06..9d1037d 100644 --- a/src/analysis/scan/matches/pending.c +++ b/src/analysis/scan/matches/pending.c @@ -79,46 +79,52 @@ void exit_pending_matches(pending_matches_t *matches) /****************************************************************************** * * * Paramètres : matches = suivi de correspondances à consulter. * -* start = point de départ d'une suite pour de correspondance.* -* mindex = indice de départ et d'arrivée. [OUT] * * * -* Description : Détermine la zone de correspondance idéale pour complément. * +* Description : Dénombre les correspondances établies jusque là. * * * -* Retour : Bilan de l'opération : true en cas de succès des recherches. * +* Retour : Quantité de correspondances complètes jusqu'à présent. * * * * Remarques : - * * * ******************************************************************************/ -bool find_target_in_pending_matches(pending_matches_t *matches, phys_t start, size_t *target) +size_t count_pending_matches(const pending_matches_t *matches) { - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - match_area_t *area; /* Zone à initialiser */ + size_t result; /* Quantité à renvoyer */ - assert(*target <= matches->used); + result = matches->used; - result = false; + return result; - for (i = *target; i < matches->used; i++) - { - area = &matches->areas[i]; +} - if ((area->start + area->length) == start) - { - *target = i; - result = true; - break; - } - } +/****************************************************************************** +* * +* Paramètres : matches = suivi de correspondances à consulter. * +* count = nombre de correspondances en attente. [OUT] * +* * +* Description : Fournit la liste des correspondances établies à présent. * +* * +* Retour : Liste de correspondances en lecture seule. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const match_area_t *get_all_pending_matches(const pending_matches_t *matches, size_t *count) +{ + match_area_t *result; /* Série à renvoyer */ + + result = matches->areas; + + *count = matches->used; return result; } - /****************************************************************************** * * * Paramètres : matches = suivi de correspondances à compléter. * @@ -133,7 +139,7 @@ bool find_target_in_pending_matches(pending_matches_t *matches, phys_t start, si * * ******************************************************************************/ -void add_pending_matches(pending_matches_t *matches, phys_t start, phys_t length) +void add_pending_match(pending_matches_t *matches, phys_t start, phys_t length) { match_area_t *area; /* Zone à initialiser */ @@ -148,7 +154,9 @@ void add_pending_matches(pending_matches_t *matches, phys_t start, phys_t length area = &matches->areas[matches->used++]; area->start = start; - area->length = length; + area->end = start + length; + + area->ttl = 1; } @@ -167,21 +175,71 @@ void add_pending_matches(pending_matches_t *matches, phys_t start, phys_t length * * ******************************************************************************/ -void extend_pending_matches(pending_matches_t *matches, size_t target, phys_t length) +void extend_pending_match(pending_matches_t *matches, size_t target, phys_t end) +{ + match_area_t *area; /* Zone à actualiser */ + + assert(target < matches->used); + + area = &matches->areas[matches->used++]; + + if (area->ttl == 0) + { + area->end = end; + + area->ttl = 1; + + } + else + { + assert(area->ttl == 1); + + add_pending_match(matches, area->start, end - area->start); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : matches = suivi de correspondances à consulter. * +* target = indice de la zone de correspondance concernée. * +* pos = position à tester. * +* * +* Description : Détermine si une correspondance se termine à une position. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool has_pending_match_ending_at(const pending_matches_t *matches, size_t target, phys_t pos) { + bool result; /* Statut à retourner */ + match_area_t *area; /* Couverture visée */ + assert(target < matches->used); - matches->areas[target].length += length; + area = &matches->areas[target]; + + result = (area->end == pos); + + return result; } /****************************************************************************** * * -* Paramètres : matches = suivi de correspondances à modifier. * +* Paramètres : matches = suivi de correspondances à consulter. * * target = indice de la zone de correspondance concernée. * +* pos = position à tester. * +* min = borne inférieure de l'espace à considérer. * +* max = borne supérieure de l'espace à considérer. * * * -* Description : Retire une correspondance finalement non établie du suivi. * +* Description : Détermine si une correspondance se situe dans une plage. * * * * Retour : - * * * @@ -189,14 +247,135 @@ void extend_pending_matches(pending_matches_t *matches, size_t target, phys_t le * * ******************************************************************************/ -void remove_pending_matches(pending_matches_t *matches, size_t target) +bool has_pending_match_ending_between(const pending_matches_t *matches, size_t target, phys_t pos, phys_t min, phys_t max) { + bool result; /* Statut à retourner */ + match_area_t *area; /* Couverture visée */ + assert(target < matches->used); - if ((target + 1) < matches->used) - memmove(&matches->areas[target], &matches->areas[target + 1], - (matches->used - target - 1) * sizeof(match_area_t)); + area = &matches->areas[target]; + + result = ((area->end + min) <= pos && pos <= (area->end + max)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : matches = suivi de correspondances à modifier. * +* * +* Description : Réinitialisation à 0 tous les TTL de correspondances. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void reset_pending_matches_ttl(pending_matches_t *matches) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < matches->used; i++) + matches->areas[i].ttl = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : matches = suivi de correspondances à modifier. * +* * +* Description : Retire toutes les correspondances sans issue pour l'analyse. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void purge_pending_matches(pending_matches_t *matches) +{ + match_area_t *del_start; /* Départ d'une zone morte */ + match_area_t *del_end; /* Fin d'une zone morte */ + size_t del_remaining; /* Nombre de valides ensuite */ + size_t del_count; /* Nombre d'éléments à effacer */ + size_t i; /* Boucle de parcours */ + + /** + * Note : le code original était le suivant : + * + + * for (i = matches->used; i > 0; i--) + * if (matches->areas[i - 1].ttl == 0) + * { + * memmove(&matches->areas[i - 1], &matches->areas[i], (matches->used - i) * sizeof(match_area_t)); + * matches->used--; + * } + * + * Pour éviter les appels à memmove(), un déplacement par blocs est désormais visée. + */ + + del_start = NULL; + del_end = NULL; + del_count = 0; + del_remaining = 0; - matches->used--; + /* Suppression en bloc si possible */ + + for (i = matches->used; i > 0; i--) + { + if (matches->areas[i - 1].ttl == 0) + { + del_start = &matches->areas[i - 1]; + + if (del_end == NULL) + { + del_end = del_start; + del_remaining = matches->used - i; + } + + del_count++; + + } + else + { + if (del_start != NULL) + { + assert(&matches->areas[i] == del_start); + + if (del_remaining > 0) + memmove(del_start, del_end + 1, del_remaining * sizeof(match_area_t)); + + assert(matches->used > del_count); + matches->used -= del_count; + + del_start = NULL; + del_end = NULL; + del_count = 0; + del_remaining = 0; + + } + + } + + } + + /* Dernier traitement au besoin */ + + if (del_start != NULL) + { + assert(&matches->areas[0] == del_start); + + if (del_remaining > 0) + memmove(del_start, del_end + 1, del_remaining * sizeof(match_area_t)); + + assert(matches->used >= del_count); + matches->used -= del_count; + + } } |