keep some additional erase entities history and send to viewers

This commit is contained in:
Brad Hefta-Gaub 2015-11-10 15:31:51 -08:00
parent ff87a6ce6f
commit 006a1d60c8
3 changed files with 65 additions and 62 deletions

View file

@ -18,9 +18,7 @@
class EntityNodeData : public OctreeQueryNode { class EntityNodeData : public OctreeQueryNode {
public: public:
EntityNodeData() : EntityNodeData() : OctreeQueryNode() { }
OctreeQueryNode(),
_lastDeletedEntitiesSentAt(0) { }
virtual PacketType getMyPacketType() const { return PacketType::EntityData; } virtual PacketType getMyPacketType() const { return PacketType::EntityData; }
@ -28,7 +26,7 @@ public:
void setLastDeletedEntitiesSentAt(quint64 sentAt) { _lastDeletedEntitiesSentAt = sentAt; } void setLastDeletedEntitiesSentAt(quint64 sentAt) { _lastDeletedEntitiesSentAt = sentAt; }
private: private:
quint64 _lastDeletedEntitiesSentAt; quint64 _lastDeletedEntitiesSentAt { usecTimestampNow() };
}; };
#endif // hifi_EntityNodeData_h #endif // hifi_EntityNodeData_h

View file

@ -82,7 +82,6 @@ bool EntityServer::hasSpecialPacketsToSend(const SharedNodePointer& node) {
EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData()); EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
if (nodeData) { if (nodeData) {
quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt(); quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree); EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
shouldSendDeletedEntities = tree->hasEntitiesDeletedSince(deletedEntitiesSentAt); shouldSendDeletedEntities = tree->hasEntitiesDeletedSince(deletedEntitiesSentAt);
} }
@ -97,7 +96,6 @@ int EntityServer::sendSpecialPackets(const SharedNodePointer& node, OctreeQueryN
if (nodeData) { if (nodeData) {
quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt(); quint64 deletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
quint64 deletePacketSentAt = usecTimestampNow(); quint64 deletePacketSentAt = usecTimestampNow();
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree); EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
bool hasMoreToSend = true; bool hasMoreToSend = true;
@ -127,7 +125,6 @@ void EntityServer::pruneDeletedEntities() {
if (tree->hasAnyDeletedEntities()) { if (tree->hasAnyDeletedEntities()) {
quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future
DependencyManager::get<NodeList>()->eachNode([&earliestLastDeletedEntitiesSent](const SharedNodePointer& node) { DependencyManager::get<NodeList>()->eachNode([&earliestLastDeletedEntitiesSent](const SharedNodePointer& node) {
if (node->getLinkedData()) { if (node->getLinkedData()) {
EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData()); EntityNodeData* nodeData = static_cast<EntityNodeData*>(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); tree->forgetEntitiesDeletedBefore(earliestLastDeletedEntitiesSent);
} }
} }

View file

@ -384,16 +384,17 @@ void EntityTree::deleteEntities(QSet<EntityItemID> entityIDs, bool force, bool i
} }
void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) { void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) {
quint64 deletedAt = usecTimestampNow();
const RemovedEntities& entities = theOperator.getEntities(); const RemovedEntities& entities = theOperator.getEntities();
foreach(const EntityToDeleteDetails& details, entities) { foreach(const EntityToDeleteDetails& details, entities) {
EntityItemPointer theEntity = details.entity; EntityItemPointer theEntity = details.entity;
if (getIsServer()) { if (getIsServer()) {
// set up the deleted entities ID // set up the deleted entities ID
quint64 deletedAt = usecTimestampNow(); {
_recentlyDeletedEntitiesLock.lockForWrite(); QWriteLocker locker(&_recentlyDeletedEntitiesLock);
_recentlyDeletedEntityItemIDs.insert(deletedAt, theEntity->getEntityItemID()); _recentlyDeletedEntityItemIDs.insert(deletedAt, theEntity->getEntityItemID());
_recentlyDeletedEntitiesLock.unlock(); }
} }
if (_simulation) { if (_simulation) {
@ -802,18 +803,23 @@ void EntityTree::update() {
} }
bool EntityTree::hasEntitiesDeletedSince(quint64 sinceTime) { 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... // we can probably leverage the ordered nature of QMultiMap to do this quickly...
bool hasSomethingNewer = false; bool hasSomethingNewer = false;
{
QReadLocker locker(&_recentlyDeletedEntitiesLock);
_recentlyDeletedEntitiesLock.lockForRead(); QMultiMap<quint64, QUuid>::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin();
QMultiMap<quint64, QUuid>::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin(); while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) {
while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) { if (iterator.key() > considerEntitiesSince) {
if (iterator.key() > sinceTime) { hasSomethingNewer = true;
hasSomethingNewer = true; }
++iterator;
} }
++iterator;
} }
_recentlyDeletedEntitiesLock.unlock();
return hasSomethingNewer; return hasSomethingNewer;
} }
@ -821,6 +827,8 @@ bool EntityTree::hasEntitiesDeletedSince(quint64 sinceTime) {
std::unique_ptr<NLPacket> EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime, std::unique_ptr<NLPacket> EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime,
bool& hasMore) { bool& hasMore) {
int EXTRA_SECONDS_TO_CONSIDER = 4;
quint64 considerEntitiesSince = sinceTime - (USECS_PER_SECOND * EXTRA_SECONDS_TO_CONSIDER);
auto deletesPacket = NLPacket::create(PacketType::EntityErase); auto deletesPacket = NLPacket::create(PacketType::EntityErase);
// pack in flags // pack in flags
@ -841,48 +849,46 @@ std::unique_ptr<NLPacket> 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 // 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 // deleted since we last sent to this node
_recentlyDeletedEntitiesLock.lockForRead(); {
QReadLocker locker(&_recentlyDeletedEntitiesLock);
bool hasFilledPacket = false; bool hasFilledPacket = false;
auto it = _recentlyDeletedEntityItemIDs.constBegin(); auto it = _recentlyDeletedEntityItemIDs.constBegin();
while (it != _recentlyDeletedEntityItemIDs.constEnd()) { while (it != _recentlyDeletedEntityItemIDs.constEnd()) {
QList<QUuid> values = _recentlyDeletedEntityItemIDs.values(it.key()); QList<QUuid> values = _recentlyDeletedEntityItemIDs.values(it.key());
for (int valueItem = 0; valueItem < values.size(); ++valueItem) { for (int valueItem = 0; valueItem < values.size(); ++valueItem) {
// if the timestamp is more recent then out last sent time, include it // if the timestamp is more recent then out last sent time, include it
if (it.key() > sinceTime) { if (it.key() > considerEntitiesSince) {
QUuid entityID = values.at(valueItem); QUuid entityID = values.at(valueItem);
deletesPacket->write(entityID.toRfc4122()); deletesPacket->write(entityID.toRfc4122());
++numberOfIDs;
++numberOfIDs; // check to make sure we have room for one more ID
if (NUM_BYTES_RFC4122_UUID > deletesPacket->bytesAvailableForWrite()) {
// check to make sure we have room for one more ID hasFilledPacket = true;
if (NUM_BYTES_RFC4122_UUID > deletesPacket->bytesAvailableForWrite()) { break;
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 we got to the end, then we're done sending
if (hasFilledPacket) { if (it == _recentlyDeletedEntityItemIDs.constEnd()) {
// let our caller know how far we got hasMore = false;
sinceTime = it.key();
break;
} }
++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 // replace the count for the number of included IDs
deletesPacket->seek(numberOfIDsPos); deletesPacket->seek(numberOfIDsPos);
deletesPacket->writePrimitive(numberOfIDs); deletesPacket->writePrimitive(numberOfIDs);
@ -895,23 +901,23 @@ std::unique_ptr<NLPacket> EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_S
void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) { void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
QSet<quint64> keysToRemove; QSet<quint64> keysToRemove;
_recentlyDeletedEntitiesLock.lockForWrite(); {
QMultiMap<quint64, QUuid>::iterator iterator = _recentlyDeletedEntityItemIDs.begin(); QWriteLocker locker(&_recentlyDeletedEntitiesLock);
QMultiMap<quint64, QUuid>::iterator iterator = _recentlyDeletedEntityItemIDs.begin();
// First find all the keys in the map that are older and need to be deleted // First find all the keys in the map that are older and need to be deleted
while (iterator != _recentlyDeletedEntityItemIDs.end()) { while (iterator != _recentlyDeletedEntityItemIDs.end()) {
if (iterator.key() <= sinceTime) { if (iterator.key() <= sinceTime) {
keysToRemove << iterator.key(); keysToRemove << iterator.key();
}
++iterator;
} }
++iterator;
}
// Now run through the keysToRemove and remove them // Now run through the keysToRemove and remove them
foreach (quint64 value, keysToRemove) { foreach (quint64 value, keysToRemove) {
_recentlyDeletedEntityItemIDs.remove(value); _recentlyDeletedEntityItemIDs.remove(value);
}
} }
_recentlyDeletedEntitiesLock.unlock();
} }