Range sets¶
Cluster node names being typically indexed, common node sets rely heavily on
numerical range sets. The RangeSet
module provides two public classes
to deal directly with such range sets, RangeSet
and
RangeSetND
, presented in the following sections.
RangeSet class¶
The RangeSet
class implements a mutable, ordered set of cluster node
indexes (over a single dimension) featuring a fast range-based API. This class
is used by the NodeSet
class (see NodeSet class). Since
version 1.6, RangeSet
actually derives from the standard Python set
class (Python sets), and thus provides methods like RangeSet.union()
,
RangeSet.intersection()
, RangeSet.difference()
,
RangeSet.symmetric_difference()
and their in-place versions
RangeSet.update()
, RangeSet.intersection_update()
,
RangeSet.difference_update()
and
RangeSet.symmetric_difference_update()
.
In v1.9, the implementation of zero-based padding of indexes (e.g. 001) has
been improved. The inner set contains indexes as strings with the padding
included, which allows the use of mixed length zero-padded indexes (eg. using
both 01 and 001 is valid and supported in the same object). Prior to v1.9,
zero-padding was a simple display feature of fixed length per
RangeSet
object, and indexes where stored as integers in the inner
set.
To iterate over indexes as strings with zero-padding included, you can now
iterate over the RangeSet
object (RangeSet.__iter__()
),
or still use the RangeSet.striter()
method which has not changed.
To iterate over the set's indexes as integers, you may use the new method
RangeSet.intiter()
, which is the equivalent of iterating over the
RangeSet
object before v1.9.
RangeSetND class¶
The RangeSetND
class builds a N-dimensional RangeSet mutable object
and provides the common set methods. This class is public and may be used
directly, however we think it is less convenient to manipulate that
NodeSet
and does not necessarily provide the same one-dimension
optimization (see Multidimensional considerations). Several constructors are
available, using RangeSet objects, strings or individual multidimensional
tuples, for instance:
>>> from ClusterShell.RangeSet import RangeSet, RangeSetND
>>> r1 = RangeSet("1-5/2")
>>> list(r1)
['1', '3', '5']
>>> r2 = RangeSet("10-12")
>>> r3 = RangeSet("0-4/2")
>>> r4 = RangeSet("10-12")
>>> print r1, r2, r3, r4
1,3,5 10-12 0,2,4 10-12
>>> rnd = RangeSetND([[r1, r2], [r3, r4]])
>>> print rnd
0-5; 10-12
>>> print list(rnd)
[('0', '10'), ('0', '11'), ('0', '12'), ('1', '10'), ('1', '11'), ('1', '12'), ('2', '10'), ('2', '11'), ('2', '12'), ('3', '10'), ('3', '11'), ('3', '12'), ('4', '10'), ('4', '11'), ('4', '12'), ('5', '10'), ('5', '11'), ('5', '12')]
>>> r1 = RangeSetND([(0, 4), (0, 5), (1, 4), (1, 5)])
>>> len(r1)
4
>>> str(r1)
'0-1; 4-5\n'
>>> r2 = RangeSetND([(1, 4), (1, 5), (1, 6), (2, 5)])
>>> str(r2)
'1; 4-6\n2; 5\n'
>>> r = r1 & r2
>>> str(r)
'1; 4-5\n'
>>> list(r)
[('1', '4'), ('1', '5')]