v = (int)blob1->blob_location - (int)blob2->blob_location;
- /* Different locations? */
+ /* Different locations? Note: "unsafe compaction mode" requires that
+ * blobs in WIMs sort before all others. For the logic here to ensure
+ * this, BLOB_IN_WIM must have the lowest value among all defined
+ * blob_locations. Statically verify that the enum values haven't
+ * changed. */
+ STATIC_ASSERT(BLOB_NONEXISTENT == 0 && BLOB_IN_WIM == 1);
if (v)
return v;
wim1 = blob1->rdesc->wim;
wim2 = blob2->rdesc->wim;
- /* Different (possibly split) WIMs? */
+ /* Different WIM files? */
if (wim1 != wim2) {
+
+ /* Resources from the WIM file currently being compacted
+ * (if any) must always sort first. */
+ v = (int)wim2->being_compacted - (int)wim1->being_compacted;
+ if (v)
+ return v;
+
+ /* Different split WIMs? */
v = cmp_guids(wim1->hdr.guid, wim2->hdr.guid);
if (v)
return v;
+
+ /* Different part numbers in the same split WIM? */
+ v = (int)wim1->hdr.part_number - (int)wim2->hdr.part_number;
+ if (v)
+ return v;
+
+ /* Probably two WIMStructs for the same on-disk file.
+ * Just sort by pointer. */
+ return wim1 < wim2 ? -1 : 1;
}
- /* Different part numbers in the same WIM? */
- v = (int)wim1->hdr.part_number - (int)wim2->hdr.part_number;
- if (v)
- return v;
+ /* Same WIM file */
+ /* Sort by increasing resource offset */
if (blob1->rdesc->offset_in_wim != blob2->rdesc->offset_in_wim)
return cmp_u64(blob1->rdesc->offset_in_wim,
blob2->rdesc->offset_in_wim);
+ /* The blobs are in the same solid resource. Sort by increasing
+ * offset in the resource. */
return cmp_u64(blob1->offset_in_res, blob2->offset_in_res);
case BLOB_IN_FILE_ON_DISK: