summaryrefslogtreecommitdiff
path: root/src/analysis/scan/matches/pending.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/scan/matches/pending.c')
-rw-r--r--src/analysis/scan/matches/pending.c243
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;
+
+ }
}