storageChain = new PriorityQueue(); } /** * @param StorageInterface $storage * @param int $priority */ public function add(StorageInterface $storage, $priority = 1) { $this->storageChain->insert($storage, $priority); } /** * Loop over the queue of storage until a storage is found that is non-empty. If such * storage is not found, then this chain storage itself is empty. * * In case a non-empty storage is found then this chain storage is also non-empty. Report * that, but also make sure that all storage with higher priorty that are empty * are filled. * * @see StorageInterface::isEmpty() */ public function isEmpty() { $storageWithHigherPriority = array(); // Loop invariant: $storageWithHigherPriority contains all storage with higher priorty // than the current one. foreach ($this->storageChain as $storage) { if ($storage->isEmpty()) { $storageWithHigherPriority[] = $storage; continue; } $storageValue = $storage->read(); foreach ($storageWithHigherPriority as $higherPriorityStorage) { $higherPriorityStorage->write($storageValue); } return false; } return true; } /** * If the chain is non-empty then the storage with the top priority is guaranteed to be * filled. Return its value. * * @see StorageInterface::read() */ public function read() { return $this->storageChain->top()->read(); } /** * Write the new $contents to all storage in the chain. * * @see StorageInterface::write() */ public function write($contents) { foreach ($this->storageChain as $storage) { $storage->write($contents); } } /** * Clear all storage in the chain. * * @see StorageInterface::clear() */ public function clear() { foreach ($this->storageChain as $storage) { $storage->clear(); } } }