2011-10-04 3 views
0

Je reçois la première entrée de l'utilisateur qui est un arbre (ayant une hauteur et une profondeur significatives) de nœuds. Chaque noeud contient une regex et des modificateurs. Cet arbre est enregistré en mémoire. Ceci est pris une seule fois au démarrage de l'application.eval ne correspond pas à regex après un certain temps

La deuxième entrée est une valeur qui correspond à partir du nœud racine de l'arbre jusqu'à ce qu'un nœud feuille correspondant exact soit trouvé (Depth First Search). Le match est déterminé comme suit:

my $evalstr = <<EOEVAL; 
if(\$input_value =~ /\$node_regex/$node_modifiers){ 
    1; 
}else{ 
    -1; 
} 
EOEVAL 

no strict 'refs'; 
my $return_value = eval "no strict;$evalstr"; 

La deuxième entrée est fournie en continu tout au long de la durée de vie de l'application par une source. Le code ci-dessus fonctionne très bien pendant un certain temps (environ 10 heures), mais après une entrée continue pendant ce temps, l'eval commence continuellement à échouer et j'obtiens -1 dans $ return_value. Toutes les autres fonctionnalités de l'application fonctionnent très bien, y compris d'autres déclarations de comparaison.Si je redémarre l'application, la correspondance commence à nouveau et donne des résultats appropriés. 112 Je reçois un avertissement de récursivité profonde plusieurs fois, mais j'ai lu quelque part que c'est normal, car la taille de la pile pour moi serait plus de 100 fois, compte tenu de la taille de l'arbre d'entrée. 2) Si j'utilise une logique simple pour une correspondance regex sans eval comme ci-dessus, je n'ai aucun problème pour toute exécution continue de l'application.

if($input_value =~ /$node_regex/){ 
    $return_value=1; 
}else{ 
    $return_value=-1; 
} 

mais je dois sacrifier les modificateurs dynamiques, comme par Dynamic Modifiers

Contrôles: 1) j'ai vérifié $ @ pour mais il est vide. 2) Également imprimées les valeurs respectives de $ input_value, $ node_regex et $ node_modifiers, elles sont correctes et devraient correspondre à la valeur avec regex au point de défaillance. 3) J'ai vérifié l'utilisation de la mémoire, mais c'est assez constant au cours du temps pour le processus Perl. 4) utilisait perl 5.8.8 puis l'a mis à jour en 5.12, mais toujours confronté au même problème.

Question: Quelle pourrait être la cause du problème ci-dessus? Pourquoi cela échoue après un certain temps, mais fonctionne bien lorsque l'application est redémarrée?

+0

D'où vient l'expression régulière? C'est une conjecture sauvage, mais peut-être qu'il se heurte à un retour en arrière catastrophique qui aurait du sens avec la performance dégradant des recherches de plus en plus profondes à travers l'arbre. Pouvez-vous poster quelques expressions rationnelles utilisées? Une partie du texte qu'ils sont censés correspondre? –

+0

Pourquoi auriez-vous besoin du 'non strict;' dans l'eval? Le code ne fonctionne-t-il pas sans cela? – Dallaylaen

+0

En note, que faire si vous pré-compilez les expressions rationnelles et les stockez dans l'arbre au lieu de faire des changements de chaîne tout le temps? Voir: Sur l'initialisation du noeud (ou modification, si l'arbre n'est pas r/o): 'my $ cached_regex = eval" qr/\ $ noeud_regex/$ node_modifiers ";' Et plus tard dans la boucle principale: 'my $ return_value = $ input_value = ~/$ cached_regex /?1: -1; ' – Dallaylaen

Répondre

0

Une réponse définitive nécessiterait plus de connaissances sur les internes perl que j'ai. Mais compte tenu de ce que vous faites, l'analyse continue de grands arbres, il semble sûr de supposer que certaines limites sont atteintes, certaines ressources sont épuisées. Je regarderais les choses de près et je m'assurerais que toutes les ressources sont libérées entre chaque itération d'une analyse. Je serais particulièrement concerné par les références circulaires dans les structures complexes, et en s'assurant qu'il n'y en a pas.

Questions connexes