Begin preparing to split accept nodes and non-accept nodes.

Create a new ProtoState class that will encapsulate the split, but for
this patch it will just contain what was done previously with NodeSet

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2011-12-15 05:08:31 -08:00
parent 9d374d4726
commit d452f53576
3 changed files with 43 additions and 30 deletions

View file

@ -571,22 +571,6 @@ void label_nodes(Node *root);
unsigned long hash_NodeSet(NodeSet *ns);
void flip_tree(Node *node);
/* Comparison operator for sets of <NodeSet *>.
* Compare set hashes, and if the sets have the same hash
* do compare pointer comparison on set of <Node *>, the pointer comparison
* allows us to determine which Sets of <Node *> we have seen already from
* new ones when constructing the DFA.
*/
struct deref_less_than {
bool operator()(pair<unsigned long, NodeSet *>const &lhs,
pair<unsigned long, NodeSet *>const &rhs)const
{
if (lhs.first == rhs.first)
return *(lhs.second) < *(rhs.second);
else
return lhs.first < rhs.first;
}
};
class MatchFlag: public AcceptNode {
public:

View file

@ -45,12 +45,11 @@ ostream &operator<<(ostream &os, const State &state)
}
State *DFA::add_new_state(NodeMap &nodemap,
pair<unsigned long, NodeSet *> index,
NodeSet *nodes, State *other, dfa_stats_t &stats)
{
State *state = new State(nodemap.size(), nodes, other);
states.push_back(state);
nodemap.insert(make_pair(index, state));
nodemap.insert(make_pair(ProtoState(nodes), state));
stats.proto_sum += nodes->size();
if (nodes->size() > stats.proto_max)
stats.proto_max = nodes->size();
@ -62,16 +61,15 @@ State *DFA::find_target_state(NodeMap &nodemap, list<State *> &work_queue,
{
State *target;
pair<unsigned long, NodeSet *> index = make_pair(hash_NodeSet(nodes), nodes);
ProtoState index(nodes);
map<pair<unsigned long, NodeSet *>, State *, deref_less_than>::iterator x = nodemap.find(index);
map<ProtoState, State *, deref_less_than>::iterator x = nodemap.find(index);
if (x == nodemap.end()) {
/* set of nodes isn't known so create new state, and nodes to
* state mapping
*/
target = add_new_state(nodemap, index, nodes, nonmatching,
stats);
target = add_new_state(nodemap, nodes, nonmatching, stats);
work_queue.push_back(target);
} else {
/* set of nodes already has a mapping so free this one */
@ -161,13 +159,10 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root)
NodeMap nodemap;
NodeSet *emptynode = new NodeSet;
nonmatching = add_new_state(nodemap,
make_pair(hash_NodeSet(emptynode), emptynode),
emptynode, NULL, stats);
nonmatching = add_new_state(nodemap, emptynode, NULL, stats);
NodeSet *first = new NodeSet(root->firstpos);
start = add_new_state(nodemap, make_pair(hash_NodeSet(first), first),
first, nonmatching, stats);
start = add_new_state(nodemap, first, nonmatching, stats);
/* the work_queue contains the states that need to have their
* transitions computed. This could be done with a recursive
@ -212,7 +207,7 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root)
dump_node_to_dfa();
for (NodeMap::iterator i = nodemap.begin(); i != nodemap.end(); i++)
delete i->first.second;
delete i->first.nodes;
nodemap.clear();
if (flags & (DFA_DUMP_STATS))

View file

@ -39,6 +39,40 @@ typedef list<State *> Partition;
uint32_t accept_perms(NodeSet *state, uint32_t *audit_ctl, int *error);
/*
* ProtoState - NodeSet and ancillery information used to create a state
*/
class ProtoState {
public:
unsigned long hash;
NodeSet *nodes;
ProtoState(NodeSet *n): nodes(n)
{
hash = hash_NodeSet(n);
}
};
/* Comparison operator for a ProtoState
* Compare set hashes, and if the sets have the same hash
* do compare pointer comparison on set of <Node *>, the pointer comparison
* allows us to determine which Sets of <Node *> we have seen already from
* new ones when constructing the DFA.
*/
struct deref_less_than {
bool operator()(ProtoState const &lhs, ProtoState const &rhs)const
{
if (lhs.hash == rhs.hash) {
if (lhs.nodes->size() == rhs.nodes->size())
return *(lhs.nodes) < *(rhs.nodes);
else
return lhs.nodes->size() < rhs.nodes->size();
} else {
return lhs.hash < rhs.hash;
}
}
};
/*
* State - DFA individual state information
* label: a unique label to identify the state used for pretty printing
@ -86,7 +120,8 @@ public:
ostream &operator<<(ostream &os, const State &state);
typedef map<pair<unsigned long, NodeSet *>, State *, deref_less_than> NodeMap;
typedef map<ProtoState, State *, deref_less_than> NodeMap;
/* Transitions in the DFA. */
/* dfa_stats - structure to group various stats about dfa creation
@ -102,7 +137,6 @@ typedef struct dfa_stats {
class DFA {
void dump_node_to_dfa(void);
State *add_new_state(NodeMap &nodemap,
pair<unsigned long, NodeSet *> index,
NodeSet *nodes, State *other, dfa_stats_t &stats);
void update_state_transitions(NodeMap &nodemap,
list<State *> &work_queue,