[apparmor] [PATCH 07/10] Add a new class hashedNodeSet. It is the functional equivalent of ProtoState. We do this to provide a new level of abstraction that ProtoState can leverage, when the node types are split.

John Johansen john.johansen at canonical.com
Fri Oct 28 19:19:34 UTC 2011


Signed-off-by: John Johansen <john.johansen at canonical.com>
---
 parser/libapparmor_re/hfa.cc |   12 +++++++++---
 parser/libapparmor_re/hfa.h  |   27 +++++++++++++++++++++++----
 2 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/parser/libapparmor_re/hfa.cc b/parser/libapparmor_re/hfa.cc
index bcfd2de..c805467 100644
--- a/parser/libapparmor_re/hfa.cc
+++ b/parser/libapparmor_re/hfa.cc
@@ -61,6 +61,12 @@ State *DFA::find_target_state(NodeMap &nodemap, list<State *> &work_queue,
 {
 	State *target;
 
+	pair<set<hashedNodeSet>::iterator,bool> uniq = uniq_nodes.insert(hashedNodeSet(nodes));
+	if (uniq.second == false) {
+		delete(nodes);
+		nodes = uniq.first->nodes;
+	}
+
 	ProtoState index(nodes);
 
 	map<ProtoState, State *>::iterator x = nodemap.find(index);
@@ -74,7 +80,6 @@ State *DFA::find_target_state(NodeMap &nodemap, list<State *> &work_queue,
 	} else {
 		/* set of nodes already has a mapping so free this one */
 		stats.duplicates++;
-		delete(nodes);
 		target = x->second;
 	}
 
@@ -206,8 +211,9 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root)
 	if (flags & DFA_DUMP_NODE_TO_DFA)
 		dump_node_to_dfa();
 
-	for (NodeMap::iterator i = nodemap.begin(); i != nodemap.end(); i++)
-		delete i->first.nodes;
+	for (set<hashedNodeSet>::iterator i = uniq_nodes.begin(); i != uniq_nodes.end(); i++)
+		delete i->nodes;
+	uniq_nodes.clear();
 	nodemap.clear();
 
 	if (flags & (DFA_DUMP_STATS))
diff --git a/parser/libapparmor_re/hfa.h b/parser/libapparmor_re/hfa.h
index 29c552f..8719eb4 100644
--- a/parser/libapparmor_re/hfa.h
+++ b/parser/libapparmor_re/hfa.h
@@ -40,19 +40,19 @@ 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
+ * hashedNodes - for efficient set comparison
  */
-class ProtoState {
+class hashedNodeSet {
 public:
 	unsigned long hash;
 	NodeSet *nodes;
 
-	ProtoState(NodeSet *n): nodes(n)
+	hashedNodeSet(NodeSet *n): nodes(n)
 	{
 		hash = hash_NodeSet(n);
 	}
 
-	bool operator<(ProtoState const &rhs)const
+	bool operator<(hashedNodeSet const &rhs)const
 	{
 		if (hash == rhs.hash) {
 			if (nodes->size() == rhs.nodes->size())
@@ -66,6 +66,21 @@ public:
 };
 
 /*
+ * ProtoState - NodeSet and ancillery information used to create a state
+ */
+class ProtoState {
+public:
+	NodeSet *nodes;
+
+	ProtoState(NodeSet *n): nodes(n) { };
+	bool operator<(ProtoState const &rhs)const
+	{
+		return nodes < rhs.nodes;
+	}
+
+};
+
+/*
  * State - DFA individual state information
  * label: a unique label to identify the state used for pretty printing
  *        the non-matching state is setup to have label == 0 and
@@ -135,6 +150,10 @@ class DFA {
 				      State *state, dfa_stats_t &stats);
 	State *find_target_state(NodeMap &nodemap, list<State *> &work_queue,
 				 NodeSet *nodes, dfa_stats_t &stats);
+
+	/* temporary values used during computations */
+	set<hashedNodeSet> uniq_nodes;
+
 public:
 	DFA(Node *root, dfaflags_t flags);
 	virtual ~DFA();
-- 
1.7.5.4




More information about the AppArmor mailing list