summaryrefslogtreecommitdiff
path: root/src/analysis/scan/patterns/tokens
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2024-03-03 11:54:51 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2024-03-03 11:54:51 (GMT)
commit7f25bd904e483ca90548c7001839a102090eb290 (patch)
treed19c48beb00ce3d3bbc38e5f801896f9ae406f99 /src/analysis/scan/patterns/tokens
parent28ef52f37784817c6590cdafc94aa9b356123802 (diff)
Use a global allocator to store (partial) matches.
Diffstat (limited to 'src/analysis/scan/patterns/tokens')
-rw-r--r--src/analysis/scan/patterns/tokens/node.h1
-rw-r--r--src/analysis/scan/patterns/tokens/nodes/any.c10
-rw-r--r--src/analysis/scan/patterns/tokens/nodes/masked.c169
-rw-r--r--src/analysis/scan/patterns/tokens/nodes/plain.c163
4 files changed, 218 insertions, 125 deletions
diff --git a/src/analysis/scan/patterns/tokens/node.h b/src/analysis/scan/patterns/tokens/node.h
index 55bf0a8..5b1a247 100644
--- a/src/analysis/scan/patterns/tokens/node.h
+++ b/src/analysis/scan/patterns/tokens/node.h
@@ -33,6 +33,7 @@
#include "../backend.h"
#include "../../context.h"
#include "../../matches/bytes.h"
+#include "../../../../glibext/umemslice.h"
#define G_TYPE_SCAN_TOKEN_NODE g_scan_token_node_get_type()
diff --git a/src/analysis/scan/patterns/tokens/nodes/any.c b/src/analysis/scan/patterns/tokens/nodes/any.c
index d65f3c9..4334fff 100644
--- a/src/analysis/scan/patterns/tokens/nodes/any.c
+++ b/src/analysis/scan/patterns/tokens/nodes/any.c
@@ -52,7 +52,7 @@ static void g_scan_token_node_any_finalize(GScanTokenNodeAny *);
/* Inscrit la définition d'un motif dans un moteur de recherche. */
-static bool g_scan_token_node_any_enroll(GScanTokenNodeAny *, GScanContext *, GEngineBackend *, size_t, size_t *);
+static bool g_scan_token_node_any_enroll(GScanTokenNodeAny *, GEngineBackend *, size_t, size_t *);
/* Transforme les correspondances locales en trouvailles. */
static void g_scan_token_node_any_check_forward(const GScanTokenNodeAny *, scan_node_check_params_t *, TokenNodeCheckFlags, bool *);
@@ -264,7 +264,6 @@ void g_scan_token_node_any_merge(GScanTokenNodeAny *any, GScanTokenNodeAny *extr
/******************************************************************************
* *
* Paramètres : node = définition de la bribe à enregistrer. *
-* context = contexte de l'analyse à mener. *
* backend = moteur de recherche à préchauffer. *
* maxsize = taille max. des atomes (mise en commun optimisée). *
* slow = niveau de ralentissement induit (0 = idéal). [OUT] *
@@ -277,7 +276,7 @@ void g_scan_token_node_any_merge(GScanTokenNodeAny *any, GScanTokenNodeAny *extr
* *
******************************************************************************/
-static bool g_scan_token_node_any_enroll(GScanTokenNodeAny *node, GScanContext *context, GEngineBackend *backend, size_t maxsize, size_t *slow)
+static bool g_scan_token_node_any_enroll(GScanTokenNodeAny *node, GEngineBackend *backend, size_t maxsize, size_t *slow)
{
bool result; /* Statut à retourner */
bool forced; /* Inclusion dans un scan ? */
@@ -370,7 +369,7 @@ static void g_scan_token_node_any_check_forward(const GScanTokenNodeAny *node, s
if (match_size <= size)
{
- size -= match_size;
+ size -= (match_size - 1);
assert(cflags & TNCF_UPDATE_IN_PLACE);
@@ -382,10 +381,11 @@ static void g_scan_token_node_any_check_forward(const GScanTokenNodeAny *node, s
space->end = space->start + match_size;
add_tail_match_area(space, &params->main_areas);
- params->main_count++;
}
+ params->main_count += size;
+
}
}
diff --git a/src/analysis/scan/patterns/tokens/nodes/masked.c b/src/analysis/scan/patterns/tokens/nodes/masked.c
index 4941e0e..5194cb8 100644
--- a/src/analysis/scan/patterns/tokens/nodes/masked.c
+++ b/src/analysis/scan/patterns/tokens/nodes/masked.c
@@ -475,15 +475,18 @@ static void g_scan_token_node_masked_check_forward(const GScanTokenNodeMasked *n
#ifndef NDEBUG
bool forced; /* Inclusion dans un scan ? */
#endif
+ match_area_t **areas; /* Liste de zones à constituer */
+ size_t *count; /* Taille de cette liste */
+ bool copy; /* Besoin d'une copie ? */
+ bool inverted; /* Inversion des bilans ? */
size_t i; /* Boucle de parcours #1 */
const tracked_scan_atom_t *atom; /* Atome correspondant */
- GUMemSlice *atoms; /* Localisations des bribes */
- const umem_slice_iter_t *aiter; /* Boucle de parcours #2 */
- match_area_t *end; /* Borne de fin de parcours */
- match_area_t *pos; /* Position courante */
- bool status; /* Bilan d'une correspondance */
+ match_area_t *atoms; /* Localisations des bribes */
+ bool first_round; /* Premier tour de traitement */
match_area_t *area; /* Correspondance à valider */
match_area_t *next; /* Correspondance suivante */
+ phys_t start; /* Début potentiel de motif */
+ bool status; /* Bilan d'une correspondance */
phys_t after; /* Espace disposible après */
phys_t min_end; /* Fin la plus proche possible */
phys_t max_end; /* Fin la plus éloignée trouvée*/
@@ -514,101 +517,145 @@ static void g_scan_token_node_masked_check_forward(const GScanTokenNodeMasked *n
if (!params->initialized)
{
+ /* Destinations établies une fois pour toutes */
+
+ if (cflags & TNCF_KEEP_DISCARDED)
+ {
+ areas = &params->kept_areas;
+ count = &params->kept_count;
+
+ copy = false;
+ inverted = true;
+
+ }
+
+ else if (cflags & TNCF_CREATE_NEW)
+ {
+ areas = &params->created_areas;
+ count = &params->created_count;
+
+ copy = true;
+ inverted = false;
+
+ }
+
+ else
+ {
+ assert(cflags & TNCF_UPDATE_IN_PLACE);
+
+ areas = &params->main_areas;
+ count = &params->main_count;
+
+ copy = false;
+ inverted = false;
+
+ }
+
+ /* Parcours des combinaisons enregistrées */
+
for (i = 0; i < node->enrolled_count; i++)
{
atom = &node->enrolled_atoms[i];
atoms = g_scan_context_get_atom_matches(params->context, atom->pid);
+ first_round = (*count == 0);
+
if (atom->fast_check)
{
- for (aiter = g_umem_slice_get_iter(atoms); aiter != NULL; aiter = aiter->next)
- {
- end = aiter->data_end;
+ /**
+ * Toutes les correspondances sont validées d'office car le motif identifié
+ * correspondant au motif complet.
+ */
- for (pos = aiter->data; pos < end; pos++)
+ if (!inverted)
+ {
+ for_each_match_area(area, atoms)
{
/**
* La modification de la zone d'origine est possible dans tous les cas
* car cette zone a été allouée de façon dédiée à un type de correspondances
* et ne sera pas réutilisée comme autre source de correspondance ailleurs.
*/
- pos->end = pos->start + atom->len;
- if (cflags & TNCF_KEEP_DISCARDED)
- {
- add_tail_match_area(pos, &params->kept_areas);
- params->kept_count++;
- }
-
- else if (cflags & TNCF_CREATE_NEW)
- {
- add_tail_match_area(pos, &params->created_areas);
- params->created_count++;
- }
+ assert(area->end >= atom->len);
- else
- {
- assert(cflags & TNCF_UPDATE_IN_PLACE);
+ area->start = area->end - atom->len;
- add_tail_match_area(pos, &params->main_areas);
- params->main_count++;
-
- }
+ (*count)++;
}
}
+ else
+ atoms = NULL;
+
}
else
{
- for (aiter = g_umem_slice_get_iter(atoms); aiter != NULL; aiter = aiter->next)
+ for_each_match_area_safe(area, &atoms, next)
{
- end = aiter->data_end;
+ start = area->end - atom->len - atom->pos;
- for (pos = aiter->data; pos < end; pos++)
+ status = check_scan_token_node_masked_content(node->bytes, node->len,
+ start, params->content);
+
+ if (status)
{
- status = check_scan_token_node_masked_content(node->bytes, node->len,
- pos->start, params->content);
+ /**
+ * La modification de la zone d'origine est possible dans tous les cas
+ * car cette zone a été allouée de façon dédiée à un type de correspondances
+ * et ne sera pas réutilisée comme autre source de correspondance ailleurs.
+ */
- if (status)
+ if (!inverted)
{
- /**
- * La modification de la zone d'origine est possible dans tous les cas
- * car cette zone a été allouée de façon dédiée à un type de correspondances
- * et ne sera pas réutilisée comme autre source de correspondance ailleurs.
- */
- pos->end = pos->start + node->len;
-
- if (cflags & TNCF_KEEP_DISCARDED)
- {
- add_tail_match_area(pos, &params->kept_areas);
- params->kept_count++;
- }
-
- else if (cflags & TNCF_CREATE_NEW)
- {
- add_tail_match_area(pos, &params->created_areas);
- params->created_count++;
- }
-
- else
- {
- assert(cflags & TNCF_UPDATE_IN_PLACE);
-
- add_tail_match_area(pos, &params->main_areas);
- params->main_count++;
-
- }
+ area->start = start;
+ area->end += atom->rem;
+
+ (*count)++;
}
+ else
+ del_match_area(area, &atoms);
+
+ }
+
+ else
+ {
+ /**
+ * Les principes de modifications restent valables, même inversés.
+ */
+ if (inverted)
+ {
+ area->start = start;
+ area->end += atom->rem;
+
+ (*count)++;
+
+ }
+ else
+ del_match_area(area, &atoms);
}
}
+
+ }
+
+ /* Mise à jour de la liste */
+
+ if (atoms != NULL)
+ {
+ if (first_round)
+ *areas = atoms;
+
+ else
+ merge_match_areas(areas, &atoms);
+
}
}
diff --git a/src/analysis/scan/patterns/tokens/nodes/plain.c b/src/analysis/scan/patterns/tokens/nodes/plain.c
index 71e2e9b..5dd45df 100644
--- a/src/analysis/scan/patterns/tokens/nodes/plain.c
+++ b/src/analysis/scan/patterns/tokens/nodes/plain.c
@@ -654,16 +654,19 @@ static void g_scan_token_node_plain_check_forward(const GScanTokenNodePlain *nod
{
bool track_path; /* Conservation du chemin */
bool nocase; /* Pas d'intérêt pour la casse */
+ match_area_t **areas; /* Liste de zones à constituer */
+ size_t *count; /* Taille de cette liste */
+ bool copy; /* Besoin d'une copie ? */
+ bool inverted; /* Inversion des bilans ? */
size_t i; /* Boucle de parcours #1 */
- const sized_binary_t *raw; /* Données brutes d'origine */
const tracked_scan_atom_t *atom; /* Atome correspondant */
- GUMemSlice *atoms; /* Localisations des bribes */
- const umem_slice_iter_t *aiter; /* Boucle de parcours #2 */
- match_area_t *end; /* Borne de fin de parcours */
- match_area_t *pos; /* Position courante */
- bool status; /* Bilan d'une correspondance */
+ match_area_t *atoms; /* Localisations des bribes */
+ bool first_round; /* Premier tour de traitement */
match_area_t *area; /* Correspondance à valider */
+ const sized_binary_t *raw; /* Données brutes d'origine */
match_area_t *next; /* Correspondance suivante */
+ phys_t start; /* Début potentiel de motif */
+ bool status; /* Bilan d'une correspondance */
phys_t after; /* Espace disposible après */
phys_t min_end; /* Fin la plus proche possible */
phys_t max_end; /* Fin la plus éloignée trouvée*/
@@ -689,98 +692,128 @@ static void g_scan_token_node_plain_check_forward(const GScanTokenNodePlain *nod
*/
if (!params->initialized)
{
+ /* Destinations établies une fois pour toutes */
+
+ if (cflags & TNCF_KEEP_DISCARDED)
+ {
+ areas = &params->kept_areas;
+ count = &params->kept_count;
+
+ copy = false;
+ inverted = true;
+
+ }
+
+ else if (cflags & TNCF_CREATE_NEW)
+ {
+ areas = &params->created_areas;
+ count = &params->created_count;
+
+ copy = true;
+ inverted = false;
+
+ }
+
+ else
+ {
+ assert(cflags & TNCF_UPDATE_IN_PLACE);
+
+ areas = &params->main_areas;
+ count = &params->main_count;
+
+ copy = false;
+ inverted = false;
+
+ }
+
+ /* Parcours des combinaisons enregistrées */
+
for (i = 0; i < node->count; i++)
{
- raw = &node->raw[i];
atom = &node->atoms[i];
atoms = g_scan_context_get_atom_matches(params->context, atom->pid);
+ first_round = (*count == 0);
+
if (atom->fast_check)
{
- for (aiter = g_umem_slice_get_iter(atoms); aiter != NULL; aiter = aiter->next)
- {
- end = aiter->data_end;
+ /**
+ * Toutes les correspondances sont validées d'office car le motif identifié
+ * correspondant au motif complet.
+ */
- for (pos = aiter->data; pos < end; pos++)
+ if (!inverted)
+ {
+ for_each_match_area(area, atoms)
{
/**
* La modification de la zone d'origine est possible dans tous les cas
* car cette zone a été allouée de façon dédiée à un type de correspondances
* et ne sera pas réutilisée comme autre source de correspondance ailleurs.
*/
- pos->end = pos->start + atom->len;
- if (cflags & TNCF_KEEP_DISCARDED)
- {
- add_tail_match_area(pos, &params->kept_areas);
- params->kept_count++;
- }
-
- else if (cflags & TNCF_CREATE_NEW)
- {
- add_tail_match_area(pos, &params->created_areas);
- params->created_count++;
- }
-
- else
- {
- assert(cflags & TNCF_UPDATE_IN_PLACE);
+ assert(area->end >= atom->len);
- add_tail_match_area(pos, &params->main_areas);
- params->main_count++;
+ area->start = area->end - atom->len;
- }
+ (*count)++;
}
}
+ else
+ atoms = NULL;
+
}
else
{
- for (aiter = g_umem_slice_get_iter(atoms); aiter != NULL; aiter = aiter->next)
+ raw = &node->raw[i];
+
+ for_each_match_area_safe(area, &atoms, next)
{
- end = aiter->data_end;
+ start = area->end - atom->len - atom->pos;
- for (pos = aiter->data; pos < end; pos++)
+ status = check_scan_token_node_plain_content(raw, atom, nocase, start, params->content);
+
+ if (status)
{
- status = check_scan_token_node_plain_content(raw, atom, nocase,
- pos->start - atom->pos, params->content);
+ /**
+ * La modification de la zone d'origine est possible dans tous les cas
+ * car cette zone a été allouée de façon dédiée à un type de correspondances
+ * et ne sera pas réutilisée comme autre source de correspondance ailleurs.
+ */
- if (status)
+ if (!inverted)
{
- /**
- * La modification de la zone d'origine est possible dans tous les cas
- * car cette zone a été allouée de façon dédiée à un type de correspondances
- * et ne sera pas réutilisée comme autre source de correspondance ailleurs.
- */
- pos->start -= atom->pos;
- pos->end = pos->start + raw->len;
+ area->start = start;
+ area->end += atom->rem;
- if (cflags & TNCF_KEEP_DISCARDED)
- {
- add_tail_match_area(pos, &params->kept_areas);
- params->kept_count++;
- }
+ (*count)++;
- else if (cflags & TNCF_CREATE_NEW)
- {
- add_tail_match_area(pos, &params->created_areas);
- params->created_count++;
- }
+ }
+ else
+ del_match_area(area, &atoms);
- else
- {
- assert(cflags & TNCF_UPDATE_IN_PLACE);
+ }
- add_tail_match_area(pos, &params->main_areas);
- params->main_count++;
+ else
+ {
+ /**
+ * Les principes de modifications restent valables, même inversés.
+ */
+ if (inverted)
+ {
+ area->start = start;
+ area->end += atom->rem;
- }
+ (*count)++;
}
+ else
+ del_match_area(area, &atoms);
}
@@ -789,6 +822,18 @@ static void g_scan_token_node_plain_check_forward(const GScanTokenNodePlain *nod
}
+ /* Mise à jour de la liste */
+
+ if (atoms != NULL)
+ {
+ if (first_round)
+ *areas = atoms;
+
+ else
+ merge_match_areas(areas, &atoms);
+
+ }
+
}
}