use a vector for ignored node IDs

This commit is contained in:
Stephen Birarda 2018-08-03 10:38:11 -07:00
parent 5d00aa0bdb
commit aed79b3b17
4 changed files with 22 additions and 54 deletions

View file

@ -647,32 +647,9 @@ AudioMixerClientData::IgnoreZone& AudioMixerClientData::IgnoreZoneMemo::get(unsi
return _zone;
}
void AudioMixerClientData::IgnoreNodeCache::cache(bool shouldIgnore) {
if (!_isCached) {
_shouldIgnore = shouldIgnore;
_isCached = true;
}
}
bool AudioMixerClientData::IgnoreNodeCache::isCached() {
return _isCached;
}
bool AudioMixerClientData::IgnoreNodeCache::shouldIgnore() {
bool ignore = _shouldIgnore;
_isCached = false;
return ignore;
}
bool AudioMixerClientData::shouldIgnore(const SharedNodePointer self, const SharedNodePointer node, unsigned int frame) {
// this is symmetric over self / node; if computed, it is cached in the other
// check the cache to avoid computation
auto& cache = _nodeSourcesIgnoreMap[node->getUUID()];
if (cache.isCached()) {
return cache.shouldIgnore();
}
AudioMixerClientData* nodeData = static_cast<AudioMixerClientData*>(node->getLinkedData());
if (!nodeData) {
return false;
@ -696,8 +673,6 @@ bool AudioMixerClientData::shouldIgnore(const SharedNodePointer self, const Shar
}
}
// cache in node
nodeData->_nodeSourcesIgnoreMap[self->getUUID()].cache(shouldIgnore);
return shouldIgnore;
}

View file

@ -57,7 +57,7 @@ public:
void removeHRTFForStream(const QUuid& nodeID, const QUuid& streamID = QUuid());
// remove all sources and data from this node
void removeNode(const QUuid& nodeID) { _nodeSourcesIgnoreMap.unsafe_erase(nodeID); _nodeSourcesHRTFMap.erase(nodeID); }
void removeNode(const QUuid& nodeID) { _nodeSourcesHRTFMap.erase(nodeID); }
void removeAgentAvatarAudioStream();
@ -150,25 +150,6 @@ private:
};
IgnoreZoneMemo _ignoreZone;
class IgnoreNodeCache {
public:
// std::atomic is not copyable - always initialize uncached
IgnoreNodeCache() {}
IgnoreNodeCache(const IgnoreNodeCache& other) {}
void cache(bool shouldIgnore);
bool isCached();
bool shouldIgnore();
private:
std::atomic<bool> _isCached { false };
bool _shouldIgnore { false };
};
struct IgnoreNodeCacheHasher { std::size_t operator()(const QUuid& key) const { return qHash(key); } };
using NodeSourcesIgnoreMap = tbb::concurrent_unordered_map<QUuid, IgnoreNodeCache, IgnoreNodeCacheHasher>;
NodeSourcesIgnoreMap _nodeSourcesIgnoreMap;
using HRTFMap = std::unordered_map<QUuid, AudioHRTF>;
using NodeSourcesHRTFMap = std::unordered_map<QUuid, HRTFMap>;
NodeSourcesHRTFMap _nodeSourcesHRTFMap;

View file

@ -131,12 +131,14 @@ void Node::parseIgnoreRequestMessage(QSharedPointer<ReceivedMessage> message) {
void Node::addIgnoredNode(const QUuid& otherNodeID) {
if (!otherNodeID.isNull() && otherNodeID != _uuid) {
QReadLocker lock { &_ignoredNodeIDSetLock };
QWriteLocker lock { &_ignoredNodeIDSetLock };
qCDebug(networking) << "Adding" << uuidStringWithoutCurlyBraces(otherNodeID) << "to ignore set for"
<< uuidStringWithoutCurlyBraces(_uuid);
<< uuidStringWithoutCurlyBraces(_uuid);
// add the session UUID to the set of ignored ones for this listening node
_ignoredNodeIDSet.insert(otherNodeID);
if (std::find(_ignoredNodeIDs.begin(), _ignoredNodeIDs.end(), otherNodeID) == _ignoredNodeIDs.end()) {
_ignoredNodeIDs.push_back(otherNodeID);
}
} else {
qCWarning(networking) << "Node::addIgnoredNode called with null ID or ID of ignoring node.";
}
@ -144,18 +146,27 @@ void Node::addIgnoredNode(const QUuid& otherNodeID) {
void Node::removeIgnoredNode(const QUuid& otherNodeID) {
if (!otherNodeID.isNull() && otherNodeID != _uuid) {
// insert/find are read locked concurrently. unsafe_erase is not concurrent, and needs a write lock.
QWriteLocker lock { &_ignoredNodeIDSetLock };
qCDebug(networking) << "Removing" << uuidStringWithoutCurlyBraces(otherNodeID) << "from ignore set for"
<< uuidStringWithoutCurlyBraces(_uuid);
<< uuidStringWithoutCurlyBraces(_uuid);
// remove the session UUID from the set of ignored ones for this listening node
_ignoredNodeIDSet.unsafe_erase(otherNodeID);
// remove the session UUID from the set of ignored ones for this listening node, if it exists
auto it = std::remove(_ignoredNodeIDs.begin(), _ignoredNodeIDs.end(), otherNodeID);
if (it != _ignoredNodeIDs.end()) {
_ignoredNodeIDs.erase(it);
}
} else {
qCWarning(networking) << "Node::removeIgnoredNode called with null ID or ID of ignoring node.";
}
}
bool Node::isIgnoringNodeWithID(const QUuid& nodeID) const {
QReadLocker lock { &_ignoredNodeIDSetLock };
// check if this node ID is present in the ignore node ID set
return std::find(_ignoredNodeIDs.begin(), _ignoredNodeIDs.end(), nodeID) != _ignoredNodeIDs.end();
}
void Node::parseIgnoreRadiusRequestMessage(QSharedPointer<ReceivedMessage> message) {
bool enabled;
message->readPrimitive(&enabled);

View file

@ -15,6 +15,7 @@
#include <memory>
#include <ostream>
#include <stdint.h>
#include <vector>
#include <QtCore/QDebug>
#include <QtCore/QMutex>
@ -83,7 +84,7 @@ public:
void parseIgnoreRequestMessage(QSharedPointer<ReceivedMessage> message);
void addIgnoredNode(const QUuid& otherNodeID);
void removeIgnoredNode(const QUuid& otherNodeID);
bool isIgnoringNodeWithID(const QUuid& nodeID) const { QReadLocker lock { &_ignoredNodeIDSetLock }; return _ignoredNodeIDSet.find(nodeID) != _ignoredNodeIDSet.cend(); }
bool isIgnoringNodeWithID(const QUuid& nodeID) const;
void parseIgnoreRadiusRequestMessage(QSharedPointer<ReceivedMessage> message);
friend QDataStream& operator<<(QDataStream& out, const Node& node);
@ -108,7 +109,7 @@ private:
MovingPercentile _clockSkewMovingPercentile;
NodePermissions _permissions;
bool _isUpstream { false };
tbb::concurrent_unordered_set<QUuid, UUIDHasher> _ignoredNodeIDSet;
std::vector<QUuid> _ignoredNodeIDs;
mutable QReadWriteLock _ignoredNodeIDSetLock;
std::vector<QString> _replicatedUsernames { };