]> git.mxchange.org Git - hub.git/blob - application/hub/main/dht/class_BaseDht.php
ad09de3e6a71ec2ca5c18069b797adf2a4811c2b
[hub.git] / application / hub / main / dht / class_BaseDht.php
1 <?php
2 /**
3  * A general DHT class
4  *
5  * @author              Roland Haeder <webmaster@shipsimu.org>
6  * @version             0.0.0
7  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Hub Developer Team
8  * @license             GNU GPL 3.0 or any newer version
9  * @link                http://www.shipsimu.org
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23  */
24 abstract class BaseDht extends BaseHubSystem {
25         /**
26          * Stacker name for "INSERT" node data
27          */
28         const STACKER_NAME_INSERT_NODE        = 'dht_insert_node';
29         const STACKER_NAME_PENDING_PUBLISHING = 'dht_pending_publish';
30
31         /**
32          * Protected constructor
33          *
34          * @param       $className      Name of the class
35          * @return      void
36          */
37         protected function __construct ($className) {
38                 // Call parent constructor
39                 parent::__construct($className);
40
41                 // Get a stacker instance for this DHT
42                 $stackerInstance = ObjectFactory::createObjectByConfiguredName('dht_stacker_class');
43
44                 // Set it in this class
45                 $this->setStackerInstance($stackerInstance);
46
47                 // Init all stackers
48                 $this->initStacks();
49
50                 /*
51                  * Get the state factory and create the initial state, we don't need
52                  * the state instance here
53                  */
54                 DhtStateFactory::createDhtStateInstanceByName('init', $this);
55         }
56
57         /**
58          * Initializes all stackers
59          *
60          * @return      void
61          */
62         private function initStacks () {
63                 // Initialize all stacker
64                 $this->getStackerInstance()->initStacks(array(
65                         self::STACKER_NAME_INSERT_NODE,
66                         self::STACKER_NAME_PENDING_PUBLISHING,
67                 ));
68         }
69
70         /**
71          * Registers/updates an entry in the DHT with given data from $dhtData
72          * array. Different DHT implemtations may handle this differently as they
73          * may enrich the data with more meta data.
74          *
75          * @param       $dhtData        A valid array with DHT-related data (e.g. node/peer data)
76          * @return      void
77          */
78         protected abstract function insertDataIntoDht (array $dhtData);
79
80         /**
81          * Updates/refreshes DHT data (e.g. status).
82          *
83          * @return      void
84          * @todo        Find more to do here
85          */
86         public function updateDhtData () {
87                 // Set some dummy configuration entries, e.g. dht_status
88                 $this->getConfigInstance()->setConfigEntry('dht_status', $this->getStateInstance()->getStateName());
89         }
90
91         /**
92          * Checks whether there are entries in "INSERT" node data stack
93          *
94          * @return      $isPending      Whether there are pending entries
95          */
96         public function ifInsertNodeDataPending () {
97                 // Determine it if it is not empty
98                 $isPending = ($this->getStackerInstance()->isStackEmpty(self::STACKER_NAME_INSERT_NODE) === FALSE);
99
100                 // Return status
101                 return $isPending;
102         }
103
104         /**
105          * Inserts a single entry of node data into the DHT
106          *
107          * @return      void
108          */
109         public function insertSingleNodeData () {
110                 // Get next node data from stack
111                 $nodeData = $this->getStackerInstance()->popNamed(self::STACKER_NAME_INSERT_NODE);
112
113                 // Make sure $nodeData is really an array and has at least one entry
114                 assert((is_array($nodeData)) && (count($nodeData) > 0));
115
116                 // Insert the data
117                 $this->insertDataIntoDht($nodeData);
118         }
119
120         /**
121          * Checks whether there are unpublished entries
122          *
123          * @return      $hasUnpublished         Whether there are unpublished entries
124          * @todo        Add minimum/maximum age limitations
125          */
126         public function hasUnpublishedEntries () {
127                 // Call method on database wrapper
128                 $hasUnpublished = $this->getWrapperInstance()->hasUnpublishedEntries();
129
130                 // Return it
131                 return $hasUnpublished;
132         }
133
134         /**
135          * Initializes publication of DHT entries. This does only prepare
136          * publication. The next step is to pickup such prepared entries and publish
137          * them by uploading to other (recently appeared) DHT members.
138          *
139          * @return      void
140          */
141         public function initEntryPublication () {
142                 // Call method on database wrapper
143                 $this->getWrapperInstance()->initEntryPublication();
144
145                 // Get result instance
146                 $resultInstance = $this->getWrapperInstance()->getUnpublishedEntriesInstance();
147
148                 // Must still be valid
149                 assert($resultInstance->valid());
150
151                 // "Walk" through all entries
152                 while ($resultInstance->next()) {
153                         // Get current entry
154                         $current = $resultInstance->current();
155
156                         // Make sure only valid entries pass
157                         // @TODO Maybe add more small checks?
158                         assert(is_array($current));
159
160                         // ... and push it to the next stack
161                         /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . '] Pushing entry with ' . count($current) . ' elements to stack ' . self::STACKER_NAME_PENDING_PUBLISHING . ' ...');
162                         $this->getStackerInstance()->pushNamed(self::STACKER_NAME_PENDING_PUBLISHING, $current);
163                 } // END - while
164         }
165
166         /**
167          * Checks whether there are entries pending publication
168          *
169          * @return      $isPending      Whether there are entries pending publication
170          */
171         public function hasEntriesPendingPublication () {
172                 // Determine it if it is not empty
173                 $isPending = ($this->getStackerInstance()->isStackEmpty(self::STACKER_NAME_PENDING_PUBLISHING) === FALSE);
174
175                 // Return status
176                 return $isPending;
177         }
178
179         /**
180          * Publishes next entry found in stack. This method shall also update the
181          * corresponding dabase entry.
182          *
183          * @return      void
184          */
185         public function publishEntry () {
186                 $this->partialStub('Unimplemented method.');
187         }
188 }
189
190 // [EOF]
191 ?>