909
909
# indexes can't directly store that, so we give them
910
910
# an empty tuple instead.
912
line_bytes = ''.join(lines)
912
913
return self._add(key, lines, parents,
913
parent_texts, left_matching_blocks, nostore_sha, random_id)
914
parent_texts, left_matching_blocks, nostore_sha, random_id,
915
line_bytes=line_bytes)
917
def _add_text(self, key, parents, text, nostore_sha=None, random_id=False):
918
"""See VersionedFiles.add_text()."""
919
self._index._check_write_ok()
920
self._check_add(key, None, random_id, check_content=False)
921
if text.__class__ is not str:
922
raise errors.BzrBadParameterUnicode("text")
924
# The caller might pass None if there is no graph data, but kndx
925
# indexes can't directly store that, so we give them
926
# an empty tuple instead.
928
return self._add(key, None, parents,
929
None, None, nostore_sha, random_id,
915
932
def _add(self, key, lines, parents, parent_texts,
916
left_matching_blocks, nostore_sha, random_id):
933
left_matching_blocks, nostore_sha, random_id,
917
935
"""Add a set of lines on top of version specified by parents.
919
937
Any versions not present will be converted into ghosts.
939
:param lines: A list of strings where each one is a single line (has a
940
single newline at the end of the string) This is now optional
941
(callers can pass None). It is left in its location for backwards
942
compatibility. It should ''.join(lines) must == line_bytes
943
:param line_bytes: A single string containing the content
945
We pass both lines and line_bytes because different routes bring the
946
values to this function. And for memory efficiency, we don't want to
947
have to split/join on-demand.
921
949
# first thing, if the content is something we don't need to store, find
923
line_bytes = ''.join(lines)
924
951
digest = sha_string(line_bytes)
925
952
if nostore_sha == digest:
926
953
raise errors.ExistingContent
948
975
text_length = len(line_bytes)
951
if lines[-1][-1] != '\n':
952
# copy the contents of lines.
978
# Note: line_bytes is not modified to add a newline, that is tracked
979
# via the no_eol flag. 'lines' *is* modified, because that is the
980
# general values needed by the Content code.
981
if line_bytes and line_bytes[-1] != '\n':
982
options.append('no-eol')
984
# Copy the existing list, or create a new one
986
lines = osutils.split_lines(line_bytes)
954
options.append('no-eol')
955
lines[-1] = lines[-1] + '\n'
989
# Replace the last line with one that ends in a final newline
990
lines[-1] = lines[-1] + '\n'
992
lines = osutils.split_lines(line_bytes)
958
994
for element in key[:-1]:
959
if type(element) != str:
995
if type(element) is not str:
960
996
raise TypeError("key contains non-strings: %r" % (key,))
961
997
if key[-1] is None:
962
998
key = key[:-1] + ('sha1:' + digest,)
963
elif type(key[-1]) != str:
999
elif type(key[-1]) is not str:
964
1000
raise TypeError("key contains non-strings: %r" % (key,))
965
1001
# Knit hunks are still last-element only
966
1002
version_id = key[-1]
967
1003
content = self._factory.make(lines, version_id)
968
if 'no-eol' in options:
969
1005
# Hint to the content object that its text() call should strip the
971
1007
content._should_strip_eol = True
1920
1959
function spends less time resizing the final string.
1921
1960
:return: (len, a StringIO instance with the raw data ready to read.)
1923
# Note: using a string copy here increases memory pressure with e.g.
1924
# ISO's, but it is about 3 seconds faster on a 1.2Ghz intel machine
1925
# when doing the initial commit of a mozilla tree. RBC 20070921
1926
bytes = ''.join(chain(
1927
["version %s %d %s\n" % (key[-1],
1930
dense_lines or lines,
1931
["end %s\n" % key[-1]]))
1932
if type(bytes) != str:
1933
raise AssertionError(
1934
'data must be plain bytes was %s' % type(bytes))
1962
chunks = ["version %s %d %s\n" % (key[-1], len(lines), digest)]
1963
chunks.extend(dense_lines or lines)
1964
chunks.append("end %s\n" % key[-1])
1965
for chunk in chunks:
1966
if type(chunk) is not str:
1967
raise AssertionError(
1968
'data must be plain bytes was %s' % type(chunk))
1935
1969
if lines and lines[-1][-1] != '\n':
1936
1970
raise ValueError('corrupt lines value %r' % lines)
1937
compressed_bytes = tuned_gzip.bytes_to_gzip(bytes)
1971
compressed_bytes = tuned_gzip.chunks_to_gzip(chunks)
1938
1972
return len(compressed_bytes), compressed_bytes
1940
1974
def _split_header(self, line):