leverage new libcuckoo hash outside LimitedNodeList

This commit is contained in:
Stephen Birarda 2014-11-05 15:09:54 -08:00
parent a492abc3a1
commit 8a72cdd59d
16 changed files with 157 additions and 64 deletions

View file

@ -437,7 +437,12 @@ int AudioMixer::prepareMixForListeningNode(Node* node) {
// loop through all other nodes that have sufficient audio to mix // loop through all other nodes that have sufficient audio to mix
int streamsMixed = 0; int streamsMixed = 0;
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer otherNode = it->second;
if (otherNode->getLinkedData()) { if (otherNode->getLinkedData()) {
AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData(); AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData();
@ -480,7 +485,11 @@ void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const Hif
QByteArray packet = receivedPacket; QByteArray packet = receivedPacket;
populatePacketHeader(packet, PacketTypeMuteEnvironment); populatePacketHeader(packet, PacketTypeMuteEnvironment);
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && node != nodeList->sendingNodeForPacket(receivedPacket)) { if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && node != nodeList->sendingNodeForPacket(receivedPacket)) {
nodeList->writeDatagram(packet, packet.size(), node); nodeList->writeDatagram(packet, packet.size(), node);
} }
@ -548,8 +557,10 @@ void AudioMixer::sendStatsPacket() {
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
int clientNumber = 0; int clientNumber = 0;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
// if we're too large, send the packet // if we're too large, send the packet
if (sizeOfStats > TOO_BIG_FOR_MTU) { if (sizeOfStats > TOO_BIG_FOR_MTU) {
nodeList->sendStatsToDomainServer(statsObject2); nodeList->sendStatsToDomainServer(statsObject2);
@ -559,9 +570,9 @@ void AudioMixer::sendStatsPacket() {
} }
clientNumber++; clientNumber++;
AudioMixerClientData* clientData = static_cast<AudioMixerClientData*>(node->getLinkedData()); AudioMixerClientData* clientData = static_cast<AudioMixerClientData*>(it->second->getLinkedData());
if (clientData) { if (clientData) {
QString property = "jitterStats." + node->getUUID().toString(); QString property = "jitterStats." + it->first.toString();
QString value = clientData->getAudioStreamStatsString(); QString value = clientData->getAudioStreamStatsString();
statsObject2[qPrintable(property)] = value; statsObject2[qPrintable(property)] = value;
somethingToSend = true; somethingToSend = true;
@ -706,7 +717,11 @@ void AudioMixer::run() {
_lastPerSecondCallbackTime = now; _lastPerSecondCallbackTime = now;
} }
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getLinkedData()) { if (node->getLinkedData()) {
AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData();
@ -873,7 +888,11 @@ void AudioMixer::perSecondActions() {
_timeSpentPerHashMatchCallStats.getWindowSum() / WINDOW_LENGTH_USECS * 100.0, _timeSpentPerHashMatchCallStats.getWindowSum() / WINDOW_LENGTH_USECS * 100.0,
_timeSpentPerHashMatchCallStats.getCurrentIntervalSum() / USECS_PER_SECOND * 100.0); _timeSpentPerHashMatchCallStats.getCurrentIntervalSum() / USECS_PER_SECOND * 100.0);
foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getLinkedData()) { if (node->getLinkedData()) {
AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData();

View file

@ -122,7 +122,9 @@ void AvatarMixer::broadcastAvatarData() {
AvatarMixerClientData* nodeData = NULL; AvatarMixerClientData* nodeData = NULL;
AvatarMixerClientData* otherNodeData = NULL; AvatarMixerClientData* otherNodeData = NULL;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket() if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()
&& (nodeData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData()))->getMutex().tryLock()) { && (nodeData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData()))->getMutex().tryLock()) {
++_sumListeners; ++_sumListeners;
@ -135,7 +137,9 @@ void AvatarMixer::broadcastAvatarData() {
// this is an AGENT we have received head data from // this is an AGENT we have received head data from
// send back a packet with other active node data to this node // send back a packet with other active node data to this node
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) { NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer otherNode = it->second;
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID() if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()
&& (otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData()))->getMutex().tryLock()) { && (otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData()))->getMutex().tryLock()) {

View file

@ -123,9 +123,14 @@ void EntityServer::pruneDeletedEntities() {
if (tree->hasAnyDeletedEntities()) { if (tree->hasAnyDeletedEntities()) {
quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
if (otherNode->getLinkedData()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
EntityNodeData* nodeData = static_cast<EntityNodeData*>(otherNode->getLinkedData());
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getLinkedData()) {
EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
quint64 nodeLastDeletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt(); quint64 nodeLastDeletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
if (nodeLastDeletedEntitiesSentAt < earliestLastDeletedEntitiesSent) { if (nodeLastDeletedEntitiesSentAt < earliestLastDeletedEntitiesSent) {
earliestLastDeletedEntitiesSent = nodeLastDeletedEntitiesSentAt; earliestLastDeletedEntitiesSent = nodeLastDeletedEntitiesSentAt;

View file

@ -248,7 +248,7 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
continue; continue;
} }
const SharedNodePointer& destinationNode = NodeList::getInstance()->getNodeHash().value(nodeUUID); const SharedNodePointer& destinationNode = NodeList::getInstance()->nodeWithUUID(nodeUUID);
// retrieve sequence number stats of node, prune its missing set // retrieve sequence number stats of node, prune its missing set
SequenceNumberStats& sequenceNumberStats = nodeStats.getIncomingEditSequenceNumberStats(); SequenceNumberStats& sequenceNumberStats = nodeStats.getIncomingEditSequenceNumberStats();

View file

@ -1137,9 +1137,12 @@ void OctreeServer::aboutToFinish() {
qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish..."; qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish...";
qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down..."; qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down...";
_octreeInboundPacketProcessor->shuttingDown(); _octreeInboundPacketProcessor->shuttingDown();
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node; NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
forceNodeShutdown(node);
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *it->second;
forceNodeShutdown(it->second);
} }
qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish..."; qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish...";
} }

View file

@ -821,7 +821,10 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
if (nodeData->isAuthenticated()) { if (nodeData->isAuthenticated()) {
// if this authenticated node has any interest types, send back those nodes as well // if this authenticated node has any interest types, send back those nodes as well
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) { NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer otherNode = it->second;
// reset our nodeByteArray and nodeDataStream // reset our nodeByteArray and nodeDataStream
QByteArray nodeByteArray; QByteArray nodeByteArray;
@ -960,7 +963,10 @@ void DomainServer::readAvailableDatagrams() {
void DomainServer::setupPendingAssignmentCredits() { void DomainServer::setupPendingAssignmentCredits() {
// enumerate the NodeList to find the assigned nodes // enumerate the NodeList to find the assigned nodes
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData()); DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
if (!nodeData->getAssignmentUUID().isNull() && !nodeData->getWalletUUID().isNull()) { if (!nodeData->getAssignmentUUID().isNull() && !nodeData->getWalletUUID().isNull()) {
@ -1119,7 +1125,13 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) {
// add the number of currently connected agent users // add the number of currently connected agent users
int numConnectedAuthedUsers = 0; int numConnectedAuthedUsers = 0;
foreach(const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getLinkedData() && !static_cast<DomainServerNodeData*>(node->getLinkedData())->getUsername().isEmpty()) { if (node->getLinkedData() && !static_cast<DomainServerNodeData*>(node->getLinkedData())->getUsername().isEmpty()) {
++numConnectedAuthedUsers; ++numConnectedAuthedUsers;
} }
@ -1242,8 +1254,9 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS
parseNodeDataFromByteArray(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress, parseNodeDataFromByteArray(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress,
senderSockAddr); senderSockAddr);
SharedNodePointer checkInNode = nodeList->updateSocketsForNode(nodeUUID, SharedNodePointer checkInNode = nodeList->nodeWithUUID(nodeUUID);
nodePublicAddress, nodeLocalAddress); checkInNode->setPublicSocket(nodePublicAddress);
checkInNode->setLocalSocket(nodeLocalAddress);
// update last receive to now // update last receive to now
quint64 timeNow = usecTimestampNow(); quint64 timeNow = usecTimestampNow();
@ -1425,7 +1438,12 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
QJsonObject assignedNodesJSON; QJsonObject assignedNodesJSON;
// enumerate the NodeList to find the assigned nodes // enumerate the NodeList to find the assigned nodes
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData()); DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
if (!nodeData->getAssignmentUUID().isNull()) { if (!nodeData->getAssignmentUUID().isNull()) {
@ -1489,9 +1507,11 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
// enumerate the NodeList to find the assigned nodes // enumerate the NodeList to find the assigned nodes
LimitedNodeList* nodeList = LimitedNodeList::getInstance(); LimitedNodeList* nodeList = LimitedNodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
// add the node using the UUID as the key // add the node using the UUID as the key
nodesJSONArray.append(jsonObjectForNode(node)); nodesJSONArray.append(jsonObjectForNode(it->second));
} }
rootJSON["nodes"] = nodesJSONArray; rootJSON["nodes"] = nodesJSONArray;
@ -2023,8 +2043,10 @@ void DomainServer::addStaticAssignmentsToQueue() {
bool foundMatchingAssignment = false; bool foundMatchingAssignment = false;
// enumerate the nodes and check if there is one with an attached assignment with matching UUID // enumerate the nodes and check if there is one with an attached assignment with matching UUID
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
if (node->getUUID() == staticAssignment->data()->getUUID()) {
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
if (it->first == staticAssignment->data()->getUUID()) {
foundMatchingAssignment = true; foundMatchingAssignment = true;
} }
} }

View file

@ -2405,7 +2405,10 @@ int Application::sendNackPackets() {
char packet[MAX_PACKET_SIZE]; char packet[MAX_PACKET_SIZE];
// iterates thru all nodes in NodeList // iterates thru all nodes in NodeList
foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getActiveSocket() && if (node->getActiveSocket() &&
( node->getType() == NodeType::VoxelServer ( node->getType() == NodeType::VoxelServer
@ -2503,7 +2506,13 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
int inViewServers = 0; int inViewServers = 0;
int unknownJurisdictionServers = 0; int unknownJurisdictionServers = 0;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { NodeList* nodeList = NodeList::getInstance();
NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
// only send to the NodeTypes that are serverType // only send to the NodeTypes that are serverType
if (node->getActiveSocket() && node->getType() == serverType) { if (node->getActiveSocket() && node->getType() == serverType) {
totalServers++; totalServers++;
@ -2560,10 +2569,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
if (wantExtraDebugging) { if (wantExtraDebugging) {
qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
} }
NodeList* nodeList = NodeList::getInstance(); for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
// only send to the NodeTypes that are serverType // only send to the NodeTypes that are serverType
if (node->getActiveSocket() && node->getType() == serverType) { if (node->getActiveSocket() && node->getType() == serverType) {

View file

@ -163,7 +163,12 @@ void MetavoxelSystem::render() {
} }
void MetavoxelSystem::refreshVoxelData() { void MetavoxelSystem::refreshVoxelData() {
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getType() == NodeType::MetavoxelServer) { if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex()); QMutexLocker locker(&node->getMutex());
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData()); MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
@ -685,7 +690,11 @@ MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) {
} }
void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) { void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getType() == NodeType::MetavoxelServer) { if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex()); QMutexLocker locker(&node->getMutex());
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData()); MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());

View file

@ -42,7 +42,11 @@ SharedObjectPointer MetavoxelClientManager::findFirstRaySpannerIntersection(cons
const glm::vec3& direction, const AttributePointer& attribute, float& distance) { const glm::vec3& direction, const AttributePointer& attribute, float& distance) {
SharedObjectPointer closestSpanner; SharedObjectPointer closestSpanner;
float closestDistance = FLT_MAX; float closestDistance = FLT_MAX;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getType() == NodeType::MetavoxelServer) { if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex()); QMutexLocker locker(&node->getMutex());
MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData()); MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData());
@ -115,7 +119,11 @@ MetavoxelClient* MetavoxelClientManager::createClient(const SharedNodePointer& n
} }
void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) { void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) {
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
if (node->getType() == NodeType::MetavoxelServer) { if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex()); QMutexLocker locker(&node->getMutex());
MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData()); MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData());

View file

@ -392,7 +392,10 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
try { try {
SharedNodePointer matchingNode = _nodeHash[uuid]; SharedNodePointer matchingNode = _nodeHash[uuid];
matchingNode->updateSockets(publicSocket, localSocket);
matchingNode->setPublicSocket(publicSocket);
matchingNode->setLocalSocket(localSocket);
return matchingNode; return matchingNode;
} catch (std::out_of_range) { } catch (std::out_of_range) {
// we didn't have this node, so add them // we didn't have this node, so add them
@ -412,7 +415,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) { unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) {
unsigned n = 0; unsigned n = 0;
SnapshotNodeHash snapshotHash = _nodeHash.snapshot_table(); NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
if (destinationNodeTypes.contains(it->second->getType())) { if (destinationNodeTypes.contains(it->second->getType())) {
writeDatagram(packet, it->second); writeDatagram(packet, it->second);
@ -459,7 +462,7 @@ QByteArray LimitedNodeList::constructPingReplyPacket(const QByteArray& pingPacke
SharedNodePointer LimitedNodeList::soloNodeOfType(char nodeType) { SharedNodePointer LimitedNodeList::soloNodeOfType(char nodeType) {
if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) { if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) {
SnapshotNodeHash snapshotHash = _nodeHash.snapshot_table(); NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
if (it->second->getType() == nodeType) { if (it->second->getType() == nodeType) {
@ -483,7 +486,7 @@ void LimitedNodeList::resetPacketStats() {
void LimitedNodeList::removeSilentNodes() { void LimitedNodeList::removeSilentNodes() {
SnapshotNodeHash snapshotHash = _nodeHash.snapshot_table(); NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second; SharedNodePointer node = it->second;

View file

@ -55,7 +55,7 @@ typedef QSharedPointer<Node> SharedNodePointer;
Q_DECLARE_METATYPE(SharedNodePointer) Q_DECLARE_METATYPE(SharedNodePointer)
typedef cuckoohash_map<QUuid, SharedNodePointer, UUIDCityHasher > NodeHash; typedef cuckoohash_map<QUuid, SharedNodePointer, UUIDCityHasher > NodeHash;
typedef std::vector<std::pair<QUuid, SharedNodePointer> > SnapshotNodeHash; typedef std::vector<std::pair<QUuid, SharedNodePointer> > NodeHashSnapshot;
typedef quint8 PingType_t; typedef quint8 PingType_t;
namespace PingType { namespace PingType {
@ -104,8 +104,6 @@ public:
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
SharedNodePointer updateSocketsForNode(const QUuid& uuid,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; } const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }

View file

@ -81,8 +81,6 @@ public:
const HifiSockAddr& getSymmetricSocket() const { return _symmetricSocket; } const HifiSockAddr& getSymmetricSocket() const { return _symmetricSocket; }
virtual void setSymmetricSocket(const HifiSockAddr& symmetricSocket); virtual void setSymmetricSocket(const HifiSockAddr& symmetricSocket);
void updateSockets(const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
const HifiSockAddr* getActiveSocket() const { return _activeSocket; } const HifiSockAddr* getActiveSocket() const { return _activeSocket; }
void activatePublicSocket(); void activatePublicSocket();

View file

@ -40,9 +40,11 @@ bool JurisdictionListener::queueJurisdictionRequest() {
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { NodeHashSnapshot nodeHashSnapshot = nodeList->getNodeHash().snapshot_table();
if (node->getType() == getNodeType() && node->getActiveSocket()) {
_packetSender.queuePacketForSending(node, QByteArray(reinterpret_cast<char*>(bufferOut), sizeOut)); for (auto it = nodeHashSnapshot.begin(); it != nodeHashSnapshot.end(); it++) {
if (it->second->getType() == getNodeType() && it->second->getActiveSocket()) {
_packetSender.queuePacketForSending(it->second, QByteArray(reinterpret_cast<char*>(bufferOut), sizeOut));
nodeCount++; nodeCount++;
} }
} }

View file

@ -52,12 +52,13 @@ bool OctreeEditPacketSender::serversExist() const {
bool hasServers = false; bool hasServers = false;
bool atLeastOneJurisdictionMissing = false; // assume the best bool atLeastOneJurisdictionMissing = false; // assume the best
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
// only send to the NodeTypes that are getMyNodeType() // only send to the NodeTypes that are getMyNodeType()
SharedNodePointer node = it->second;
if (node->getType() == getMyNodeType() && node->getActiveSocket()) { if (node->getType() == getMyNodeType() && node->getActiveSocket()) {
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();
// If we've got Jurisdictions set, then check to see if we know the jurisdiction for this server // If we've got Jurisdictions set, then check to see if we know the jurisdiction for this server
if (_serverJurisdictions) { if (_serverJurisdictions) {
@ -86,8 +87,11 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c
bool wantDebug = false; bool wantDebug = false;
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
// only send to the NodeTypes that are getMyNodeType() // only send to the NodeTypes that are getMyNodeType()
if (node->getType() == getMyNodeType() && if (node->getType() == getMyNodeType() &&
((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) { ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
@ -194,8 +198,10 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, size_t le
// But we can't really do that with a packed message, since each edit message could be destined // But we can't really do that with a packed message, since each edit message could be destined
// for a different server... So we need to actually manage multiple queued packets... one // for a different server... So we need to actually manage multiple queued packets... one
// for each server // for each server
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
// only send to the NodeTypes that are getMyNodeType() // only send to the NodeTypes that are getMyNodeType()
if (node->getActiveSocket() && node->getType() == getMyNodeType()) { if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();
@ -249,7 +255,9 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch
_packetsQueueLock.lock(); _packetsQueueLock.lock();
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
// only send to the NodeTypes that are getMyNodeType() // only send to the NodeTypes that are getMyNodeType()
if (node->getActiveSocket() && node->getType() == getMyNodeType()) { if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();
@ -384,7 +392,7 @@ void OctreeEditPacketSender::processNackPacket(const QByteArray& packet) {
// retrieve packet from history // retrieve packet from history
const QByteArray* packet = sentPacketHistory.getPacket(sequenceNumber); const QByteArray* packet = sentPacketHistory.getPacket(sequenceNumber);
if (packet) { if (packet) {
const SharedNodePointer& node = NodeList::getInstance()->getNodeHash().value(sendingNodeUUID); const SharedNodePointer& node = NodeList::getInstance()->nodeWithUUID(sendingNodeUUID);
queuePacketForSending(node, *packet); queuePacketForSending(node, *packet);
} }
} }

View file

@ -76,8 +76,10 @@ void OctreeHeadlessViewer::queryOctree() {
int totalServers = 0; int totalServers = 0;
int inViewServers = 0; int inViewServers = 0;
int unknownJurisdictionServers = 0; int unknownJurisdictionServers = 0;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
// only send to the NodeTypes that are serverType // only send to the NodeTypes that are serverType
if (node->getActiveSocket() && node->getType() == serverType) { if (node->getActiveSocket() && node->getType() == serverType) {
totalServers++; totalServers++;
@ -142,11 +144,11 @@ void OctreeHeadlessViewer::queryOctree() {
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
// only send to the NodeTypes that are serverType // only send to the NodeTypes that are serverType
if (node->getActiveSocket() && node->getType() == serverType) { if (node->getActiveSocket() && node->getType() == serverType) {
// get the server bounds for this server // get the server bounds for this server
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();

View file

@ -520,7 +520,11 @@ void ScriptEngine::run() {
// write audio packet to AudioMixer nodes // write audio packet to AudioMixer nodes
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
foreach(const SharedNodePointer& node, nodeList->getNodeHash()) { NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table();
for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) {
SharedNodePointer node = it->second;
// only send to nodes of type AudioMixer // only send to nodes of type AudioMixer
if (node->getType() == NodeType::AudioMixer) { if (node->getType() == NodeType::AudioMixer) {
// pack sequence number // pack sequence number