]> arthur.barton.de Git - bup.git/commitdiff
bloom.py: move bloom.ShaBloom.create to just bloom.create.
authorAvery Pennarun <apenwarr@gmail.com>
Thu, 17 Feb 2011 02:39:35 +0000 (18:39 -0800)
committerAvery Pennarun <apenwarr@gmail.com>
Thu, 17 Feb 2011 02:59:30 +0000 (18:59 -0800)
I don't really like class-level functions.  Ideally we'd just move all the
creation stuff into cmd/bloom, but tbloom.py is testing them, so it's not
really worth it.

Signed-off-by: Avery Pennarun <apenwarr@gmail.com>
cmd/bloom-cmd.py
lib/bup/bloom.py
lib/bup/t/tbloom.py

index 033ad85f190c8b1a4bce787bf96dc7a7e57a3ada..47b4294ba7eec5fac62110b7a54a766c32886f9b 100755 (executable)
@@ -98,7 +98,7 @@ def do_bloom(path, outfilename):
     if b is None:
         tfname = os.path.join(path, 'bup.tmp.bloom')
         tf = open(tfname, 'w+')
-        b = bloom.ShaBloom.create(tfname, f=tf, expected=add_count, k=opt.k)
+        b = bloom.create(tfname, f=tf, expected=add_count, k=opt.k)
     count = 0
     icount = 0
     for name in add:
index 1c40dfe6db2f02ce41c0a88fe9300d006bf69b3a..5444fd5d0a67717e561bb23d92800a36dcfa1ade 100644 (file)
@@ -96,8 +96,7 @@ bloom_add = _helpers.bloom_add
 
 
 class ShaBloom:
-    """Wrapper which contains data from multiple index files.
-    """
+    """Wrapper which contains data from multiple index files. """
     def __init__(self, filename, f=None, readwrite=False, expected=-1):
         self.name = filename
         self.rwfile = None
@@ -193,42 +192,48 @@ class ShaBloom:
 
     def add_idx(self, ix):
         """Add the object to the filter, return current pfalse_positive."""
-        if not self.map: raise Exception, "Cannot add to closed bloom"
+        if not self.map:
+            raise Exception("Cannot add to closed bloom")
         self.entries += bloom_add(self.map, ix.shatable, self.bits, self.k)
         self.idxnames.append(os.path.basename(ix.name))
 
     def exists(self, sha):
-        """Return nonempty if the object probably exists in the bloom filter."""
+        """Return nonempty if the object probably exists in the bloom filter.
+
+        If this function returns false, the object definitely does not exist.
+        If it returns true, there is a small probability that it exists
+        anyway, so you'll have to check it some other way.
+        """
         global _total_searches, _total_steps
         _total_searches += 1
-        if not self.map: return None
+        if not self.map:
+            return None
         found, steps = bloom_contains(self.map, str(sha), self.bits, self.k)
         _total_steps += steps
         return found
 
-    @classmethod
-    def create(cls, name, expected, delaywrite=None, f=None, k=None):
-        """Create and return a bloom filter for `expected` entries."""
-        bits = int(math.floor(math.log(expected*MAX_BITS_EACH/8,2)))
-        k = k or ((bits <= MAX_BLOOM_BITS[5]) and 5 or 4)
-        if bits > MAX_BLOOM_BITS[k]:
-            log('bloom: warning, max bits exceeded, non-optimal\n')
-            bits = MAX_BLOOM_BITS[k]
-        debug1('bloom: using 2^%d bytes and %d hash functions\n' % (bits, k))
-        f = f or open(name, 'w+b')
-        f.write('BLOM')
-        f.write(struct.pack('!IHHI', BLOOM_VERSION, bits, k, 0))
-        assert(f.tell() == 16)
-        # NOTE: On some systems this will not extend+zerofill, but it does on
-        # darwin, linux, bsd and solaris.
-        f.truncate(16+2**bits)
-        f.seek(0)
-        if delaywrite != None and not delaywrite:
-            # tell it to expect very few objects, forcing a direct mmap
-            expected = 1
-        return cls(name, f=f, readwrite=True, expected=expected)
-
     def __len__(self):
         return int(self.entries)
 
 
+def create(name, expected, delaywrite=None, f=None, k=None):
+    """Create and return a bloom filter for `expected` entries."""
+    bits = int(math.floor(math.log(expected*MAX_BITS_EACH/8,2)))
+    k = k or ((bits <= MAX_BLOOM_BITS[5]) and 5 or 4)
+    if bits > MAX_BLOOM_BITS[k]:
+        log('bloom: warning, max bits exceeded, non-optimal\n')
+        bits = MAX_BLOOM_BITS[k]
+    debug1('bloom: using 2^%d bytes and %d hash functions\n' % (bits, k))
+    f = f or open(name, 'w+b')
+    f.write('BLOM')
+    f.write(struct.pack('!IHHI', BLOOM_VERSION, bits, k, 0))
+    assert(f.tell() == 16)
+    # NOTE: On some systems this will not extend+zerofill, but it does on
+    # darwin, linux, bsd and solaris.
+    f.truncate(16+2**bits)
+    f.seek(0)
+    if delaywrite != None and not delaywrite:
+        # tell it to expect very few objects, forcing a direct mmap
+        expected = 1
+    return ShaBloom(name, f=f, readwrite=True, expected=expected)
+
index adc0decc4ef7f7b949930b9fdb18293fcc335ee4..de89e6641e0f0d9aac8debd2ad18cad356d122d5 100644 (file)
@@ -12,7 +12,7 @@ def test_bloom():
     ix.name='dummy.idx'
     ix.shatable = ''.join(hashes)
     for k in (4, 5):
-        b = bloom.ShaBloom.create('pybuptest.bloom', expected=100, k=k)
+        b = bloom.create('pybuptest.bloom', expected=100, k=k)
         b.add_idx(ix)
         WVPASSLT(b.pfalse_positive(), .1)
         b.close()
@@ -29,10 +29,9 @@ def test_bloom():
         os.unlink('pybuptest.bloom')
 
     tf = tempfile.TemporaryFile()
-    b = bloom.ShaBloom.create('bup.bloom', f=tf, expected=100)
+    b = bloom.create('bup.bloom', f=tf, expected=100)
     WVPASSEQ(b.rwfile, tf)
     WVPASSEQ(b.k, 5)
     tf = tempfile.TemporaryFile()
-    b = bloom.ShaBloom.create('bup.bloom', f=tf, expected=2**28,
-                              delaywrite=False)
+    b = bloom.create('bup.bloom', f=tf, expected=2**28, delaywrite=False)
     WVPASSEQ(b.k, 4)