Skip to content
This repository was archived by the owner on Jun 27, 2018. It is now read-only.

Commit debb8cc

Browse files
author
Joshua Reich
committed
un-nest sequential helper function
1 parent 3a3b6ec commit debb8cc

File tree

1 file changed

+83
-90
lines changed

1 file changed

+83
-90
lines changed

pyretic/core/classifier.py

Lines changed: 83 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -174,107 +174,100 @@ def _cross(r1,r2):
174174

175175
def __rshift__(c1, c2):
176176
from pyretic.core.language import match, modify, drop, identity, Controller, CountBucket, DerivedPolicy
177-
def _sequence_actions_classifier(acts, c2):
178-
def _sequence_action_classifier(act, c2):
179-
# given a test b and an action p, return a test
180-
# b' such that p >> b == b' >> p.
181-
def _commute_test(act, pkts):
182-
while isinstance(act, DerivedPolicy):
183-
act = act.policy
184-
if act == identity:
185-
return pkts
186-
elif act == drop:
187-
return drop
188-
elif act == Controller or isinstance(act, CountBucket):
189-
return identity
190-
elif isinstance(act, modify):
191-
new_match_dict = {}
192-
if pkts == identity:
193-
return identity
194-
elif pkts == drop:
195-
return drop
196-
for f, v in pkts.map.iteritems():
197-
if f in act.map and act.map[f] == v:
198-
continue
199-
elif f in act.map and act.map[f] != v:
200-
return drop
201-
else:
202-
new_match_dict[f] = v
203-
if len(new_match_dict) == 0:
204-
return identity
205-
return match(**new_match_dict)
206-
else:
207-
# TODO (cole) use compile error.
208-
# TODO (cole) what actions are allowable?
209-
raise TypeError
210-
211-
# sequentially compose actions. a1 must be a
212-
# single action. Returns a list of actions.
213-
def _sequence_actions(a1, as2):
214-
while isinstance(a1, DerivedPolicy):
215-
a1 = a1.policy
216-
# TODO: be uniform about returning copied or modified objects.
217-
new_actions = []
218-
if a1 == drop:
219-
return [drop]
220-
elif a1 == identity:
221-
return as2
222-
elif a1 == Controller or isinstance(a1, CountBucket):
223-
return [a1]
224-
elif isinstance(a1, modify):
225-
for a2 in as2:
226-
while isinstance(a2, DerivedPolicy):
227-
a2 = a2.policy
228-
new_a1 = modify(**a1.map.copy())
229-
if a2 == drop:
230-
new_actions.append(drop)
231-
elif a2 == Controller or isinstance(a2, CountBucket):
232-
new_actions.append(a2)
233-
elif a2 == identity:
234-
new_actions.append(new_a1)
235-
elif isinstance(a2, modify):
236-
new_a1.map.update(a2.map)
237-
new_actions.append(new_a1)
238-
else:
239-
raise TypeError
240-
return new_actions
241-
else:
242-
raise TypeError
243-
# END _commute_test and _sequence_actions
244-
245-
c3 = Classifier()
246-
for r2 in c2.rules:
247-
pkts = _commute_test(act, r2.match)
177+
def _sequence_action_classifier(act, c2):
178+
# given a test b and an action p, return a test
179+
# b' such that p >> b == b' >> p.
180+
def _commute_test(act, pkts):
181+
while isinstance(act, DerivedPolicy):
182+
act = act.policy
183+
if act == identity:
184+
return pkts
185+
elif act == drop:
186+
return drop
187+
elif act == Controller or isinstance(act, CountBucket):
188+
return identity
189+
elif isinstance(act, modify):
190+
new_match_dict = {}
248191
if pkts == identity:
249-
acts = _sequence_actions(act, r2.actions)
250-
c3.append(Rule(identity, acts))
251-
break
192+
return identity
252193
elif pkts == drop:
253-
continue
254-
else:
255-
acts = _sequence_actions(act, r2.actions)
256-
c3.append(Rule(pkts, acts))
257-
if len(c3) == 0:
258-
c3.append(Rule(identity, [drop]))
259-
return c3
260-
261-
# END _sequence_action_classifier
262-
263-
c3 = Classifier([Rule(identity, [drop])])
264-
for act in acts:
265-
c3 = c3 + _sequence_action_classifier(act, c2)
194+
return drop
195+
for f, v in pkts.map.iteritems():
196+
if f in act.map and act.map[f] == v:
197+
continue
198+
elif f in act.map and act.map[f] != v:
199+
return drop
200+
else:
201+
new_match_dict[f] = v
202+
if len(new_match_dict) == 0:
203+
return identity
204+
return match(**new_match_dict)
205+
else:
206+
# TODO (cole) use compile error.
207+
# TODO (cole) what actions are allowable?
208+
raise TypeError
209+
210+
# sequentially compose actions. a1 must be a
211+
# single action. Returns a list of actions.
212+
def _sequence_actions(a1, as2):
213+
while isinstance(a1, DerivedPolicy):
214+
a1 = a1.policy
215+
# TODO: be uniform about returning copied or modified objects.
216+
new_actions = []
217+
if a1 == drop:
218+
return [drop]
219+
elif a1 == identity:
220+
return as2
221+
elif a1 == Controller or isinstance(a1, CountBucket):
222+
return [a1]
223+
elif isinstance(a1, modify):
224+
for a2 in as2:
225+
while isinstance(a2, DerivedPolicy):
226+
a2 = a2.policy
227+
new_a1 = modify(**a1.map.copy())
228+
if a2 == drop:
229+
new_actions.append(drop)
230+
elif a2 == Controller or isinstance(a2, CountBucket):
231+
new_actions.append(a2)
232+
elif a2 == identity:
233+
new_actions.append(new_a1)
234+
elif isinstance(a2, modify):
235+
new_a1.map.update(a2.map)
236+
new_actions.append(new_a1)
237+
else:
238+
raise TypeError
239+
return new_actions
240+
else:
241+
raise TypeError
242+
# END _commute_test and _sequence_actions
243+
244+
c3 = Classifier()
245+
for r2 in c2.rules:
246+
pkts = _commute_test(act, r2.match)
247+
if pkts == identity:
248+
acts = _sequence_actions(act, r2.actions)
249+
c3.append(Rule(identity, acts))
250+
break
251+
elif pkts == drop:
252+
continue
253+
else:
254+
acts = _sequence_actions(act, r2.actions)
255+
c3.append(Rule(pkts, acts))
256+
if len(c3) == 0:
257+
c3.append(Rule(identity, [drop]))
266258
return c3
267259

268-
# END _sequence_actions_classifier
269-
260+
# END _sequence_action_classifier
270261

271262
# core __rshift__ logic begins here.
272263
# start with an empty set of rules for the output classifier
273264
# then for each rule in the first classifier (self)
274265
c3 = Classifier()
275266
for r1 in c1.rules:
276267
# sequence the actions in second classifier c2 w/ respect to r1
277-
c2_seqd = _sequence_actions_classifier(r1.actions, c2)
268+
c2_seqd = Classifier([Rule(identity, [drop])])
269+
for act in r1.actions:
270+
c2_seqd = c2_seqd + _sequence_action_classifier(act, c2)
278271

279272
# for each rule in the sequenced c2,
280273
# intersect the rule's match with r1's match

0 commit comments

Comments
 (0)