From 006a1d60c82699612fa2d98629ba990735a3e356 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 10 Nov 2015 15:31:51 -0800 Subject: [PATCH] keep some additional erase entities history and send to viewers --- .../src/entities/EntityNodeData.h | 6 +- .../src/entities/EntityServer.cpp | 5 +- libraries/entities/src/EntityTree.cpp | 116 +++++++++--------- 3 files changed, 65 insertions(+), 62 deletions(-) diff --git a/assignment-client/src/entities/EntityNodeData.h b/assignment-client/src/entities/EntityNodeData.h index e4008fcb03..69da9ee14b 100644 --- a/assignment-client/src/entities/EntityNodeData.h +++ b/assignment-client/src/entities/EntityNodeData.h @@ -18,9 +18,7 @@ class EntityNodeData : public OctreeQueryNode { public: - EntityNodeData() : - OctreeQueryNode(), - _lastDeletedEntitiesSentAt(0) { } + EntityNodeData() : OctreeQueryNode() { } virtual PacketType getMyPacketType() const { return PacketType::EntityData; } @@ -28,7 +26,7 @@ public: void setLastDeletedEntitiesSentAt(quint64 sentAt) { _lastDeletedEntitiesSentAt = sentAt; } private: - quint64 _lastDeletedEntitiesSentAt; + quint64 _lastDeletedEntitiesSentAt { usecTimestampNow() }; }; #endif // hifi_EntityNodeData_h diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index f2a4c2664a..e2941541af 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -82,7 +82,6 @@ bool EntityServer::hasSpecialPacketsToSend(const SharedNodePointer& node) { EntityNodeData* nodeData = static_cast(node->getLinkedData()); if (nodeData) { quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt(); - EntityTreePointer tree = std::static_pointer_cast(_tree); shouldSendDeletedEntities = tree->hasEntitiesDeletedSince(deletedEntitiesSentAt); } @@ -97,7 +96,6 @@ int EntityServer::sendSpecialPackets(const SharedNodePointer& node, OctreeQueryN if (nodeData) { quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt(); quint64 deletePacketSentAt = usecTimestampNow(); - EntityTreePointer tree = std::static_pointer_cast(_tree); bool hasMoreToSend = true; @@ -127,7 +125,6 @@ void EntityServer::pruneDeletedEntities() { if (tree->hasAnyDeletedEntities()) { quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future - DependencyManager::get()->eachNode([&earliestLastDeletedEntitiesSent](const SharedNodePointer& node) { if (node->getLinkedData()) { EntityNodeData* nodeData = static_cast(node->getLinkedData()); @@ -138,6 +135,8 @@ void EntityServer::pruneDeletedEntities() { } }); + int EXTRA_SECONDS_TO_KEEP = 4; + earliestLastDeletedEntitiesSent -= USECS_PER_SECOND * EXTRA_SECONDS_TO_KEEP; tree->forgetEntitiesDeletedBefore(earliestLastDeletedEntitiesSent); } } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 8e32158362..c69c2daa16 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -384,16 +384,17 @@ void EntityTree::deleteEntities(QSet entityIDs, bool force, bool i } void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) { + quint64 deletedAt = usecTimestampNow(); const RemovedEntities& entities = theOperator.getEntities(); foreach(const EntityToDeleteDetails& details, entities) { EntityItemPointer theEntity = details.entity; if (getIsServer()) { // set up the deleted entities ID - quint64 deletedAt = usecTimestampNow(); - _recentlyDeletedEntitiesLock.lockForWrite(); - _recentlyDeletedEntityItemIDs.insert(deletedAt, theEntity->getEntityItemID()); - _recentlyDeletedEntitiesLock.unlock(); + { + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + _recentlyDeletedEntityItemIDs.insert(deletedAt, theEntity->getEntityItemID()); + } } if (_simulation) { @@ -802,18 +803,23 @@ void EntityTree::update() { } bool EntityTree::hasEntitiesDeletedSince(quint64 sinceTime) { + int EXTRA_SECONDS_TO_CONSIDER = 4; + quint64 considerEntitiesSince = sinceTime - (USECS_PER_SECOND * EXTRA_SECONDS_TO_CONSIDER); + // we can probably leverage the ordered nature of QMultiMap to do this quickly... bool hasSomethingNewer = false; + { + QReadLocker locker(&_recentlyDeletedEntitiesLock); - _recentlyDeletedEntitiesLock.lockForRead(); - QMultiMap::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin(); - while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) { - if (iterator.key() > sinceTime) { - hasSomethingNewer = true; + QMultiMap::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin(); + while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) { + if (iterator.key() > considerEntitiesSince) { + hasSomethingNewer = true; + } + ++iterator; } - ++iterator; } - _recentlyDeletedEntitiesLock.unlock(); + return hasSomethingNewer; } @@ -821,6 +827,8 @@ bool EntityTree::hasEntitiesDeletedSince(quint64 sinceTime) { std::unique_ptr EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime, bool& hasMore) { + int EXTRA_SECONDS_TO_CONSIDER = 4; + quint64 considerEntitiesSince = sinceTime - (USECS_PER_SECOND * EXTRA_SECONDS_TO_CONSIDER); auto deletesPacket = NLPacket::create(PacketType::EntityErase); // pack in flags @@ -841,48 +849,46 @@ std::unique_ptr EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_S // we keep a multi map of entity IDs to timestamps, we only want to include the entity IDs that have been // deleted since we last sent to this node - _recentlyDeletedEntitiesLock.lockForRead(); + { + QReadLocker locker(&_recentlyDeletedEntitiesLock); - bool hasFilledPacket = false; + bool hasFilledPacket = false; - auto it = _recentlyDeletedEntityItemIDs.constBegin(); - while (it != _recentlyDeletedEntityItemIDs.constEnd()) { - QList values = _recentlyDeletedEntityItemIDs.values(it.key()); - for (int valueItem = 0; valueItem < values.size(); ++valueItem) { + auto it = _recentlyDeletedEntityItemIDs.constBegin(); + while (it != _recentlyDeletedEntityItemIDs.constEnd()) { + QList values = _recentlyDeletedEntityItemIDs.values(it.key()); + for (int valueItem = 0; valueItem < values.size(); ++valueItem) { - // if the timestamp is more recent then out last sent time, include it - if (it.key() > sinceTime) { - QUuid entityID = values.at(valueItem); - deletesPacket->write(entityID.toRfc4122()); + // if the timestamp is more recent then out last sent time, include it + if (it.key() > considerEntitiesSince) { + QUuid entityID = values.at(valueItem); + deletesPacket->write(entityID.toRfc4122()); + ++numberOfIDs; - ++numberOfIDs; - - // check to make sure we have room for one more ID - if (NUM_BYTES_RFC4122_UUID > deletesPacket->bytesAvailableForWrite()) { - hasFilledPacket = true; - break; + // check to make sure we have room for one more ID + if (NUM_BYTES_RFC4122_UUID > deletesPacket->bytesAvailableForWrite()) { + hasFilledPacket = true; + break; + } } } + + // check to see if we're about to return + if (hasFilledPacket) { + // let our caller know how far we got + sinceTime = it.key(); + break; + } + + ++it; } - // check to see if we're about to return - if (hasFilledPacket) { - // let our caller know how far we got - sinceTime = it.key(); - - break; + // if we got to the end, then we're done sending + if (it == _recentlyDeletedEntityItemIDs.constEnd()) { + hasMore = false; } - - ++it; } - // if we got to the end, then we're done sending - if (it == _recentlyDeletedEntityItemIDs.constEnd()) { - hasMore = false; - } - - _recentlyDeletedEntitiesLock.unlock(); - // replace the count for the number of included IDs deletesPacket->seek(numberOfIDsPos); deletesPacket->writePrimitive(numberOfIDs); @@ -895,23 +901,23 @@ std::unique_ptr EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_S void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) { QSet keysToRemove; - _recentlyDeletedEntitiesLock.lockForWrite(); - QMultiMap::iterator iterator = _recentlyDeletedEntityItemIDs.begin(); + { + QWriteLocker locker(&_recentlyDeletedEntitiesLock); + QMultiMap::iterator iterator = _recentlyDeletedEntityItemIDs.begin(); - // First find all the keys in the map that are older and need to be deleted - while (iterator != _recentlyDeletedEntityItemIDs.end()) { - if (iterator.key() <= sinceTime) { - keysToRemove << iterator.key(); + // First find all the keys in the map that are older and need to be deleted + while (iterator != _recentlyDeletedEntityItemIDs.end()) { + if (iterator.key() <= sinceTime) { + keysToRemove << iterator.key(); + } + ++iterator; } - ++iterator; - } - // Now run through the keysToRemove and remove them - foreach (quint64 value, keysToRemove) { - _recentlyDeletedEntityItemIDs.remove(value); + // Now run through the keysToRemove and remove them + foreach (quint64 value, keysToRemove) { + _recentlyDeletedEntityItemIDs.remove(value); + } } - - _recentlyDeletedEntitiesLock.unlock(); }