[Pkg-bazaar-commits] ./bzr/unstable r924: - Add IntSet class

Martin Pool mbp at sourcefrog.net
Fri Apr 10 08:21:28 UTC 2009


------------------------------------------------------------
revno: 924
committer: Martin Pool <mbp at sourcefrog.net>
timestamp: Sun 2005-07-17 14:53:39 -0300
message:
  - Add IntSet class
  
  - Start converting weave calculation to use it
added:
  bzrlib/intset.py
modified:
  bzrlib/weave.py
  tools/testweave.py
-------------- next part --------------
=== added file 'bzrlib/intset.py'
--- a/bzrlib/intset.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/intset.py	2005-07-17 17:53:39 +0000
@@ -0,0 +1,167 @@
+#! /usr/bin/python
+
+# Copyright (C) 2005 Canonical Ltd
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# Author: Martin Pool <mbp at canonical.com>
+
+
+class IntSet(Exception):
+    """Faster set-like class storing only whole numbers.
+
+    Despite the name this stores long integers happily, but negative
+    values are not allowed.
+
+    >>> a = IntSet([0, 2, 5])
+    >>> bool(a)
+    True
+    >>> 2 in a
+    True
+    >>> 4 in a
+    False
+    >>> a.add(4)
+    >>> 4 in a
+    True
+
+    >>> b = IntSet()
+    >>> not b
+    True
+    >>> b.add(10)
+    >>> 10 in a
+    False
+    >>> a.update(b)
+    >>> 10 in a
+    True
+    >>> a.update(range(5))
+    >>> 3 in a
+    True
+
+    Being a set, duplicates are ignored:
+    >>> a = IntSet()
+    >>> a.add(10)
+    >>> a.add(10)
+    >>> 10 in a
+    True
+    >>> list(a)
+    [10]
+    
+    """
+    # __slots__ = ['_val']
+
+    def __init__(self, values=None):
+        """Create a new intset.
+
+        values
+            If specified, an initial collection of values.
+        """
+        self._val = 0
+        if values != None:
+            self.update(values)
+
+
+    def __nonzero__(self):
+        """IntSets are false if empty, otherwise True.
+
+        >>> bool(IntSet())
+        False
+        
+        >>> bool(IntSet([0]))
+        True
+        """
+        return bool(self._val)
+
+
+    def __eq__(self, other):
+        """Comparison."""
+        if isinstance(other, IntSet):
+            return self._val == other._val
+        else:
+            return False
+
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+
+    def __contains__(self, i):
+        assert i >= 0
+        return self._val & (1L << i)
+
+
+    def __iter__(self):
+        """Return contents of set.
+
+        >>> list(IntSet())
+        []
+        >>> list(IntSet([0, 1, 5, 7]))
+        [0, 1, 5, 7]
+        """
+        v = self._val
+        o = 0
+        # XXX: This is a bit slow
+        while v:
+            if v & 1:
+                yield o
+            v = v >> 1
+            o = o + 1
+
+        
+    def update(self, to_add):
+        """Add all the values from the sequence or intset to_add"""
+        if isinstance(to_add, IntSet):
+            self._val |= to_add._val
+        else:
+            for i in to_add:
+                assert i >= 0
+                self._val |= (1L << i)
+
+
+    def add(self, to_add):
+        assert 0 <= to_add
+        self._val |= (1L << to_add)
+
+
+    def remove(self, to_remove):
+        """Remove one value from the set.
+
+        Raises KeyError if the value is not present.
+
+        >>> a = IntSet([10])
+        >>> a.remove(9)
+        Traceback (most recent call last):
+          File "/usr/lib/python2.4/doctest.py", line 1243, in __run
+            compileflags, 1) in test.globs
+          File "<doctest __main__.IntSet.remove[1]>", line 1, in ?
+            a.remove(9)
+        KeyError: 9
+        >>> a.remove(10)
+        >>> not a
+        True
+        """
+        assert 0 <= to_remove
+        m = 1L << to_remove
+        if not self._val & m:
+            raise KeyError(to_remove)
+        self._val ^= m
+        
+        
+            
+    
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
+    

=== modified file 'bzrlib/weave.py'
--- a/bzrlib/weave.py	2005-07-15 22:55:10 +0000
+++ b/bzrlib/weave.py	2005-07-17 17:53:39 +0000
@@ -67,6 +67,7 @@
     del Set, ImmutableSet
 
 
+
 class WeaveError(Exception):
     """Exception in processing weave"""
 
@@ -256,7 +257,9 @@
 
     def inclusions(self, versions):
         """Return set of all ancestors of given version(s)."""
-        i = set(versions)
+        from bzrlib.intset import IntSet
+        
+        i = IntSet(versions)
         v = max(versions)
         try:
             while v >= 0:
@@ -271,6 +274,8 @@
 
     def minimal_parents(self, version):
         """Find the minimal set of parents for the version."""
+        from bzrlib.intset import IntSet
+        
         included = self._v[version]
         if not included:
             return []
@@ -279,7 +284,7 @@
         li.sort(reverse=True)
 
         mininc = []
-        gotit = set()
+        gotit = IntSet()
 
         for pv in li:
             if pv not in gotit:

=== modified file 'tools/testweave.py'
--- a/tools/testweave.py	2005-07-15 22:55:10 +0000
+++ b/tools/testweave.py	2005-07-17 17:53:39 +0000
@@ -26,7 +26,7 @@
 from bzrlib.weave import Weave, WeaveFormatError
 from bzrlib.weavefile import write_weave, read_weave
 from pprint import pformat
-
+from bzrlib.intset import IntSet
 
 
 try:
@@ -118,7 +118,7 @@
                           ('}', 0),
                           ])
 
-        changes = list(k._delta(set([0]),
+        changes = list(k._delta(IntSet([0]),
                                 ['line 1',
                                  'new line']))
 
@@ -522,8 +522,8 @@
                          ["first line",
                           "alternative second line"])
 
-        self.assertEqual(k.inclusions([2]),
-                         set([0, 2]))
+        self.assertEqual(list(k.inclusions([2])),
+                         [0, 2])
 
 
 
@@ -571,8 +571,8 @@
                           (2, 'line from 2'),
                           ])
 
-        self.assertEqual(k.inclusions([3]),
-                         set([0, 1, 2, 3]))
+        self.assertEqual(list(k.inclusions([3])),
+                         [0, 1, 2, 3])
 
         self.log('k._l=' + pformat(k._l))
 



More information about the Pkg-bazaar-commits mailing list