Rev 2254: Implement support for slicing ranges in http://bzr.arbash-meinel.com/branches/bzr/0.15-dev/list_patch
John Arbash Meinel
john at arbash-meinel.com
Tue Jan 30 17:55:56 GMT 2007
At http://bzr.arbash-meinel.com/branches/bzr/0.15-dev/list_patch
------------------------------------------------------------
revno: 2254
revision-id: john at arbash-meinel.com-20070130175551-v30z9f40xpvx2m4v
parent: john at arbash-meinel.com-20070130170743-8d4lsxgevxk4dspc
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: list_patch
timestamp: Tue 2007-01-30 11:55:51 -0600
message:
Implement support for slicing ranges
modified:
bzrlib/hybrid_linked_list.py hybrid_linked_list.p-20070130001028-zlexwz74tzo56o2t-1
bzrlib/tests/test_hybrid_linked_list.py test_hybrid_linked_l-20070130001028-zlexwz74tzo56o2t-2
-------------- next part --------------
=== modified file 'bzrlib/hybrid_linked_list.py'
--- a/bzrlib/hybrid_linked_list.py 2007-01-30 17:07:43 +0000
+++ b/bzrlib/hybrid_linked_list.py 2007-01-30 17:55:51 +0000
@@ -68,6 +68,9 @@
cur_range_id = self._links[cur_range_id]
def __len__(self):
+ # TODO: jam 20070130 Should we fast path __len__? We could always just
+ # keep a reference of the current length, and updated it when we
+ # add or delete entries. list() uses it, as does __getitem__
cur_range_id = self._head
length = 0
while cur_range_id is not None:
@@ -77,9 +80,40 @@
return length
def __getitem__(self, pos):
- (prev_range_id, cur_range_id, offset,
- start, end, content) = self._find_nodes_for_pos(pos)
- return content[start+offset]
+ if isinstance(pos, slice):
+ # cur, stop, stride are in terms of location in the output list.
+ cur, stop, stride = pos.indices(len(self))
+ result = []
+
+ # offset, start, end are in terms of the current content
+ (prev_range_id, cur_range_id, offset,
+ start, end, content) = self._find_nodes_for_pos(cur)
+
+ # They requested something out of range
+ if content is None:
+ return result
+
+ offset += start
+ while cur < stop:
+ while offset >= end:
+ # Keep skipping until we find next
+ offset -= end
+ cur_range_id = self._links[cur_range_id]
+ if cur_range_id is None:
+ content = None
+ break
+ start, end, content = self._range_map[cur_range_id]
+ offset += start
+ if content is None:
+ break
+ result.append(content[offset])
+ offset += stride
+ cur += stride
+ return result
+ else:
+ (prev_range_id, cur_range_id, offset,
+ start, end, content) = self._find_nodes_for_pos(pos)
+ return content[start+offset]
def flatten(self):
"""Flatten the linked structure into a single list."""
=== modified file 'bzrlib/tests/test_hybrid_linked_list.py'
--- a/bzrlib/tests/test_hybrid_linked_list.py 2007-01-30 17:07:43 +0000
+++ b/bzrlib/tests/test_hybrid_linked_list.py 2007-01-30 17:55:51 +0000
@@ -59,6 +59,17 @@
for expected, pos in zip([0, 1, 3, 4, 5, 8], xrange(0,5)):
self.assertEqual(expected, hll[pos])
+ # Test that we support extracting ranges
+ self.assertEqual([0, 1, 3], hll[0:3])
+ self.assertEqual([0, 3], hll[0:3:2])
+ self.assertEqual([0, 1, 3, 4, 5, 8], hll[:])
+ self.assertEqual([0, 1, 3, 4, 5, 8], hll[0:20])
+ self.assertEqual([4, 5], hll[-3:-1])
+
+ # Slicing off the end returns an empty list
+ self.assertEqual([], hll[20:])
+ self.assertEqual([], hll[20:21])
+
def test_insert(self):
hll = hybrid_linked_list.HybridLinkedList([0, 1, 2, 3, 4])
hll.insert(3, [5, 6, 7])
More information about the bazaar-commits
mailing list