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