RuleWatchNode.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\DependencyResolver;
  12. /**
  13. * Wrapper around a Rule which keeps track of the two literals it watches
  14. *
  15. * Used by RuleWatchGraph to store rules in two RuleWatchChains.
  16. *
  17. * @author Nils Adermann <naderman@naderman.de>
  18. */
  19. class RuleWatchNode
  20. {
  21. public $watch1;
  22. public $watch2;
  23. protected $rule;
  24. /**
  25. * Creates a new node watching the first and second literals of the rule.
  26. *
  27. * @param Rule $rule The rule to wrap
  28. */
  29. public function __construct($rule)
  30. {
  31. $this->rule = $rule;
  32. $literals = $rule->literals;
  33. $this->watch1 = count($literals) > 0 ? $literals[0] : 0;
  34. $this->watch2 = count($literals) > 1 ? $literals[1] : 0;
  35. }
  36. /**
  37. * Places the second watch on the rule's literal, decided at the highest level
  38. *
  39. * Useful for learned rules where the literal for the highest rule is most
  40. * likely to quickly lead to further decisions.
  41. *
  42. * @param Decisions $decisions The decisions made so far by the solver
  43. */
  44. public function watch2OnHighest(Decisions $decisions)
  45. {
  46. $literals = $this->rule->literals;
  47. // if there are only 2 elements, both are being watched anyway
  48. if (count($literals) < 3) {
  49. return;
  50. }
  51. $watchLevel = 0;
  52. foreach ($literals as $literal) {
  53. $level = $decisions->decisionLevel($literal);
  54. if ($level > $watchLevel) {
  55. $this->watch2 = $literal;
  56. $watchLevel = $level;
  57. }
  58. }
  59. }
  60. /**
  61. * Returns the rule this node wraps
  62. *
  63. * @return Rule
  64. */
  65. public function getRule()
  66. {
  67. return $this->rule;
  68. }
  69. /**
  70. * Given one watched literal, this method returns the other watched literal
  71. *
  72. * @param int $literal The watched literal that should not be returned
  73. * @return int A literal
  74. */
  75. public function getOtherWatch($literal)
  76. {
  77. if ($this->watch1 == $literal) {
  78. return $this->watch2;
  79. } else {
  80. return $this->watch1;
  81. }
  82. }
  83. /**
  84. * Moves a watch from one literal to another
  85. *
  86. * @param int $from The previously watched literal
  87. * @param int $to The literal to be watched now
  88. */
  89. public function moveWatch($from, $to)
  90. {
  91. if ($this->watch1 == $from) {
  92. $this->watch1 = $to;
  93. } else {
  94. $this->watch2 = $to;
  95. }
  96. }
  97. }