290
290
self._data = _KnitData(transport, relpath + DATA_SUFFIX,
291
291
access_mode, create=create and not len(self), file_mode=file_mode)
294
return '%s(%s)' % (self.__class__.__name__,
295
self.transport.abspath(self.filename))
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)
359
def _add_raw_records(self, records, data):
360
"""Add all the records 'records' with data pre-joined in 'data'.
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.
368
pos = self._data.add_raw_record(data)
370
for (version_id, options, parents, size) in records:
371
index_entries.append((version_id, options, pos, size, parents))
373
self._index.add_versions(index_entries)
355
375
def clear_cache(self):
356
376
"""Clear the data cache only."""
357
377
self._data.clear_cache()
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)
1145
content = "\n%s %s %s %s %s :" % (version_id.encode('utf-8'),
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))
1163
self.add_versions(((version_id, options, pos, size, parents),))
1165
def add_versions(self, versions):
1166
"""Add multiple versions to the index.
1168
:param versions: a list of tuples:
1169
(version_id, options, pos, size, parents).
1172
for version_id, options, pos, size, parents in versions:
1173
line = "\n%s %s %s %s %s :" % (version_id.encode('utf-8'),
1177
self._version_list_to_index(parents))
1178
assert isinstance(line, str), \
1179
'content must be utf-8 encoded: %r' % (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)
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
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.
1276
:return: the offset in the data file raw_data was written.
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))
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:
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.
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))
1460
1497
for version in mismatched_versions:
1461
1498
# FIXME RBC 20060309 is this needed?