aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2012-05-02 20:46:34 +0000
committerRob Austein <sra@hactrn.net>2012-05-02 20:46:34 +0000
commit960ec3dc294fd941d66661157508312ead2766f7 (patch)
tree6cfb7cf214fa9733413e0423698559621d8f683f
parente65d3153ca2a13e57aa2460e037d51053f6e415a (diff)
More set operations.
svn path=/branches/tk33/; revision=4458
-rw-r--r--rpkid/rpki/resource_set.py110
1 files changed, 91 insertions, 19 deletions
diff --git a/rpkid/rpki/resource_set.py b/rpkid/rpki/resource_set.py
index be39df75..6301f1a5 100644
--- a/rpkid/rpki/resource_set.py
+++ b/rpkid/rpki/resource_set.py
@@ -425,18 +425,24 @@ class resource_set(list):
del set2[0]
return type(self)(result)
+ __or__ = union
+
def intersection(self, other):
"""
Set intersection for resource sets.
"""
return self._comm(other)[2]
+ __and__ = intersection
+
def difference(self, other):
"""
Set difference for resource sets.
"""
return self._comm(other)[0]
+ __sub__ = difference
+
def symmetric_difference(self, other):
"""
Set symmetric difference (XOR) for resource sets.
@@ -444,6 +450,8 @@ class resource_set(list):
com = self._comm(other)
return com[0].union(com[1])
+ __xor__ = symmetric_difference
+
def contains(self, item):
"""
Set membership test for resource sets.
@@ -468,6 +476,8 @@ class resource_set(list):
hi = mid
return lo < len(self) and self[lo].min <= min and self[lo].max >= max
+ __contains__ = contains
+
def issubset(self, other):
"""
Test whether self is a subset (possibly improper) of other.
@@ -477,12 +487,26 @@ class resource_set(list):
return False
return True
+ __le__ = issubset
+
def issuperset(self, other):
"""
Test whether self is a superset (possibly improper) of other.
"""
return other.issubset(self)
+ __ge__ = issuperset
+
+ def __lt__(self, other):
+ return not self.issuperset(other)
+
+ def __gt__(self, other):
+ return not self.issubset(other)
+
+ __eq__ = list.__eq__
+
+ __ne__ = list.__ne__
+
@classmethod
def from_sql(cls, sql, query, args = None):
"""
@@ -730,6 +754,26 @@ class resource_bag(object):
return self
@classmethod
+ def from_str(cls, text):
+ """
+ Parse a comma-separated text string into a resource_bag. Not
+ particularly efficient, fix that if and when it becomes an issue.
+ """
+ asns = []
+ v4s = []
+ v6s = []
+ for word in text.split(","):
+ if "." in word:
+ v4s.append(word)
+ elif ":" in word:
+ v6s.append(word)
+ else:
+ asns.append(word)
+ return cls(asn = resource_set_as(",".join(asns)) if asns else None,
+ v4 = resource_set_ipv4(",".join(v4s)) if v4s else None,
+ v6 = resource_set_ipv6(",".join(v6s)) if v6s else None)
+
+ @classmethod
def from_rfc3779_tuples(cls, exts):
"""
Build a resource_bag from intermediate form generated by RFC 3779
@@ -773,21 +817,49 @@ class resource_bag(object):
Compute intersection with another resource_bag. valid_until
attribute (if any) inherits from self.
"""
- return self.__class__(self.asn.intersection(other.asn),
- self.v4.intersection(other.v4),
- self.v6.intersection(other.v6),
+ return self.__class__(self.asn & other.asn,
+ self.v4 & other.v4,
+ self.v6 & other.v6,
self.valid_until)
+ __and__ = intersection
+
def union(self, other):
"""
Compute union with another resource_bag. valid_until attribute
(if any) inherits from self.
"""
- return self.__class__(self.asn.union(other.asn),
- self.v4.union(other.v4),
- self.v6.union(other.v6),
+ return self.__class__(self.asn | other.asn,
+ self.v4 | other.v4,
+ self.v6 | other.v6,
+ self.valid_until)
+
+ __or__ = union
+
+ def difference(self, other):
+ """
+ Compute difference against another resource_bag. valid_until
+ attribute (if any) inherits from self
+ """
+ return self.__class__(self.asn - other.asn,
+ self.v4 - other.v4,
+ self.v6 - other.v6,
self.valid_until)
+ __sub__ = difference
+
+ def symmetric_difference(self, other):
+ """
+ Compute symmetric difference against another resource_bag.
+ valid_until attribute (if any) inherits from self
+ """
+ return self.__class__(self.asn ^ other.asn,
+ self.v4 ^ other.v4,
+ self.v6 ^ other.v6,
+ self.valid_until)
+
+ __xor__ = symmetric_difference
+
def __str__(self):
s = ""
if self.asn:
@@ -1095,25 +1167,25 @@ if __name__ == "__main__":
v1 = r1._comm(r2)
v2 = r2._comm(r1)
assert v1[0] == v2[1] and v1[1] == v2[0] and v1[2] == v2[2]
- for i in r1: assert r1.contains(i) and r1.contains(i.min) and r1.contains(i.max)
- for i in r2: assert r2.contains(i) and r2.contains(i.min) and r2.contains(i.max)
- for i in v1[0]: assert r1.contains(i) and not r2.contains(i)
- for i in v1[1]: assert not r1.contains(i) and r2.contains(i)
- for i in v1[2]: assert r1.contains(i) and r2.contains(i)
- v1 = r1.union(r2)
- v2 = r2.union(r1)
+ for i in r1: assert i in r1 and i.min in r1 and i.max in r1
+ for i in r2: assert i in r2 and i.min in r2 and i.max in r2
+ for i in v1[0]: assert i in r1 and i not in r2
+ for i in v1[1]: assert i not in r1 and i in r2
+ for i in v1[2]: assert i in r1 and i in r2
+ v1 = r1 | r2
+ v2 = r2 | r1
assert v1 == v2
print "x|y:", v1, testprefix(v1)
- v1 = r1.difference(r2)
- v2 = r2.difference(r1)
+ v1 = r1 - r2
+ v2 = r2 - r1
print "x-y:", v1, testprefix(v1)
print "y-x:", v2, testprefix(v2)
- v1 = r1.symmetric_difference(r2)
- v2 = r2.symmetric_difference(r1)
+ v1 = r1 ^ r2
+ v2 = r2 ^ r1
assert v1 == v2
print "x^y:", v1, testprefix(v1)
- v1 = r1.intersection(r2)
- v2 = r2.intersection(r1)
+ v1 = r1 & r2
+ v2 = r2 & r1
assert v1 == v2
print "x&y:", v1, testprefix(v1)