Movable.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @package Zend_Memory
  16. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  17. * @license http://framework.zend.com/license/new-bsd New BSD License
  18. * @version $Id$
  19. */
  20. /** Zend_Memory_Container */
  21. require_once 'Zend/Memory/Container.php';
  22. /** Zend_Memory_Value */
  23. require_once 'Zend/Memory/Value.php';
  24. /**
  25. * Memory value container
  26. *
  27. * Movable (may be swapped with specified backend and unloaded).
  28. *
  29. * @category Zend
  30. * @package Zend_Memory
  31. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  32. * @license http://framework.zend.com/license/new-bsd New BSD License
  33. */
  34. class Zend_Memory_Container_Movable extends Zend_Memory_Container {
  35. /**
  36. * Internal object Id
  37. *
  38. * @var integer
  39. */
  40. protected $_id;
  41. /**
  42. * Memory manager reference
  43. *
  44. * @var Zend_Memory_Manager
  45. */
  46. private $_memManager;
  47. /**
  48. * Value object
  49. *
  50. * @var Zend_Memory_Value
  51. */
  52. private $_value;
  53. /** Value states */
  54. const LOADED = 1;
  55. const SWAPPED = 2;
  56. const LOCKED = 4;
  57. /**
  58. * Value state (LOADED/SWAPPED/LOCKED)
  59. *
  60. * @var integer
  61. */
  62. private $_state;
  63. /**
  64. * Object constructor
  65. *
  66. * @param Zend_Memory_Manager $memoryManager
  67. * @param integer $id
  68. * @param string $value
  69. */
  70. public function __construct(Zend_Memory_Manager $memoryManager, $id, $value)
  71. {
  72. $this->_memManager = $memoryManager;
  73. $this->_id = $id;
  74. $this->_state = self::LOADED;
  75. $this->_value = new Zend_Memory_Value($value, $this);
  76. }
  77. /**
  78. * Lock object in memory.
  79. */
  80. public function lock()
  81. {
  82. if ( !($this->_state & self::LOADED) ) {
  83. $this->_memManager->load($this, $this->_id);
  84. $this->_state |= self::LOADED;
  85. }
  86. $this->_state |= self::LOCKED;
  87. /**
  88. * @todo
  89. * It's possible to set "value" container attribute to avoid modification tracing, while it's locked
  90. * Check, if it's more effective
  91. */
  92. }
  93. /**
  94. * Unlock object
  95. */
  96. public function unlock()
  97. {
  98. // Clear LOCKED state bit
  99. $this->_state &= ~self::LOCKED;
  100. }
  101. /**
  102. * Return true if object is locked
  103. *
  104. * @return boolean
  105. */
  106. public function isLocked()
  107. {
  108. return $this->_state & self::LOCKED;
  109. }
  110. /**
  111. * Get handler
  112. *
  113. * Loads object if necessary and moves it to the top of loaded objects list.
  114. * Swaps objects from the bottom of loaded objects list, if necessary.
  115. *
  116. * @param string $property
  117. * @return string
  118. * @throws Zend_Memory_Exception
  119. */
  120. public function __get($property)
  121. {
  122. if ($property != 'value') {
  123. require_once 'Zend/Memory/Exception.php';
  124. throw new Zend_Memory_Exception('Unknown property: Zend_Memory_container::$' . $property);
  125. }
  126. if ( !($this->_state & self::LOADED) ) {
  127. $this->_memManager->load($this, $this->_id);
  128. $this->_state |= self::LOADED;
  129. }
  130. return $this->_value;
  131. }
  132. /**
  133. * Set handler
  134. *
  135. * @param string $property
  136. * @param string $value
  137. * @throws Zend_Exception
  138. */
  139. public function __set($property, $value)
  140. {
  141. if ($property != 'value') {
  142. require_once 'Zend/Memory/Exception.php';
  143. throw new Zend_Memory_Exception('Unknown property: Zend_Memory_container::$' . $property);
  144. }
  145. $this->_state = self::LOADED;
  146. $this->_value = new Zend_Memory_Value($value, $this);
  147. $this->_memManager->processUpdate($this, $this->_id);
  148. }
  149. /**
  150. * Get string value reference
  151. *
  152. * _Must_ be used for value access before PHP v 5.2
  153. * or _may_ be used for performance considerations
  154. *
  155. * @return &string
  156. */
  157. public function &getRef()
  158. {
  159. if ( !($this->_state & self::LOADED) ) {
  160. $this->_memManager->load($this, $this->_id);
  161. $this->_state |= self::LOADED;
  162. }
  163. return $this->_value->getRef();
  164. }
  165. /**
  166. * Signal, that value is updated by external code.
  167. *
  168. * Should be used together with getRef()
  169. */
  170. public function touch()
  171. {
  172. $this->_memManager->processUpdate($this, $this->_id);
  173. }
  174. /**
  175. * Process container value update.
  176. * Must be called only by value object
  177. *
  178. * @internal
  179. */
  180. public function processUpdate()
  181. {
  182. // Clear SWAPPED state bit
  183. $this->_state &= ~self::SWAPPED;
  184. $this->_memManager->processUpdate($this, $this->_id);
  185. }
  186. /**
  187. * Start modifications trace
  188. *
  189. * @internal
  190. */
  191. public function startTrace()
  192. {
  193. if ( !($this->_state & self::LOADED) ) {
  194. $this->_memManager->load($this, $this->_id);
  195. $this->_state |= self::LOADED;
  196. }
  197. $this->_value->startTrace();
  198. }
  199. /**
  200. * Set value (used by memory manager when value is loaded)
  201. *
  202. * @internal
  203. */
  204. public function setValue($value)
  205. {
  206. $this->_value = new Zend_Memory_Value($value, $this);
  207. }
  208. /**
  209. * Clear value (used by memory manager when value is swapped)
  210. *
  211. * @internal
  212. */
  213. public function unloadValue()
  214. {
  215. // Clear LOADED state bit
  216. $this->_state &= ~self::LOADED;
  217. $this->_value = null;
  218. }
  219. /**
  220. * Mark, that object is swapped
  221. *
  222. * @internal
  223. */
  224. public function markAsSwapped()
  225. {
  226. // Clear LOADED state bit
  227. $this->_state |= self::LOADED;
  228. }
  229. /**
  230. * Check if object is marked as swapped
  231. *
  232. * @internal
  233. * @return boolean
  234. */
  235. public function isSwapped()
  236. {
  237. return $this->_state & self::SWAPPED;
  238. }
  239. /**
  240. * Get object id
  241. *
  242. * @internal
  243. * @return integer
  244. */
  245. public function getId()
  246. {
  247. return $this->_id;
  248. }
  249. /**
  250. * Destroy memory container and remove it from memory manager list
  251. *
  252. * @internal
  253. */
  254. public function destroy()
  255. {
  256. /**
  257. * We don't clean up swap because of performance considerations
  258. * Cleaning is performed by Memory Manager destructor
  259. */
  260. $this->_memManager->unlink($this, $this->_id);
  261. }
  262. }