From aed7702a67426dfd9d24b512c90df8e909162179 Mon Sep 17 00:00:00 2001 From: Peter Amstutz Date: Tue, 18 Apr 2017 17:54:57 -0400 Subject: [PATCH] 11510: Fix longstanding bug in replace_range() when appending data from a buffer that was written out of order. --- sdk/python/arvados/_ranges.py | 6 +++--- sdk/python/arvados/arvfile.py | 4 ---- sdk/python/tests/test_arvfile.py | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/sdk/python/arvados/_ranges.py b/sdk/python/arvados/_ranges.py index 83874164ee..5532ea011e 100644 --- a/sdk/python/arvados/_ranges.py +++ b/sdk/python/arvados/_ranges.py @@ -109,7 +109,7 @@ def locators_and_ranges(data_locators, range_start, range_size, limit=None): block_size = dl.range_size block_end = block_start + block_size _logger.log(RANGES_SPAM, - "%s range_start %s block_start %s range_end %s block_end %s", + "L&R %s range_start %s block_start %s range_end %s block_end %s", dl.locator, range_start, block_start, range_end, block_end) if range_end <= block_start: # range ends before this block starts, so don't look at any more locators @@ -165,7 +165,7 @@ def replace_range(data_locators, new_range_start, new_range_size, new_locator, n last = data_locators[-1] if (last.range_start+last.range_size) == new_range_start: - if last.locator == new_locator: + if last.locator == new_locator and (last.segment_offset+last.range_size) == new_segment_offset: # extend last segment last.range_size += new_range_size else: @@ -183,7 +183,7 @@ def replace_range(data_locators, new_range_start, new_range_size, new_locator, n old_segment_start = dl.range_start old_segment_end = old_segment_start + dl.range_size _logger.log(RANGES_SPAM, - "%s range_start %s segment_start %s range_end %s segment_end %s", + "RR %s range_start %s segment_start %s range_end %s segment_end %s", dl, new_range_start, old_segment_start, new_range_end, old_segment_end) if new_range_end <= old_segment_start: diff --git a/sdk/python/arvados/arvfile.py b/sdk/python/arvados/arvfile.py index d3377854aa..33e55ad4fb 100644 --- a/sdk/python/arvados/arvfile.py +++ b/sdk/python/arvados/arvfile.py @@ -1022,12 +1022,8 @@ class ArvadosFile(object): if len(data) == 0: return - print "Writing", len(data), "bytes to offset", offset, "current size is", self.size() - if offset > self.size(): - print "Need to extend to", offset self.truncate(offset) - print "Size is now", self.size() if len(data) > config.KEEP_BLOCK_SIZE: # Chunk it up into smaller writes diff --git a/sdk/python/tests/test_arvfile.py b/sdk/python/tests/test_arvfile.py index 95106a7459..1a2c034802 100644 --- a/sdk/python/tests/test_arvfile.py +++ b/sdk/python/tests/test_arvfile.py @@ -330,6 +330,23 @@ class ArvadosFileWriterTestCase(unittest.TestCase): self.assertEqual(c.manifest_text(), ". 7f614da9329cd3aebf59b91aadc30bf0+67108864 781e5e245d69b566979b86e28d23f2c7+10 0:67108864:count.txt 0:67108864:count.txt 0:2:count.txt 67108864:10:count.txt\n") + + def test_sparse_write3(self): + keep = ArvadosFileWriterTestCase.MockKeep({}) + api = ArvadosFileWriterTestCase.MockApi({}, {}) + for r in [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0], [3, 2, 0, 4, 1]]: + with Collection() as c: + writer = c.open("count.txt", "r+") + self.assertEqual(writer.size(), 0) + + for i in r: + w = ("%s" % i) * 10 + writer.seek(i*10) + writer.write(w) + writer.seek(0) + self.assertEqual(writer.read(), "00000000001111111111222222222233333333334444444444") + + def test_rewrite_on_empty_file(self): keep = ArvadosFileWriterTestCase.MockKeep({}) with Collection('. ' + arvados.config.EMPTY_BLOCK_LOCATOR + ' 0:0:count.txt', -- 2.39.5