~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

Merge With main tree, move the NEWS entry to the good place.

Show diffs side-by-side

added added

removed removed

Lines of Context:
290
290
        self._data = _KnitData(transport, relpath + DATA_SUFFIX,
291
291
            access_mode, create=create and not len(self), file_mode=file_mode)
292
292
 
 
293
    def __repr__(self):
 
294
        return '%s(%s)' % (self.__class__.__name__, 
 
295
                           self.transport.abspath(self.filename))
 
296
    
293
297
    def _add_delta(self, version_id, parents, delta_parent, sha1, noeol, delta):
294
298
        """See VersionedFile._add_delta()."""
295
299
        self._check_add(version_id, []) # should we check the lines ?
352
356
        where, size = self._data.add_record(version_id, digest, store_lines)
353
357
        self._index.add_version(version_id, options, where, size, parents)
354
358
 
 
359
    def _add_raw_records(self, records, data):
 
360
        """Add all the records 'records' with data pre-joined in 'data'.
 
361
 
 
362
        :param records: A list of tuples(version_id, options, parents, size).
 
363
        :param data: The data for the records. When it is written, the records
 
364
                     are adjusted to have pos pointing into data by the sum of
 
365
                     the preceeding records sizes.
 
366
        """
 
367
        # write all the data
 
368
        pos = self._data.add_raw_record(data)
 
369
        index_entries = []
 
370
        for (version_id, options, parents, size) in records:
 
371
            index_entries.append((version_id, options, pos, size, parents))
 
372
            pos += size
 
373
        self._index.add_versions(index_entries)
 
374
 
355
375
    def clear_cache(self):
356
376
        """Clear the data cache only."""
357
377
        self._data.clear_cache()
1140
1160
 
1141
1161
    def add_version(self, version_id, options, pos, size, parents):
1142
1162
        """Add a version record to the index."""
1143
 
        self._cache_version(version_id, options, pos, size, parents)
1144
 
 
1145
 
        content = "\n%s %s %s %s %s :" % (version_id.encode('utf-8'),
1146
 
                                        ','.join(options),
1147
 
                                        pos,
1148
 
                                        size,
1149
 
                                        self._version_list_to_index(parents))
1150
 
        assert isinstance(content, str), 'content must be utf-8 encoded'
1151
 
        self._transport.append(self._filename, StringIO(content))
1152
 
 
 
1163
        self.add_versions(((version_id, options, pos, size, parents),))
 
1164
 
 
1165
    def add_versions(self, versions):
 
1166
        """Add multiple versions to the index.
 
1167
        
 
1168
        :param versions: a list of tuples:
 
1169
                         (version_id, options, pos, size, parents).
 
1170
        """
 
1171
        lines = []
 
1172
        for version_id, options, pos, size, parents in versions:
 
1173
            line = "\n%s %s %s %s %s :" % (version_id.encode('utf-8'),
 
1174
                                           ','.join(options),
 
1175
                                           pos,
 
1176
                                           size,
 
1177
                                           self._version_list_to_index(parents))
 
1178
            assert isinstance(line, str), \
 
1179
                'content must be utf-8 encoded: %r' % (line,)
 
1180
            lines.append(line)
 
1181
        self._transport.append(self._filename, StringIO(''.join(lines)))
 
1182
        # cache after writing, so that a failed write leads to missing cache
 
1183
        # entries not extra ones. XXX TODO: RBC 20060502 in the event of a 
 
1184
        # failure, reload the index or flush it or some such, to prevent
 
1185
        # writing records that did complete twice.
 
1186
        for version_id, options, pos, size, parents in versions:
 
1187
            self._cache_version(version_id, options, pos, size, parents)
 
1188
        
1153
1189
    def has_version(self, version_id):
1154
1190
        """True if the version is in the index."""
1155
1191
        return self._cache.has_key(version_id)
1235
1271
        return length, sio
1236
1272
 
1237
1273
    def add_raw_record(self, raw_data):
1238
 
        """Append a prepared record to the data file."""
 
1274
        """Append a prepared record to the data file.
 
1275
        
 
1276
        :return: the offset in the data file raw_data was written.
 
1277
        """
1239
1278
        assert isinstance(raw_data, str), 'data must be plain bytes'
1240
 
        start_pos = self._transport.append(self._filename, StringIO(raw_data))
1241
 
        return start_pos, len(raw_data)
 
1279
        return self._transport.append(self._filename, StringIO(raw_data))
1242
1280
        
1243
1281
    def add_record(self, version_id, digest, lines):
1244
1282
        """Write new text record to disk.  Returns the position in the
1443
1481
            # data suck the join:
1444
1482
            count = 0
1445
1483
            total = len(version_list)
1446
 
            # we want the raw gzip for bulk copying, but the record validated
1447
 
            # just enough to be sure its the right one.
1448
 
            # TODO: consider writev or write combining to reduce 
1449
 
            # death of a thousand cuts feeling.
 
1484
            raw_datum = []
 
1485
            raw_records = []
1450
1486
            for (version_id, raw_data), \
1451
1487
                (version_id2, options, parents) in \
1452
1488
                izip(self.source._data.read_records_iter_raw(copy_queue_records),
1454
1490
                assert version_id == version_id2, 'logic error, inconsistent results'
1455
1491
                count = count + 1
1456
1492
                pb.update("Joining knit", count, total)
1457
 
                pos, size = self.target._data.add_raw_record(raw_data)
1458
 
                self.target._index.add_version(version_id, options, pos, size, parents)
 
1493
                raw_records.append((version_id, options, parents, len(raw_data)))
 
1494
                raw_datum.append(raw_data)
 
1495
            self.target._add_raw_records(raw_records, ''.join(raw_datum))
1459
1496
 
1460
1497
            for version in mismatched_versions:
1461
1498
                # FIXME RBC 20060309 is this needed?