Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3bf67e1 authored by Tianjie Xu's avatar Tianjie Xu
Browse files

Sort the split transfers to generate a determinate package

We split large apks and generated patches for them in parallel,
resulting in nondeterminate packages between different runs. This CL
sort the split transfers by target name first; and then add them
sequentially to the final transfer list.

Also fix a side effect where we may generate a wrong sha1 for split
ranges due to synchronization error.

Bug: 71770360
Bug: 71759418

Test: Generate the package several times, compare the log and the transfer list.
Change-Id: I2a49e22594d59ffaa98b11edc776be4e3c4c561f
parent e3692095
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -1385,8 +1385,8 @@ class BlockImageDiff(object):
      assert patch_start == patch_size
      return split_info_list

    def AddSplitTransferForLargeApks():
      """Create split transfers for large apk files.
    def SplitLargeApks():
      """Split the large apks files.

      Example: Chrome.apk will be split into
        src-0: Chrome.apk-0, tgt-0: Chrome.apk-0
@@ -1452,16 +1452,16 @@ class BlockImageDiff(object):

          split_src_name = "{}-{}".format(src_name, index)
          split_tgt_name = "{}-{}".format(tgt_name, index)
          transfer_split = Transfer(split_tgt_name, split_src_name,
                                    split_tgt_ranges, split_src_ranges,
                                    self.tgt.RangeSha1(split_tgt_ranges),
                                    self.src.RangeSha1(split_src_ranges),
                                    "diff", self.transfers)
          transfer_split.patch = patch_content
          split_large_apks.append((split_tgt_name,
                                   split_src_name,
                                   split_tgt_ranges,
                                   split_src_ranges,
                                   patch_content))

    print("Finding transfers...")

    large_apks = []
    split_large_apks = []
    cache_size = common.OPTIONS.cache_size
    split_threshold = 0.125
    max_blocks_per_transfer = int(cache_size * split_threshold /
@@ -1511,13 +1511,23 @@ class BlockImageDiff(object):
      AddTransfer(tgt_fn, None, tgt_ranges, empty, "new", self.transfers)

    transfer_lock = threading.Lock()
    threads = [threading.Thread(target=AddSplitTransferForLargeApks)
    threads = [threading.Thread(target=SplitLargeApks)
               for _ in range(self.threads)]
    for th in threads:
      th.start()
    while threads:
      threads.pop().join()

    # Sort the split transfers for large apks to generate a determinate package.
    split_large_apks.sort()
    for (tgt_name, src_name, tgt_ranges, src_ranges,
         patch) in split_large_apks:
      transfer_split = Transfer(tgt_name, src_name, tgt_ranges, src_ranges,
                                self.tgt.RangeSha1(tgt_ranges),
                                self.src.RangeSha1(src_ranges),
                                "diff", self.transfers)
      transfer_split.patch = patch

  def AbbreviateSourceNames(self):
    for k in self.src.file_map.keys():
      b = os.path.basename(k)