Untested iterative implementation of evaluate

This commit is contained in:
David Adrian 2013-10-11 12:13:42 -04:00
parent 2453404604
commit f2ba9d7621
4 changed files with 111 additions and 8 deletions

View File

@ -24,7 +24,7 @@ void free_stack(stack_t* stack)
xfree(stack); xfree(stack);
} }
void push(stack_t* stack, void* elt) void stack_push(stack_t* stack, void* elt)
{ {
if (stack->cur_size == stack->max_size) { if (stack->cur_size == stack->max_size) {
stack->max_size *= 2; stack->max_size *= 2;
@ -33,8 +33,17 @@ void push(stack_t* stack, void* elt)
stack->arr[stack->cur_size++] = elt; stack->arr[stack->cur_size++] = elt;
} }
void* pop(stack_t* stack) void stack_pop(stack_t* stack)
{ {
void* res = stack->arr[--stack->cur_size]; --stack->cur_size;
return res; }
void* stack_peek(stack_t* stack)
{
return stack->arr[stack->cur_size - 1];
}
int stack_is_empty(stack_t* stack)
{
return (stack->cur_size == 0);
} }

View File

@ -9,7 +9,10 @@ typedef struct stack stack_t;
stack_t* alloc_stack(size_t size); stack_t* alloc_stack(size_t size);
void free_stack(stack_t* stack); void free_stack(stack_t* stack);
void push(stack_t* stack, void* elt); void stack_push(stack_t* stack, void* elt);
void* pop(stack_t* stack); void stack_pop(stack_t* stack);
void* stack_peek(stack_t* stack);
int stack_is_empty(stack_t* stack);
#endif /* ZMAP_STACK_H */ #endif /* ZMAP_STACK_H */

View File

@ -1,6 +1,8 @@
#include "expression.h" #include "expression.h"
#include "fieldset.H" #include "fieldset.h"
#include "../lib/stack.h"
#include "../lib/xalloc.h" #include "../lib/xalloc.h"
/* Static helper functions */ /* Static helper functions */
@ -83,6 +85,7 @@ node_t* make_field_node(char *fieldname)
node_t *node = alloc_node(); node_t *node = alloc_node();
node->type = FIELD; node->type = FIELD;
node->value.field.fieldname = fieldname; node->value.field.fieldname = fieldname;
node->result = 1;
return node; return node;
} }
@ -91,6 +94,7 @@ node_t* make_string_node(char *literal)
node_t *node = alloc_node(); node_t *node = alloc_node();
node->type = STRING; node->type = STRING;
node->value.string_literal = literal; node->value.string_literal = literal;
node->result = 1;
return node; return node;
} }
@ -99,6 +103,7 @@ node_t* make_int_node(int literal)
node_t *node = alloc_node(); node_t *node = alloc_node();
node->type = INT; node->type = INT;
node->value.int_literal = literal; node->value.int_literal = literal;
node->result = 1;
return node; return node;
} }
@ -135,6 +140,88 @@ int evaluate_expression(node_t *root, fieldset_t *fields) {
return 0; return 0;
} }
int evaluate_expression_fast(node_t *root, fieldset_t *fields) {
stack_t* s;
node_t* node;
if (!root) return 1;
s = alloc_stack(16); /* XXX Find a way to guess/know this better */
root->evaluated = 0;
stack_push(s, root);
int result = 1;
while (!stack_is_empty(s) && result) {
node = (node_t *) stack_peek(s);
if (node->type != OP) {
continue;
}
if (node->value.op == AND) {
if (!node->right_child->evaluated) {
stack_push(s, node->right_child);
}
if (!node->left_child->evaluated) {
stack_push(s, node->left_child);
continue;
}
stack_pop(s);
if (!(node->left_child->result && node->right_child->result)) {
node->evaluated = 1;
result = 0;
}
node->left_child->evaluated = 0;
node->right_child->evaluated = 0;
} else if (node->value.op == OR) {
if (!node->right_child->evaluated) {
stack_push(s, node->right_child);
}
if (!node->left_child->evaluated) {
stack_push(s, node->left_child);
continue;
}
stack_pop(s);
if (!(node->left_child->result || node->right_child->result)) {
node->evaluated = 1;
result = 0;
}
node->left_child->evaluated = 0;
node->right_child->evaluated = 0;
} else {
stack_pop(s);
switch (node->value.op) {
case GT:
node->result = eval_gt_node(node, fields);
break;
case LT:
node->result = eval_lt_node(node, fields);
break;
case EQ:
node->result = eval_eq_node(node, fields);
break;
case NEQ:
node->result = !(eval_eq_node(node, fields));
break;
case LT_EQ:
node->result = eval_lt_eq_node(node, fields);
break;
case GT_EQ:
node->result = eval_gt_eq_node(node, fields);
break;
default:
exit(-1);
break;
}
node->evaluated = 1;
if (stack_is_empty(s)) {
result = node->result;
node->evaluated = 0;
}
}
}
free_stack(s);
return result;
}
void print_expression(node_t *root) { void print_expression(node_t *root) {
if (!root) return; if (!root) return;
printf("%s", "( "); printf("%s", "( ");

View File

@ -23,8 +23,8 @@ struct field_id {
union node_value { union node_value {
struct field_id field; struct field_id field;
char *string_literal;
uint64_t int_literal; uint64_t int_literal;
char *string_literal;
enum operation op; enum operation op;
}; };
@ -33,6 +33,8 @@ typedef struct node {
struct node *right_child; struct node *right_child;
enum node_type type; enum node_type type;
union node_value value; union node_value value;
int evaluated;
int result;
} node_t; } node_t;
node_t* make_op_node(enum operation op); node_t* make_op_node(enum operation op);
@ -45,6 +47,8 @@ node_t* make_int_node(int literal);
int evaluate_expression(node_t *root, fieldset_t *fields); int evaluate_expression(node_t *root, fieldset_t *fields);
int evaluate_expression_fast(node_t *root, fieldset_t *fields);
void print_expression(node_t *root); void print_expression(node_t *root);
#endif /* ZMAP_TREE_H */ #endif /* ZMAP_TREE_H */