Tests if we can subtract "right" from "left" resulting in one valid Resource object. For example, two Resource objects with different name, type or role are not subtractable. NOTE: Set subtraction is always well defined, it does not require 'right' to be contained within 'left'. For example, assuming that "left = {1, 2}" and "right = {2, 3}", "left" and "right" are subtractable because "left - rig
| 458 | // subtractable because "left - right = {1}". However, "left" does not |
| 459 | // contain "right". |
| 460 | static bool subtractable(const Resource& left, const Resource& right) |
| 461 | { |
| 462 | // Check SharedInfo. |
| 463 | if (left.has_shared() != right.has_shared()) { |
| 464 | return false; |
| 465 | } |
| 466 | |
| 467 | // For shared resources, they can be subtracted only if left == right. |
| 468 | if (left.has_shared()) { |
| 469 | return left == right; |
| 470 | } |
| 471 | |
| 472 | // Now, we verify if the two non-shared resources can be subtracted. |
| 473 | if (left.name() != right.name() || left.type() != right.type()) { |
| 474 | return false; |
| 475 | } |
| 476 | |
| 477 | // Check AllocationInfo. |
| 478 | if (left.has_allocation_info() != right.has_allocation_info()) { |
| 479 | return false; |
| 480 | } |
| 481 | |
| 482 | if (left.has_allocation_info() && |
| 483 | left.allocation_info() != right.allocation_info()) { |
| 484 | return false; |
| 485 | } |
| 486 | |
| 487 | // Check the stack of ReservationInfo. |
| 488 | if (left.reservations_size() != right.reservations_size()) { |
| 489 | return false; |
| 490 | } |
| 491 | |
| 492 | for (int i = 0; i < left.reservations_size(); ++i) { |
| 493 | if (left.reservations(i) != right.reservations(i)) { |
| 494 | return false; |
| 495 | } |
| 496 | } |
| 497 | |
| 498 | // Check DiskInfo. |
| 499 | if (left.has_disk() != right.has_disk()) { return false; } |
| 500 | |
| 501 | if (left.has_disk()) { |
| 502 | if (left.disk() != right.disk()) { return false; } |
| 503 | |
| 504 | if (left.disk().has_source()) { |
| 505 | switch (left.disk().source().type()) { |
| 506 | case Resource::DiskInfo::Source::PATH: { |
| 507 | // Two PATH resources can be subtracted if their disks are identical. |
| 508 | break; |
| 509 | } |
| 510 | case Resource::DiskInfo::Source::BLOCK: |
| 511 | case Resource::DiskInfo::Source::MOUNT: { |
| 512 | // Two resources that represent exclusive 'MOUNT' or 'BLOCK' disks |
| 513 | // cannot be subtracted from each other if they are not the exact same |
| 514 | // mount; this would defeat the exclusivity. |
| 515 | if (left != right) { |
| 516 | return false; |
| 517 | } |