Rev 2646: And we need InMemoryGraphIndex too. in http://people.ubuntu.com/~robertc/baz2.0/repository

Robert Collins robertc at robertcollins.net
Sat Jul 14 08:43:03 BST 2007


At http://people.ubuntu.com/~robertc/baz2.0/repository

------------------------------------------------------------
revno: 2646
revision-id: robertc at robertcollins.net-20070714074258-eagpvwqma0kjm8ys
parent: robertc at robertcollins.net-20070714070210-yyotg51so4afap8c
parent: robertc at robertcollins.net-20070714072312-alys3q6a5211eegq
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Sat 2007-07-14 17:42:58 +1000
message:
  And we need InMemoryGraphIndex too.
modified:
  bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
  bzrlib/tests/test_index.py     test_index.py-20070712131115-lolkarso50vjr64s-2
    ------------------------------------------------------------
    revno: 2626.1.4
    revision-id: robertc at robertcollins.net-20070714072312-alys3q6a5211eegq
    parent: robertc at robertcollins.net-20070714060702-fnpyy4ogd1q8zzpt
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: index
    timestamp: Sat 2007-07-14 17:23:12 +1000
    message:
      Create an InMemoryGraphIndex for temporary indexing.
    modified:
      bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
      bzrlib/tests/test_index.py     test_index.py-20070712131115-lolkarso50vjr64s-2
=== modified file 'bzrlib/index.py'
--- a/bzrlib/index.py	2007-07-14 06:07:02 +0000
+++ b/bzrlib/index.py	2007-07-14 07:23:12 +0000
@@ -16,7 +16,12 @@
 
 """Indexing facilities."""
 
-__all__ = ['CombinedGraphIndex', 'GraphIndex', 'GraphIndexBuilder']
+__all__ = [
+    'CombinedGraphIndex',
+    'GraphIndex',
+    'GraphIndexBuilder',
+    'InMemoryGraphIndex',
+    ]
 
 from cStringIO import StringIO
 import re
@@ -74,15 +79,17 @@
             raise errors.BadIndexValue(value)
         if len(references) != self.reference_lists:
             raise errors.BadIndexValue(references)
+        node_refs = []
         for reference_list in references:
             for reference in reference_list:
                 if _whitespace_re.search(reference) is not None:
                     raise errors.BadIndexKey(reference)
                 if reference not in self._nodes:
-                    self._nodes[reference] = ('a', [], '')
+                    self._nodes[reference] = ('a', (), '')
+            node_refs.append(tuple(reference_list))
         if key in self._nodes and self._nodes[key][0] == '':
             raise errors.BadIndexDuplicateKey(key, self)
-        self._nodes[key] = ('', references, value)
+        self._nodes[key] = ('', tuple(node_refs), value)
 
     def finish(self):
         lines = [_SIGNATURE]
@@ -321,3 +328,48 @@
         """Validate that everything in the index can be accessed."""
         for index in self._indices:
             index.validate()
+
+
+class InMemoryGraphIndex(GraphIndexBuilder):
+    """A GraphIndex which operates entirely out of memory and is mutable.
+
+    This is designed to allow the accumulation of GraphIndex entries during a
+    single write operation, where the accumulated entries need to be immediately
+    available - for example via a CombinedGraphIndex.
+    """
+
+    def add_nodes(self, nodes):
+        """Add nodes to the index.
+
+        :param nodes: An iterable of (key, node_refs, value) entries to add.
+        """
+        for (key, node_refs, value) in nodes:
+            self.add_node(key, node_refs, value)
+
+    def iter_all_entries(self):
+        """Iterate over all keys within the index
+
+        :return: An iterable of (key, reference_lists, value). There is no
+            defined order for the result iteration - it will be in the most
+            efficient order for the index (in this case dictionary hash order).
+        """
+        for key, (absent, references, value) in self._nodes.iteritems():
+            if not absent:
+                yield key, references, value
+
+    def iter_entries(self, keys):
+        """Iterate over keys within the index.
+
+        :param keys: An iterable providing the keys to be retrieved.
+        :return: An iterable of (key, reference_lists, value). There is no
+            defined order for the result iteration - it will be in the most
+            efficient order for the index (keys iteration order in this case).
+        """
+        keys = set(keys)
+        for key in keys.intersection(self._nodes):
+            node = self._nodes[key]
+            if not node[0]:
+                yield key, node[1], node[2]
+
+    def validate(self):
+        """In memory index's have no known corruption at the moment."""

=== modified file 'bzrlib/tests/test_index.py'
--- a/bzrlib/tests/test_index.py	2007-07-14 06:07:02 +0000
+++ b/bzrlib/tests/test_index.py	2007-07-14 07:23:12 +0000
@@ -17,7 +17,7 @@
 """Tests for indices."""
 
 from bzrlib import errors
-from bzrlib.index import CombinedGraphIndex, GraphIndexBuilder, GraphIndex
+from bzrlib.index import *
 from bzrlib.tests import TestCaseWithMemoryTransport
 
 
@@ -445,3 +445,73 @@
     def test_validate_empty(self):
         index = CombinedGraphIndex([])
         index.validate()
+
+
+class TestInMemoryGraphIndex(TestCaseWithMemoryTransport):
+
+    def make_index(self, ref_lists=0, nodes=[]):
+        result = InMemoryGraphIndex(ref_lists)
+        result.add_nodes(nodes)
+        return result
+
+    def test_add_nodes(self):
+        index = self.make_index(1)
+        index.add_nodes([('name', ([],), 'data')])
+        index.add_nodes([('name2', ([],), ''), ('name3', (['r'],), '')])
+        self.assertEqual(set([
+            ('name', ((),), 'data'),
+            ('name2', ((),), ''),
+            ('name3', (('r',),), ''),
+            ]), set(index.iter_all_entries()))
+
+    def test_iter_all_entries_empty(self):
+        index = self.make_index()
+        self.assertEqual([], list(index.iter_all_entries()))
+
+    def test_iter_all_entries_simple(self):
+        index = self.make_index(nodes=[('name', (), 'data')])
+        self.assertEqual([('name', (), 'data')],
+            list(index.iter_all_entries()))
+
+    def test_iter_all_entries_references(self):
+        index = self.make_index(1, nodes=[
+            ('name', (['ref'], ), 'data'),
+            ('ref', ([], ), 'refdata')])
+        self.assertEqual(set([('name', (('ref',),), 'data'),
+            ('ref', ((), ), 'refdata')]),
+            set(index.iter_all_entries()))
+
+    def test_iteration_absent_skipped(self):
+        index = self.make_index(1, nodes=[
+            ('name', (['ref'], ), 'data')])
+        self.assertEqual(set([('name', (('ref',),), 'data')]),
+            set(index.iter_all_entries()))
+        self.assertEqual(set([('name', (('ref',),), 'data')]),
+            set(index.iter_entries(['name'])))
+        self.assertEqual([], list(index.iter_entries(['ref'])))
+
+    def test_iter_all_keys(self):
+        index = self.make_index(1, nodes=[
+            ('name', (['ref'], ), 'data'),
+            ('ref', ([], ), 'refdata')])
+        self.assertEqual(set([('name', (('ref',),), 'data'),
+            ('ref', ((), ), 'refdata')]),
+            set(index.iter_entries(['name', 'ref'])))
+
+    def test_iter_nothing_empty(self):
+        index = self.make_index()
+        self.assertEqual([], list(index.iter_entries([])))
+
+    def test_iter_missing_entry_empty(self):
+        index = self.make_index()
+        self.assertEqual([], list(index.iter_entries(['a'])))
+
+    def test_validate_empty(self):
+        index = self.make_index()
+        index.validate()
+
+    def test_validate_no_refs_content(self):
+        index = self.make_index(nodes=[('key', (), 'value')])
+        index.validate()
+
+




More information about the bazaar-commits mailing list