~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-02-20 08:24:49 UTC
  • mfrom: (4009.3.13 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20090220082449-8wtrcem3dypgq53q
(robertc) Allow VersionedFiles to insert and hold record streams
        which need missing compression parents. (Andrew Bennetts,
        Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1475
1475
                    added_keys.extend(
1476
1476
                        [index_entry[0] for index_entry in index_entries])
1477
1477
                    del buffered_index_entries[key]
1478
 
        # If there were any deltas which had a missing basis parent, error.
1479
1478
        if buffered_index_entries:
1480
 
            from pprint import pformat
1481
 
            raise errors.BzrCheckError(
1482
 
                "record_stream refers to compression parents not in %r:\n%s"
1483
 
                % (self, pformat(sorted(buffered_index_entries.keys()))))
 
1479
            # There were index entries buffered at the end of the stream,
 
1480
            # So these need to be added (if the index supports holding such
 
1481
            # entries for later insertion)
 
1482
            for key in buffered_index_entries:
 
1483
                index_entries = buffered_index_entries[key]
 
1484
                self._index.add_records(index_entries,
 
1485
                    missing_compression_parents=True)
 
1486
 
 
1487
    def get_missing_compression_parent_keys(self):
 
1488
        """Return an iterable of keys of missing compression parents.
 
1489
 
 
1490
        Check this after calling insert_record_stream to find out if there are
 
1491
        any missing compression parents.  If there are, the records that
 
1492
        depend on them are not able to be inserted safely. For atomic
 
1493
        KnitVersionedFiles built on packs, the transaction should be aborted or
 
1494
        suspended - commit will fail at this point. Nonatomic knits will error
 
1495
        earlier because they have no staging area to put pending entries into.
 
1496
        """
 
1497
        return self._index.get_missing_compression_parents()
1484
1498
 
1485
1499
    def iter_lines_added_or_present_in_keys(self, keys, pb=None):
1486
1500
        """Iterate over the lines in the versioned files from keys.
1837
1851
        self._reset_cache()
1838
1852
        self.has_graph = True
1839
1853
 
1840
 
    def add_records(self, records, random_id=False):
 
1854
    def add_records(self, records, random_id=False, missing_compression_parents=False):
1841
1855
        """Add multiple records to the index.
1842
1856
        
1843
1857
        :param records: a list of tuples:
1844
1858
                         (key, options, access_memo, parents).
1845
1859
        :param random_id: If True the ids being added were randomly generated
1846
1860
            and no check for existence will be performed.
 
1861
        :param missing_compression_parents: If True the records being added are
 
1862
            only compressed against texts already in the index (or inside
 
1863
            records). If False the records all refer to unavailable texts (or
 
1864
            texts inside records) as compression parents.
1847
1865
        """
 
1866
        if missing_compression_parents:
 
1867
            # It might be nice to get the edge of the records. But keys isn't
 
1868
            # _wrong_.
 
1869
            keys = sorted(record[0] for record in records)
 
1870
            raise errors.RevisionNotPresent(keys, self)
1848
1871
        paths = {}
1849
1872
        for record in records:
1850
1873
            key = record[0]
2213
2236
    def __repr__(self):
2214
2237
        return "%s(%r)" % (self.__class__.__name__, self._graph_index)
2215
2238
 
2216
 
    def add_records(self, records, random_id=False):
 
2239
    def add_records(self, records, random_id=False,
 
2240
        missing_compression_parents=False):
2217
2241
        """Add multiple records to the index.
2218
2242
        
2219
2243
        This function does not insert data into the Immutable GraphIndex
2225
2249
                         (key, options, access_memo, parents).
2226
2250
        :param random_id: If True the ids being added were randomly generated
2227
2251
            and no check for existence will be performed.
 
2252
        :param missing_compression_parents: If True the records being added are
 
2253
            only compressed against texts already in the index (or inside
 
2254
            records). If False the records all refer to unavailable texts (or
 
2255
            texts inside records) as compression parents.
2228
2256
        """
2229
2257
        if not self._add_callback:
2230
2258
            raise errors.ReadOnlyError(self)
2232
2260
        # anymore.
2233
2261
 
2234
2262
        keys = {}
 
2263
        compression_parents = set()
2235
2264
        for (key, options, access_memo, parents) in records:
2236
2265
            if self._parents:
2237
2266
                parents = tuple(parents)
2248
2277
                if self._deltas:
2249
2278
                    if 'line-delta' in options:
2250
2279
                        node_refs = (parents, (parents[0],))
 
2280
                        if missing_compression_parents:
 
2281
                            compression_parents.add(parents[0])
2251
2282
                    else:
2252
2283
                        node_refs = (parents, ())
2253
2284
                else:
2275
2306
            for key, (value, node_refs) in keys.iteritems():
2276
2307
                result.append((key, value))
2277
2308
        self._add_callback(result)
 
2309
        if missing_compression_parents:
 
2310
            # This may appear to be incorrect (it does not check for
 
2311
            # compression parents that are in the existing graph index),
 
2312
            # but such records won't have been buffered, so this is
 
2313
            # actually correct: every entry when
 
2314
            # missing_compression_parents==True either has a missing parent, or
 
2315
            # a parent that is one of the keys in records.
 
2316
            compression_parents.difference_update(keys)
 
2317
            self._missing_compression_parents.update(compression_parents)
 
2318
        # Adding records may have satisfied missing compression parents.
 
2319
        self._missing_compression_parents.difference_update(keys)
2278
2320
        
2279
2321
    def scan_unvalidated_index(self, graph_index):
2280
2322
        """Inform this _KnitGraphIndex that there is an unvalidated index.
2291
2333
            self._missing_compression_parents.update(new_missing)
2292
2334
 
2293
2335
    def get_missing_compression_parents(self):
2294
 
        """Return the keys of compression parents missing from unvalidated
2295
 
        indices.
 
2336
        """Return the keys of missing compression parents.
 
2337
 
 
2338
        Missing compression parents occur when a record stream was missing
 
2339
        basis texts, or a index was scanned that had missing basis texts.
2296
2340
        """
2297
2341
        return frozenset(self._missing_compression_parents)
2298
2342