Fragment each file's operations in parallel.

FragmentOperations() can take a long time if we have many replace
operations, but it doesn't have dependencies on other operations,
so it's safe to parallelize it.

Bug: 77817425
Test: generated a delta payload exactly the same as before
Change-Id: Idb62667df167108bd27bee859e2976931baa4326
diff --git a/payload_generator/ab_generator.cc b/payload_generator/ab_generator.cc
index 962118e..f24f6c3 100644
--- a/payload_generator/ab_generator.cc
+++ b/payload_generator/ab_generator.cc
@@ -57,9 +57,6 @@
                                                        blob_file));
   LOG(INFO) << "done reading " << new_part.name;
 
-  LOG(INFO) << "Fragmenting " << aops->size() << " operations.";
-  TEST_AND_RETURN_FALSE(
-      FragmentOperations(config.version, aops, new_part.path, blob_file));
   SortOperationsByDestination(aops);
 
   // Use the soft_chunk_size when merging operations to prevent merging all
diff --git a/payload_generator/delta_diff_utils.cc b/payload_generator/delta_diff_utils.cc
index 4ee1024..7293c65 100644
--- a/payload_generator/delta_diff_utils.cc
+++ b/payload_generator/delta_diff_utils.cc
@@ -49,6 +49,7 @@
 #include "update_engine/common/subprocess.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/payload_consumer/payload_constants.h"
+#include "update_engine/payload_generator/ab_generator.h"
 #include "update_engine/payload_generator/block_mapping.h"
 #include "update_engine/payload_generator/bzip.h"
 #include "update_engine/payload_generator/deflate_utils.h"
@@ -261,6 +262,13 @@
                << new_extents_blocks_ << " blocks)";
   }
 
+  if (!version_.InplaceUpdate()) {
+    if (!ABGenerator::FragmentOperations(
+            version_, &file_aops_, new_part_, blob_file_)) {
+      LOG(ERROR) << "Failed to fragment operations for " << name_;
+    }
+  }
+
   LOG(INFO) << "Encoded file " << name_ << " (" << new_extents_blocks_
             << " blocks) in " << (base::Time::Now() - start).InSecondsF()
             << " seconds.";