1081
1081
# so - wc -l of a knit index is != the number of unique names
1083
1083
self._history = []
1084
pb = bzrlib.ui.ui_factory.nested_progress_bar()
1084
pb = ui.ui_factory.nested_progress_bar()
1086
pb.update('read knit index', 0, 1)
1089
pb.update('read knit index', count, total)
1090
1088
fp = self._transport.get(self._filename)
1090
if mode != 'w' or not create:
1093
self._need_to_create = True
1095
self._transport.put_bytes_non_atomic(
1096
self._filename, self.HEADER, mode=self._file_mode)
1092
self.check_header(fp)
1093
# readlines reads the whole file at once:
1094
# bad for transports like http, good for local disk
1095
# we save 60 ms doing this one change (
1096
# from calling readline each time to calling
1098
# probably what we want for nice behaviour on
1099
# http is a incremental readlines that yields, or
1100
# a check for local vs non local indexes,
1101
for l in fp.readlines():
1103
if len(rec) < 5 or rec[-1] != ':':
1105
# FIXME: in the future we should determine if its a
1106
# short write - and ignore it
1107
# or a different failure, and raise. RBC 20060407
1111
#pb.update('read knit index', count, total)
1112
# See self._parse_parents
1114
for value in rec[4:-1]:
1116
# uncompressed reference
1117
parents.append(value[1:])
1119
# this is 15/4000ms faster than isinstance,
1121
# this function is called thousands of times a
1122
# second so small variations add up.
1123
assert value.__class__ is str
1124
parents.append(self._history[int(value)])
1125
# end self._parse_parents
1126
# self._cache_version(rec[0],
1127
# rec[1].split(','),
1131
# --- self._cache_version
1132
# only want the _history index to reference the 1st
1133
# index entry for version_id
1135
if version_id not in self._cache:
1136
index = len(self._history)
1137
self._history.append(version_id)
1139
index = self._cache[version_id][5]
1140
self._cache[version_id] = (version_id,
1146
# --- self._cache_version
1149
except NoSuchFile, e:
1150
if mode != 'w' or not create:
1153
self._need_to_create = True
1155
self._transport.put_bytes_non_atomic(self._filename,
1156
self.HEADER, mode=self._file_mode)
1159
pb.update('read knit index', total, total)
1103
pb.update('read knit index', 1, 1)
1162
def _parse_parents(self, compressed_parents):
1163
"""convert a list of string parent values into version ids.
1165
ints are looked up in the index.
1166
.FOO values are ghosts and converted in to FOO.
1168
NOTE: the function is retained here for clarity, and for possible
1169
use in partial index reads. However bulk processing now has
1170
it inlined in __init__ for inner-loop optimisation.
1173
for value in compressed_parents:
1174
if value[-1] == '.':
1175
# uncompressed reference
1176
result.append(value[1:])
1106
def _load_data(self, fp):
1108
history = self._history
1109
decode_utf8 = cache_utf8.decode
1111
self.check_header(fp)
1112
# readlines reads the whole file at once:
1113
# bad for transports like http, good for local disk
1114
# we save 60 ms doing this one change (
1115
# from calling readline each time to calling
1117
# probably what we want for nice behaviour on
1118
# http is a incremental readlines that yields, or
1119
# a check for local vs non local indexes,
1120
history_top = len(history) - 1
1121
for line in fp.readlines():
1123
if len(rec) < 5 or rec[-1] != ':':
1125
# FIXME: in the future we should determine if its a
1126
# short write - and ignore it
1127
# or a different failure, and raise. RBC 20060407
1131
for value in rec[4:-1]:
1133
# uncompressed reference
1134
parents.append(decode_utf8(value[1:]))
1136
parents.append(history[int(value)])
1138
version_id, options, pos, size = rec[:4]
1139
version_id = decode_utf8(version_id)
1141
# See self._cache_version
1142
# only want the _history index to reference the 1st
1143
# index entry for version_id
1144
if version_id not in cache:
1147
history.append(version_id)
1178
# this is 15/4000ms faster than isinstance,
1179
# this function is called thousands of times a
1180
# second so small variations add up.
1181
assert value.__class__ is str
1182
result.append(self._history[int(value)])
1149
index = cache[version_id][5]
1150
cache[version_id] = (version_id,
1156
# end self._cache_version
1185
1158
def get_graph(self):
1187
for version_id, index in self._cache.iteritems():
1188
graph.append((version_id, index[4]))
1159
return [(vid, idx[4]) for vid, idx in self._cache.iteritems()]
1191
1161
def get_ancestry(self, versions):
1192
1162
"""See VersionedFile.get_ancestry."""
1193
1163
# get a graph of all the mentioned versions:
1195
1165
pending = set(versions)
1197
1168
version = pending.pop()
1198
parents = self._cache[version][4]
1199
# got the parents ok
1201
parents = [parent for parent in parents if parent in self._cache]
1202
for parent in parents:
1203
# if not completed and not a ghost
1204
if parent not in graph:
1171
parents = [p for p in cache[version][4] if p in cache]
1173
raise RevisionNotPresent(version, self._filename)
1174
# if not completed and not a ghost
1175
pending.update([p for p in parents if p not in graph])
1206
1176
graph[version] = parents
1207
1177
return topo_sort(graph.items())
1209
1179
def get_ancestry_with_ghosts(self, versions):
1210
1180
"""See VersionedFile.get_ancestry_with_ghosts."""
1211
1181
# get a graph of all the mentioned versions:
1182
self.check_versions_present(versions)
1213
1185
pending = set(versions)
1215
1187
version = pending.pop()
1217
parents = self._cache[version][4]
1189
parents = cache[version][4]
1218
1190
except KeyError:
1219
1191
# ghost, fake it
1220
1192
graph[version] = []
1223
# got the parents ok
1224
for parent in parents:
1225
if parent not in graph:
1195
pending.update([p for p in parents if p not in graph])
1227
1196
graph[version] = parents
1228
1197
return topo_sort(graph.items())
1322
1292
def get_parents(self, version_id):
1323
1293
"""Return parents of specified version ignoring ghosts."""
1324
return [parent for parent in self._cache[version_id][4]
1294
return [parent for parent in self._cache[version_id][4]
1325
1295
if parent in self._cache]
1327
1297
def get_parents_with_ghosts(self, version_id):
1328
1298
"""Return parents of specified version with ghosts."""
1329
return self._cache[version_id][4]
1299
return self._cache[version_id][4]
1331
1301
def check_versions_present(self, version_ids):
1332
1302
"""Check that all specified versions are present."""
1333
version_ids = set(version_ids)
1334
for version_id in list(version_ids):
1335
if version_id in self._cache:
1336
version_ids.remove(version_id)
1338
raise RevisionNotPresent(list(version_ids)[0], self.filename)
1304
for version_id in version_ids:
1305
if version_id not in cache:
1306
raise RevisionNotPresent(version_id, self._filename)
1341
1309
class _KnitData(_KnitComponentFile):