diff --git a/database/yggstate.mwb b/database/yggstate.mwb index a8e2d67..4acbca8 100644 Binary files a/database/yggstate.mwb and b/database/yggstate.mwb differ diff --git a/media/db-prototype.png b/media/db-prototype.png index 0fce076..f729fd1 100644 Binary files a/media/db-prototype.png and b/media/db-prototype.png differ diff --git a/src/crontab/crawler.php b/src/crontab/crawler.php index f4fb23f..b299107 100644 --- a/src/crontab/crawler.php +++ b/src/crontab/crawler.php @@ -44,7 +44,18 @@ $debug = [ 'insert' => 0, 'update' => 0, ] - ] + ], + 'coordinate' => [ + 'total' => [ + 'insert' => 0, + ], + 'route' => [ + 'total' => [ + 'insert' => 0, + 'delete' => 0, + ] + ] + ], ] ] ]; @@ -82,7 +93,7 @@ if ($connectedPeers = Yggverse\Yggdrasilctl\Yggdrasil::getPeers()) { $debug['yggdrasil']['peer']['total']['insert']++; } - // Init peer data + // Init peer remote if ($connectedPeerRemoteUrl = Yggverse\Parser\Url::parse($connectedPeerInfo->remote)) { if ($dbPeerRemote = $db->findPeerRemote($dbPeerId, @@ -122,6 +133,38 @@ if ($connectedPeers = Yggverse\Yggdrasilctl\Yggdrasil::getPeers()) { $debug['yggdrasil']['peer']['remote']['total']['insert']++; } + + // Init peer coordinate + if ($dbPeerCoordinate = $db->getLastCoordinate($dbPeerId)) { + + $peerCoordinateId = $dbPeerCoordinate->peerCoordinateId; + + } else { + + $peerCoordinateId = $db->addPeerCoordinate($dbPeerId, $connectedPeerInfo->port, time()); + $debug['yggdrasil']['peer']['coordinate']['total']['insert']++; + } + + // Init peer coordinate route + + $localPeerCoordinateRoute = []; + foreach ($db->getPeerCoordinateRoute($peerCoordinateId) as $dbPeerCoordinateRoute) { + + $localPeerCoordinateRoute[$dbPeerCoordinateRoute->level] = $dbPeerCoordinateRoute->port; + } + + // Compare remote and local routes to prevent write operations + if ($localPeerCoordinateRoute !== $connectedPeerInfo->coords) { + + $debug['yggdrasil']['peer']['coordinate']['route']['total']['delete'] += + $db->flushPeerCoordinateRoute($peerCoordinateId); + + foreach ($connectedPeerInfo->coords as $level => $port) { + + $debug['yggdrasil']['peer']['coordinate']['route']['total']['insert'] += + $db->addPeerCoordinateRoute($peerCoordinateId, $level, $port); + } + } } $debug['yggdrasil']['peer']['total']['online']++; diff --git a/src/library/mysql.php b/src/library/mysql.php index 4f9fd7e..9979939 100644 --- a/src/library/mysql.php +++ b/src/library/mysql.php @@ -155,6 +155,68 @@ class MySQL { return $query->fetch(); } + // Peer coordinate + // https://github.com/matrix-org/pinecone/wiki/2.-Spanning-Tree#coordinates + + public function addPeerCoordinate(int $peerId, int $port, int $timeAdded) { + + $this->_debug->query->insert->total++; + + $query = $this->_db->prepare('INSERT INTO `peerCoordinate` SET `peerId` = ?, + `port` = ?, + `timeAdded` = ?'); + + $query->execute([$peerId, $port, $timeAdded]); + + return $this->_db->lastInsertId(); + } + + public function addPeerCoordinateRoute(int $peerCoordinateId, int $level, int $port) { + + $this->_debug->query->insert->total++; + + $query = $this->_db->prepare('INSERT INTO `peerCoordinateRoute` SET `peerCoordinateId` = ?, + `level` = ?, + `port` = ?'); + + $query->execute([$peerCoordinateId, $level, $port]); + + return $this->_db->lastInsertId(); + } + + public function flushPeerCoordinateRoute(int $peerCoordinateId) { + + $this->_debug->query->delete->total++; + + $query = $this->_db->prepare('DELETE FROM `peerCoordinateRoute` WHERE `peerCoordinateId` = ?'); + + $query->execute([$peerCoordinateId]); + + return $query->rowCount(); + } + + public function getLastCoordinate(int $peerId) { + + $this->_debug->query->select->total++; + + $query = $this->_db->prepare('SELECT * FROM `peerCoordinate` WHERE `peerId` = ? ORDER BY `timeAdded` DESC LIMIT 1'); + + $query->execute([$peerId]); + + return $query->fetch(); + } + + public function getPeerCoordinateRoute(int $peerCoordinateId) { + + $this->_debug->query->select->total++; + + $query = $this->_db->prepare('SELECT * FROM `peerCoordinateRoute` WHERE `peerCoordinateId` = ? ORDER BY `level` ASC'); + + $query->execute([$peerCoordinateId]); + + return $query->fetchAll(); + } + // Other public function optimize() {