Rev 2619: Add FileCollection support class. in http://people.ubuntu.com/~robertc/baz2.0/file-collection

Robert Collins robertc at robertcollins.net
Sat Jul 14 11:08:04 BST 2007


At http://people.ubuntu.com/~robertc/baz2.0/file-collection

------------------------------------------------------------
revno: 2619
revision-id: robertc at robertcollins.net-20070714100801-bo0gezkinkusmtr3
parent: robertc at robertcollins.net-20070714093531-n1kt1ch73qxhfw8i
committer: Robert Collins <robertc at robertcollins.net>
branch nick: file-collection
timestamp: Sat 2007-07-14 20:08:01 +1000
message:
  Add FileCollection support class.
added:
  bzrlib/file_collection.py      file_collection.py-20070714100753-j2zz4ahtk331k5zm-1
  bzrlib/tests/test_file_collection.py test_file_collection-20070714093417-5gc9d821to85zo4t-1
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
=== added file 'bzrlib/file_collection.py'
--- a/bzrlib/file_collection.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/file_collection.py	2007-07-14 10:08:01 +0000
@@ -0,0 +1,76 @@
+# Copyright (C) 2007 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
+
+"""A collection of file names which is persisted on a transport."""
+
+from bzrlib.lazy_import import lazy_import
+lazy_import(globals(), """
+from bzrlib import (
+        errors,
+        )
+""")
+
+
+class FileCollection(object):
+    """A collection of file names.
+
+    The file names are persisted to a file on a transport, and cand be
+    added, removed and initialised.
+
+    The set of names are stored in a flat file, one name per line.
+    New names are allocated sequentially.
+    Initialisation creates an empty file.
+
+    This is intended to support management of modest numbers of files in 
+    write-locked environments which may be read from unlistable transports.
+    
+    The save method must be called to cause the state to be saved to the
+    transport.
+
+    Finally, load is used to obtain a previously saved set.
+    """
+
+    def __init__(self, transport, index_name):
+        """Create a collection on transport called index_name."""
+        self._transport = transport
+        self._index_name = index_name
+        self._names = None
+        self._cap = 10000
+
+    def allocate(self):
+        for number in xrange(self._cap):
+            if str(number) not in self._names:
+                self._names.add(str(number))
+                return str(number)
+        raise errors.BzrError('too many files')
+
+    def initialise(self):
+        """Initialise the collection record on disk."""
+        self._names = set()
+
+    def load(self):
+        """Load the names from the transport."""
+        self._names = set(self._transport.get_bytes(
+            self._index_name).split('\n'))
+
+    def names(self):
+        """What are the names in this collection?"""
+        return frozenset(self._names)
+
+    def save(self):
+        """Save the set of names."""
+        self._transport.put_bytes(self._index_name, '\n'.join(self._names))
+

=== added file 'bzrlib/tests/test_file_collection.py'
--- a/bzrlib/tests/test_file_collection.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test_file_collection.py	2007-07-14 10:08:01 +0000
@@ -0,0 +1,85 @@
+# Copyright (C) 2007 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
+
+"""Tests for the FileCollection class."""
+
+from bzrlib import errors
+from bzrlib.file_collection import FileCollection
+from bzrlib.tests import TestCaseWithMemoryTransport
+from bzrlib.transport import get_transport
+
+
+class TestFileCollection(TestCaseWithMemoryTransport):
+
+    def test_initialise(self):
+        t = self.get_transport()
+        for name in ('index', '00index'):
+            collection = FileCollection(t, name)
+            collection.initialise()
+            self.assertFalse(t.has(name))
+            collection.save()
+            self.assertEqual('', t.get_bytes(name))
+        
+    def test_allocate_trivial(self):
+        t = self.get_transport()
+        collection = FileCollection(t, 'index')
+        collection.initialise()
+        name = collection.allocate()
+        self.assertEqual('0', name)
+        self.assertFalse(t.has('index'))
+        name = collection.allocate()
+        self.assertEqual('1', name)
+        self.assertFalse(t.has('index'))
+
+    def test_allocate_overrun(self):
+        t = self.get_transport()
+        collection = FileCollection(t, 'index')
+        collection.initialise()
+        collection._cap = 5
+        for number in xrange(5):
+            name = collection.allocate()
+        self.assertRaises(errors.BzrError, collection.allocate)
+
+    def test_load(self):
+        t = self.get_transport()
+        collection = FileCollection(t, 'index')
+        collection.initialise()
+        collection.allocate()
+        collection.allocate()
+        collection.save()
+        collection = FileCollection(t, 'index')
+        collection.load()
+        self.assertEqual(set(['0', '1']), collection.names())
+
+    def test_names(self):
+        t = self.get_transport()
+        collection = FileCollection(t, 'index')
+        collection.initialise()
+        collection.allocate()
+        collection.allocate()
+        self.assertEqual(set(['0', '1']), collection.names())
+
+    def test_names_on_unlistable_works(self):
+        t = self.get_transport()
+        collection = FileCollection(t, 'index')
+        collection.initialise()
+        collection.allocate()
+        collection.allocate()
+        collection.save()
+        collection = FileCollection(
+            get_transport('unlistable+' + self.get_url()), 'index')
+        collection.load()
+        self.assertEqual(set(['0', '1']), collection.names())

=== modified file 'NEWS'
--- a/NEWS	2007-07-14 09:35:31 +0000
+++ b/NEWS	2007-07-14 10:08:01 +0000
@@ -50,6 +50,9 @@
     * New transport decorator 'unlistable+' which disables the list_dir
       functionality for testing.
 
+    * New ``file_collection.FileCollection`` support class which mananges names
+      for unlistable transport situations. (Robert Collins)
+
   TESTING:
 
     * Remove selftest ``--clean-output``, ``--numbered-dirs`` and

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2007-07-12 09:49:37 +0000
+++ b/bzrlib/tests/__init__.py	2007-07-14 10:08:01 +0000
@@ -2259,7 +2259,6 @@
                    'bzrlib.tests.test_commit_merge',
                    'bzrlib.tests.test_config',
                    'bzrlib.tests.test_conflicts',
-                   'bzrlib.tests.test_pack',
                    'bzrlib.tests.test_counted_lock',
                    'bzrlib.tests.test_decorators',
                    'bzrlib.tests.test_delta',
@@ -2270,6 +2269,7 @@
                    'bzrlib.tests.test_escaped_store',
                    'bzrlib.tests.test_extract',
                    'bzrlib.tests.test_fetch',
+                   'bzrlib.tests.test_file_collection',
                    'bzrlib.tests.test_ftp_transport',
                    'bzrlib.tests.test_generate_docs',
                    'bzrlib.tests.test_generate_ids',
@@ -2304,6 +2304,7 @@
                    'bzrlib.tests.test_options',
                    'bzrlib.tests.test_osutils',
                    'bzrlib.tests.test_osutils_encodings',
+                   'bzrlib.tests.test_pack',
                    'bzrlib.tests.test_patch',
                    'bzrlib.tests.test_patches',
                    'bzrlib.tests.test_permissions',




More information about the bazaar-commits mailing list