From 57747599af36138ccf37bd46efb0080cdf4ec90d Mon Sep 17 00:00:00 2001 From: dgelessus Date: Sun, 13 Aug 2023 16:45:11 +0200 Subject: [PATCH 01/10] Remove a few unused statics from plVaultClientApi.cpp --- .../PubUtilLib/plVault/plVaultClientApi.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index 3b3446f6ed..dcc0b3f190 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -279,8 +279,6 @@ struct AddChildNodeFetchTrans { * ***/ -static bool s_running; - static HASHTABLEDECL( RelVaultNodeLink, THashKeyVal, @@ -300,8 +298,6 @@ static HASHTABLEDECL( static std::unordered_map s_ageDeviceInboxes; -static bool s_processPlayerInbox = false; - static std::atomic s_suppressCallbacks; /***************************************************************************** @@ -665,11 +661,8 @@ static void VaultNodeAdded ( ); } - if (parentId == inboxId) { - if (i > 0) - s_processPlayerInbox = true; - else - VaultProcessPlayerInbox(); + if (parentId == inboxId && i == 0) { + VaultProcessPlayerInbox(); } // if the added element is already downloaded then send the callbacks now @@ -1529,8 +1522,6 @@ void VaultEnableCallbacks() { //============================================================================ void VaultInitialize () { - s_running = true; - NetCliAuthVaultSetRecvNodeChangedHandler(VaultNodeChanged); NetCliAuthVaultSetRecvNodeAddedHandler(VaultNodeAdded); NetCliAuthVaultSetRecvNodeRemovedHandler(VaultNodeRemoved); @@ -1539,8 +1530,6 @@ void VaultInitialize () { //============================================================================ void VaultDestroy () { - s_running = false; - NetCliAuthVaultSetRecvNodeChangedHandler(nullptr); NetCliAuthVaultSetRecvNodeAddedHandler(nullptr); NetCliAuthVaultSetRecvNodeRemovedHandler(nullptr); From 1c87fbdb282e643651c0c06f7603a2f93a023264 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Sun, 13 Aug 2023 16:53:25 +0200 Subject: [PATCH 02/10] Convert s_notifyAfterDownload from pnUtHash to std::unordered_map --- .../PubUtilLib/plVault/plVaultClientApi.cpp | 33 +++++-------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index dcc0b3f190..63321b9431 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -60,18 +60,6 @@ struct IVaultCallback { VaultCallback * cb; }; -struct INotifyAfterDownload : THashKeyVal { - HASHLINK(INotifyAfterDownload) link; - unsigned parentId; - unsigned childId; - - INotifyAfterDownload (unsigned parentId, unsigned childId) - : THashKeyVal(childId) - , parentId(parentId) - , childId(childId) - {} -}; - // A RelVaultNodeLink may be either stored in the global table, // or stored in an IRelVaultNode's parents or children table. struct RelVaultNodeLink : THashKeyVal { @@ -290,11 +278,8 @@ static LISTDECL( link ) s_callbacks; -static HASHTABLEDECL( - INotifyAfterDownload, - THashKeyVal, - link -) s_notifyAfterDownload; +// key: childId, value: parentId +std::unordered_map s_notifyAfterDownload; static std::unordered_map s_ageDeviceInboxes; @@ -325,12 +310,13 @@ static void VaultNodeFound ( static void VaultNodeAddedDownloadCallback(ENetError result, void * param) { unsigned childId = (unsigned)((uintptr_t)param); - INotifyAfterDownload* notify = s_notifyAfterDownload.Find(childId); + auto it = s_notifyAfterDownload.find(childId); - if (notify) { + if (it != s_notifyAfterDownload.end()) { + unsigned parentId = it->second; if (IS_NET_SUCCESS(result)) { - RelVaultNodeLink* parentLink = s_nodes.Find(notify->parentId); - RelVaultNodeLink* childLink = s_nodes.Find(notify->childId); + RelVaultNodeLink* parentLink = s_nodes.Find(parentId); + RelVaultNodeLink* childLink = s_nodes.Find(childId); if (parentLink && childLink) { if (childLink->node->GetNodeType() == plVault::kNodeType_TextNote) { @@ -347,8 +333,6 @@ static void VaultNodeAddedDownloadCallback(ENetError result, void * param) { } } } - - delete notify; } } @@ -412,8 +396,7 @@ static void BuildNodeTree ( } } else { - INotifyAfterDownload* notify = new INotifyAfterDownload(parentNode->GetNodeId(), childNode->GetNodeId()); - s_notifyAfterDownload.Add(notify); + s_notifyAfterDownload.emplace(childNode->GetNodeId(), parentNode->GetNodeId()); } } } From 429842cf2afbc0145f975e7450031e1036c3c961 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Mon, 14 Aug 2023 03:04:02 +0200 Subject: [PATCH 03/10] Convert RelVaultNodeLink hash maps from pnUtHash to std::unordered_map --- .../PubUtilLib/plVault/plVaultClientApi.cpp | 344 ++++++++++-------- 1 file changed, 188 insertions(+), 156 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index 63321b9431..a10021174a 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -62,18 +62,17 @@ struct IVaultCallback { // A RelVaultNodeLink may be either stored in the global table, // or stored in an IRelVaultNode's parents or children table. -struct RelVaultNodeLink : THashKeyVal { - HASHLINK(RelVaultNodeLink) link; +struct RelVaultNodeLink { hsRef node; unsigned ownerId; bool seen; - RelVaultNodeLink(bool seen, unsigned ownerId, unsigned nodeId) - : THashKeyVal(nodeId), node(new RelVaultNode, hsStealRef), ownerId(ownerId), seen(seen) + RelVaultNodeLink(bool seen, unsigned ownerId) + : node(new RelVaultNode, hsStealRef), ownerId(ownerId), seen(seen) { } - RelVaultNodeLink (bool seen, unsigned ownerId, unsigned nodeId, hsRef node) - : THashKeyVal(nodeId), node(std::move(node)), ownerId(ownerId), seen(seen) + RelVaultNodeLink(bool seen, unsigned ownerId, hsRef node) + : node(std::move(node)), ownerId(ownerId), seen(seen) { } }; @@ -81,17 +80,8 @@ struct RelVaultNodeLink : THashKeyVal { struct IRelVaultNode { hsWeakRef node; - HASHTABLEDECL( - RelVaultNodeLink, - THashKeyVal, - link - ) parents; - - HASHTABLEDECL( - RelVaultNodeLink, - THashKeyVal, - link - ) children; + std::unordered_map parents; + std::unordered_map children; IRelVaultNode(hsWeakRef node); ~IRelVaultNode (); @@ -267,11 +257,7 @@ struct AddChildNodeFetchTrans { * ***/ -static HASHTABLEDECL( - RelVaultNodeLink, - THashKeyVal, - link -) s_nodes; +std::unordered_map s_nodes; static LISTDECL( IVaultCallback, @@ -315,10 +301,12 @@ static void VaultNodeAddedDownloadCallback(ENetError result, void * param) { if (it != s_notifyAfterDownload.end()) { unsigned parentId = it->second; if (IS_NET_SUCCESS(result)) { - RelVaultNodeLink* parentLink = s_nodes.Find(parentId); - RelVaultNodeLink* childLink = s_nodes.Find(childId); + auto parentIt = s_nodes.find(parentId); + auto childIt = s_nodes.find(childId); - if (parentLink && childLink) { + if (parentIt != s_nodes.end() && childIt != s_nodes.end()) { + RelVaultNodeLink* parentLink = parentIt->second; + RelVaultNodeLink* childLink = childIt->second; if (childLink->node->GetNodeType() == plVault::kNodeType_TextNote) { VaultTextNoteNode textNote(childLink->node); if (textNote.GetNoteType() == plVault::kNoteType_Visit) @@ -347,24 +335,27 @@ static void BuildNodeTree ( ) { for (unsigned i = 0; i < refCount; ++i) { // Find/Create global links - RelVaultNodeLink * parentLink = s_nodes.Find(refs[i].parentId); - if (!parentLink) { + auto parentIt = s_nodes.find(refs[i].parentId); + RelVaultNodeLink* parentLink; + if (parentIt == s_nodes.end()) { newNodeIds->emplace_back(refs[i].parentId); - parentLink = new RelVaultNodeLink(false, 0, refs[i].parentId); + parentLink = new RelVaultNodeLink(false, 0); parentLink->node->SetNodeId_NoDirty(refs[i].parentId); - s_nodes.Add(parentLink); - } - else { + s_nodes.emplace(refs[i].parentId, parentLink); + } else { + parentLink = parentIt->second; existingNodeIds->emplace_back(refs[i].parentId); } - RelVaultNodeLink * childLink = s_nodes.Find(refs[i].childId); - if (!childLink) { + + auto childIt = s_nodes.find(refs[i].childId); + RelVaultNodeLink* childLink; + if (childIt == s_nodes.end()) { newNodeIds->emplace_back(refs[i].childId); - childLink = new RelVaultNodeLink(refs[i].seen, refs[i].ownerId, refs[i].childId); + childLink = new RelVaultNodeLink(refs[i].seen, refs[i].ownerId); childLink->node->SetNodeId_NoDirty(refs[i].childId); - s_nodes.Add(childLink); - } - else { + s_nodes.emplace(refs[i].childId, childLink); + } else { + childLink = childIt->second; existingNodeIds->emplace_back(refs[i].childId); if (unsigned ownerId = refs[i].ownerId) childLink->ownerId = ownerId; @@ -378,15 +369,15 @@ static void BuildNodeTree ( if (!isImmediateParent) { // Add parent to child's parents table - parentLink = new RelVaultNodeLink(false, 0, parentNode->GetNodeId(), parentNode); - childNode->state->parents.Add(parentLink); + parentLink = new RelVaultNodeLink(false, 0, parentNode); + childNode->state->parents.emplace(parentNode->GetNodeId(), parentLink); LogMsg(kLogDebug, "Added relationship: p:{},c:{}", refs[i].parentId, refs[i].childId); } if (!isImmediateChild) { // Add child to parent's children table - childLink = new RelVaultNodeLink(refs[i].seen, refs[i].ownerId, childNode->GetNodeId(), childNode); - parentNode->state->children.Add(childLink); + childLink = new RelVaultNodeLink(refs[i].seen, refs[i].ownerId, childNode); + parentNode->state->children.emplace(childNode->GetNodeId(), childLink); if (notifyNow || childNode->GetNodeType() != 0) { // We made a new link, so make the callbacks @@ -474,7 +465,7 @@ static void FetchNodesFromRefs ( // Fetch the nodes that do not yet have a nodetype unsigned prevId = 0; for (unsigned nodeId : nodeIds) { - RelVaultNodeLink * link = s_nodes.Find(nodeId); + RelVaultNodeLink* link = s_nodes.at(nodeId); if (link->node->GetNodeType() != 0) continue; // filter duplicates @@ -506,8 +497,9 @@ static void VaultNodeFound ( for (unsigned i = 0; i < nodeIdCount; ++i) { // See if we already have this node - if (RelVaultNodeLink * link = s_nodes.Find(nodeIds[i])) + if (s_nodes.find(nodeIds[i]) != s_nodes.end()) { return; + } // Start fetching the node NetCliAuthVaultNodeFetch(nodeIds[i], VaultNodeFetched, nullptr); @@ -526,11 +518,14 @@ static void VaultNodeFetched ( } // Add to global node table - RelVaultNodeLink * link = s_nodes.Find(node->GetNodeId()); - if (!link) { - link = new RelVaultNodeLink(false, 0, node->GetNodeId()); + auto it = s_nodes.find(node->GetNodeId()); + RelVaultNodeLink* link; + if (it == s_nodes.end()) { + link = new RelVaultNodeLink(false, 0); link->node->SetNodeId_NoDirty(node->GetNodeId()); - s_nodes.Add(link); + s_nodes.emplace(node->GetNodeId(), link); + } else { + link = it->second; } link->node->CopyFrom(node); InitFetchedNode(link->node); @@ -551,13 +546,14 @@ static void ChangedVaultNodeFetched ( VaultNodeFetched(result, param, node); - RelVaultNodeLink* savedLink = s_nodes.Find(node->GetNodeId()); + auto it = s_nodes.find(node->GetNodeId()); // Yeah, we are purposefully allowing this global callback to go out, // even if callback suppression has been enabled. The intent behind // that is to suppress spurious callbacks, but node changes are // probably not spurious. - if (savedLink) { + if (it != s_nodes.end()) { + RelVaultNodeLink* savedLink = it->second; for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) cb->cb->ChangedNode(savedLink->node); } @@ -570,14 +566,15 @@ static void VaultNodeChanged ( ) { LogMsg(kLogDebug, "Notify: Node changed: {}", nodeId); - RelVaultNodeLink * link = s_nodes.Find(nodeId); + auto it = s_nodes.find(nodeId); // We don't have the node, so we don't care that it changed (we actually // shouldn't have been notified) - if (!link) { + if (it == s_nodes.end()) { LogMsg(kLogDebug, "rcvd change notification for node {}, but node doesn't exist locally.", nodeId); return; } + RelVaultNodeLink* link = it->second; if (link->node->GetRevision() == revisionId) { // We are the party responsible for the change, so we already have the @@ -627,7 +624,7 @@ static void VaultNodeAdded ( unsigned prevId = 0; unsigned i = 0; for (; i < nodeIds.size(); ++i) { - RelVaultNodeLink * link = s_nodes.Find(nodeIds[i]); + RelVaultNodeLink* link = s_nodes.at(nodeIds[i]); if (link->node->GetNodeType() != 0) continue; // filter duplicates @@ -649,8 +646,8 @@ static void VaultNodeAdded ( } // if the added element is already downloaded then send the callbacks now - RelVaultNodeLink* parentLink = s_nodes.Find(parentId); - RelVaultNodeLink* childLink = s_nodes.Find(childId); + RelVaultNodeLink* parentLink = s_nodes.at(parentId); + RelVaultNodeLink* childLink = s_nodes.at(childId); if (childLink->node->GetNodeType() != 0 && s_suppressCallbacks == 0) { for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) @@ -666,14 +663,18 @@ static void VaultNodeRemoved ( LogMsg(kLogDebug, "Notify: Node removed: p:{},c:{}", parentId, childId); for (;;) { // Unlink 'em locally, if we can - RelVaultNodeLink * parentLink = s_nodes.Find(parentId); - if (!parentLink) + auto parentIt = s_nodes.find(parentId); + if (parentIt == s_nodes.end()) { break; + } - RelVaultNodeLink * childLink = s_nodes.Find(childId); - if (!childLink) + auto childIt = s_nodes.find(childId); + if (childIt == s_nodes.end()) { break; - + } + + RelVaultNodeLink* parentLink = parentIt->second; + RelVaultNodeLink* childLink = childIt->second; if (parentLink->node->IsParentOf(childId, 1) && s_suppressCallbacks == 0) { // We have the relationship, so make the callbacks for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) @@ -704,7 +705,7 @@ static void SaveDirtyNodes () { if (!s_nextSaveMs || signed(s_nextSaveMs - currTimeMs) <= 0) { s_nextSaveMs = (currTimeMs + kSaveUpdateIntervalMs) | 1; unsigned bytesWritten = 0; - for (RelVaultNodeLink * link = s_nodes.Head(); link; link = s_nodes.Next(link)) { + for (const auto& [nodeId, link] : s_nodes) { if (bytesWritten >= kMaxBytesPerSaveUpdate) break; if (link->node->IsDirty()) { @@ -778,10 +779,11 @@ void VaultCreateNodeTrans::VaultNodeFetched ( VaultCreateNodeTrans * trans = (VaultCreateNodeTrans *)param; - if (IS_NET_SUCCESS(result)) - trans->node = s_nodes.Find(node->GetNodeId())->node; - else + if (IS_NET_SUCCESS(result)) { + trans->node = s_nodes.at(node->GetNodeId())->node; + } else { trans->node = nullptr; + } trans->Complete(result); } @@ -897,8 +899,8 @@ void VaultDownloadTrans::VaultNodeRefsFetched ( } else { // root node has no child heirarchy? Make sure we still d/l the root node if necessary. - RelVaultNodeLink* rootNodeLink = s_nodes.Find(trans->vaultId); - if (!rootNodeLink || rootNodeLink->node->GetNodeType() == 0) { + auto rootNodeIt = s_nodes.find(trans->vaultId); + if (rootNodeIt == s_nodes.end() || rootNodeIt->second->node->GetNodeType() == 0) { NetCliAuthVaultNodeFetch( trans->vaultId, VaultDownloadTrans::VaultNodeFetched, @@ -1028,16 +1030,16 @@ IRelVaultNode::IRelVaultNode(hsWeakRef node) //============================================================================ IRelVaultNode::~IRelVaultNode () { - ASSERT(!parents.Head()); - ASSERT(!children.Head()); + ASSERT(parents.empty()); + ASSERT(children.empty()); } //============================================================================ void IRelVaultNode::UnlinkFromRelatives () { - - RelVaultNodeLink * link, * next; - for (link = parents.Head(); link; link = next) { - next = parents.Next(link); + for (auto it = parents.begin(); it != parents.end();) { + // Advance the iterator before calling Unlink so that it doesn't get invalidated + RelVaultNodeLink* link = it->second; + ++it; // We have the relationship, so make the callbacks if (s_suppressCallbacks == 0) { @@ -1047,31 +1049,39 @@ void IRelVaultNode::UnlinkFromRelatives () { link->node->state->Unlink(node); } - for (link = children.Head(); link; link = next) { - next = children.Next(link); + for (auto it = children.begin(); it != children.end();) { + // Advance the iterator before calling Unlink so that it doesn't get invalidated + RelVaultNodeLink* link = it->second; + ++it; link->node->state->Unlink(node); } - - ASSERT(!parents.Head()); - ASSERT(!children.Head()); + + ASSERT(parents.empty()); + ASSERT(children.empty()); } //============================================================================ void IRelVaultNode::Unlink(hsWeakRef other) { ASSERT(other != node); - - RelVaultNodeLink * link; - if (link = parents.Find(other->GetNodeId()); link != nullptr) { + + auto parentIt = parents.find(other->GetNodeId()); + if (parentIt != parents.end()) { + // Copy the link pointer - the erase call will invalidate the iterator! + RelVaultNodeLink* link = parentIt->second; // make them non-findable in our parents table - link->link.Unlink(); + parents.erase(parentIt); // remove us from other's tables. link->node->state->Unlink(node); delete link; } - if (link = children.Find(other->GetNodeId()); link != nullptr) { + + auto childIt = children.find(other->GetNodeId()); + if (childIt != children.end()) { + // Copy the link pointer - the erase call will invalidate the iterator! + RelVaultNodeLink* link = childIt->second; // make them non-findable in our children table - link->link.Unlink(); + children.erase(childIt); // remove us from other's tables. link->node->state->Unlink(node); delete link; @@ -1100,10 +1110,9 @@ bool RelVaultNode::IsParentOf (unsigned childId, unsigned maxDepth) { return false; if (maxDepth == 0) return false; - if (state->children.Find(childId)) + if (state->children.find(childId) != state->children.end()) return true; - RelVaultNodeLink * link = state->children.Head(); - for (; link; link = state->children.Next(link)) + for (const auto& [nodeId, link] : state->children) if (link->node->IsParentOf(childId, maxDepth - 1)) return true; return false; @@ -1115,10 +1124,9 @@ bool RelVaultNode::IsChildOf (unsigned parentId, unsigned maxDepth) { return false; if (maxDepth == 0) return false; - if (state->parents.Find(parentId)) + if (state->parents.find(parentId) != state->parents.end()) return true; - RelVaultNodeLink * link = state->parents.Head(); - for (; link; link = state->parents.Next(link)) + for (const auto& [nodeId, link] : state->parents) if (link->node->IsChildOf(parentId, maxDepth - 1)) return true; return false; @@ -1126,13 +1134,12 @@ bool RelVaultNode::IsChildOf (unsigned parentId, unsigned maxDepth) { //============================================================================ void RelVaultNode::GetRootIds (std::vector * nodeIds) { - RelVaultNodeLink * link = state->parents.Head(); - if (!link) { + if (state->parents.empty()) { nodeIds->emplace_back(GetNodeId()); - } - else { - for (; link; link = state->parents.Next(link)) + } else { + for (const auto& [nodeId, link] : state->parents) { link->node->GetRootIds(nodeIds); + } } } @@ -1149,8 +1156,7 @@ void RelVaultNode::GetChildNodeIds ( ) { if (!maxDepth) return; - RelVaultNodeLink * link = state->children.Head(); - for (; link; link = state->children.Next(link)) { + for (const auto& [nodeId, link] : state->children) { nodeIds->emplace_back(link->node->GetNodeId()); link->node->GetChildNodeIds(nodeIds, maxDepth-1); } @@ -1163,8 +1169,7 @@ void RelVaultNode::GetParentNodeIds ( ) { if (!maxDepth) return; - RelVaultNodeLink * link = state->parents.Head(); - for (; link; link = state->parents.Next(link)) { + for (const auto& [nodeId, link] : state->parents) { nodeIds->emplace_back(link->node->GetNodeId()); link->node->GetParentNodeIds(nodeIds, maxDepth-1); } @@ -1179,15 +1184,12 @@ hsRef RelVaultNode::GetParentNode ( if (maxDepth == 0) return nullptr; - RelVaultNodeLink * link; - link = state->parents.Head(); - for (; link; link = state->parents.Next(link)) { + for (const auto& [nodeId, link] : state->parents) { if (link->node->Matches(templateNode.Get())) return link->node; } - - link = state->parents.Head(); - for (; link; link = state->parents.Next(link)) { + + for (const auto& [nodeId, link] : state->parents) { if (hsRef node = link->node->GetParentNode(templateNode, maxDepth - 1)) return node; } @@ -1203,15 +1205,12 @@ hsRef RelVaultNode::GetChildNode ( if (maxDepth == 0) return nullptr; - RelVaultNodeLink * link; - link = state->children.Head(); - for (; link; link = state->children.Next(link)) { + for (const auto& [nodeId, link] : state->children) { if (link->node->Matches(templateNode.Get())) return link->node; } - - link = state->children.Head(); - for (; link; link = state->children.Next(link)) { + + for (const auto& [nodeId, link] : state->children) { if (hsRef node = link->node->GetChildNode(templateNode, maxDepth-1)) return node; } @@ -1273,9 +1272,7 @@ void RelVaultNode::GetChildNodes ( if (maxDepth == 0) return; - RelVaultNodeLink * link; - link = state->children.Head(); - for (; link; link = state->children.Next(link)) { + for (const auto& [nodeId, link] : state->children) { nodes->push_back(link->node); link->node->GetChildNodes( maxDepth - 1, @@ -1290,9 +1287,7 @@ void RelVaultNode::GetChildNodes ( unsigned maxDepth, RelVaultNode::RefList * nodes ) { - RelVaultNodeLink * link; - link = state->children.Head(); - for (; link; link = state->children.Next(link)) { + for (const auto& [nodeId, link] : state->children) { if (link->node->Matches(templateNode.Get())) nodes->push_back(link->node); @@ -1339,30 +1334,48 @@ void RelVaultNode::GetChildFolderNodes ( //============================================================================ unsigned RelVaultNode::GetRefOwnerId (unsigned parentId) { // find our parents' link to us and return its ownerId - if (RelVaultNodeLink * parentLink = state->parents.Find(parentId)) - if (RelVaultNodeLink * childLink = parentLink->node->state->children.Find(GetNodeId())) + auto parentIt = state->parents.find(parentId); + if (parentIt != state->parents.end()) { + RelVaultNodeLink* parentLink = parentIt->second; + auto childIt = parentLink->node->state->children.find(GetNodeId()); + if (childIt != parentLink->node->state->children.end()) { + RelVaultNodeLink* childLink = childIt->second; return childLink->ownerId; + } + } return 0; } //============================================================================ bool RelVaultNode::BeenSeen (unsigned parentId) const { // find our parents' link to us and return its seen flag - if (RelVaultNodeLink * parentLink = state->parents.Find(parentId)) - if (RelVaultNodeLink * childLink = parentLink->node->state->children.Find(GetNodeId())) + auto parentIt = state->parents.find(parentId); + if (parentIt != state->parents.end()) { + RelVaultNodeLink* parentLink = parentIt->second; + auto childIt = parentLink->node->state->children.find(GetNodeId()); + if (childIt != parentLink->node->state->children.end()) { + RelVaultNodeLink* childLink = childIt->second; return childLink->seen; + } + } return true; } //============================================================================ void RelVaultNode::SetSeen (unsigned parentId, bool seen) { // find our parents' link to us and set its seen flag - if (RelVaultNodeLink * parentLink = state->parents.Find(parentId)) - if (RelVaultNodeLink * childLink = parentLink->node->state->children.Find(GetNodeId())) + auto parentIt = state->parents.find(parentId); + if (parentIt != state->parents.end()) { + RelVaultNodeLink* parentLink = parentIt->second; + auto childIt = parentLink->node->state->children.find(GetNodeId()); + if (childIt != parentLink->node->state->children.end()) { + RelVaultNodeLink* childLink = childIt->second; if (childLink->seen != seen) { childLink->seen = seen; NetCliAuthVaultSetSeen(parentId, GetNodeId(), seen); } + } + } } //============================================================================ @@ -1441,8 +1454,9 @@ void RelVaultNode::Print (const ST::string& tag, unsigned level) { //============================================================================ void RelVaultNode::PrintTree (unsigned level) { Print("", level); - for (RelVaultNodeLink * link = state->children.Head(); link; link = state->children.Next(link)) + for (const auto& [nodeId, link] : state->children) { link->node->PrintTree(level + 1); + } } //============================================================================ @@ -1519,11 +1533,11 @@ void VaultDestroy () { NetCliAuthVaultSetRecvNodeDeletedHandler(nullptr); VaultClearDeviceInboxMap(); - - RelVaultNodeLink * next, * link = s_nodes.Head(); - for (; link; link = next) { - next = s_nodes.Next(link); + + for (auto it = s_nodes.begin(); it != s_nodes.end();) { + RelVaultNodeLink* link = it->second; link->node->state->UnlinkFromRelatives(); + it = s_nodes.erase(it); delete link; } } @@ -1545,11 +1559,10 @@ hsRef VaultGetNode ( hsWeakRef templateNode ) { ASSERT(templateNode); - RelVaultNodeLink * link = s_nodes.Head(); - while (link) { - if (link->node->Matches(templateNode.Get())) + for (const auto& [nodeId, link] : s_nodes) { + if (link->node->Matches(templateNode.Get())) { return link->node; - link = s_nodes.Next(link); + } } return nullptr; } @@ -1558,9 +1571,8 @@ hsRef VaultGetNode ( hsRef VaultGetNode ( unsigned nodeId ) { - if (RelVaultNodeLink * link = s_nodes.Find(nodeId)) - return link->node; - return nullptr; + auto it = s_nodes.find(nodeId); + return it == s_nodes.end() ? nullptr : it->second->node; } //============================================================================ @@ -1582,15 +1594,20 @@ void VaultAddChildNode ( // This directly affects: New clothing items added to the avatar outfit folder, // new chronicle entries in some ages, and I'm sure several other situations. - if (RelVaultNodeLink * parentLink = s_nodes.Find(parentId)) { - RelVaultNodeLink * childLink = s_nodes.Find(childId); - if (!childLink) { - childLink = new RelVaultNodeLink(false, ownerId, childId); + auto parentIt = s_nodes.find(parentId); + if (parentIt != s_nodes.end()) { + RelVaultNodeLink* parentLink = parentIt->second; + auto childIt = s_nodes.find(childId); + RelVaultNodeLink* childLink; + if (childIt == s_nodes.end()) { + childLink = new RelVaultNodeLink(false, ownerId); childLink->node->SetNodeId_NoDirty(childId); - s_nodes.Add(childLink); - } - else if (ownerId) { - childLink->ownerId = ownerId; + s_nodes.emplace(childId, childLink); + } else { + childLink = childIt->second; + if (ownerId) { + childLink->ownerId = ownerId; + } } // We can do a sanity check for a would-be circular link, but it isn't @@ -1739,14 +1756,18 @@ void VaultRemoveChildNode ( ) { for (;;) { // Unlink 'em locally, if we can - RelVaultNodeLink * parentLink = s_nodes.Find(parentId); - if (!parentLink) + auto parentIt = s_nodes.find(parentId); + if (parentIt == s_nodes.end()) { break; + } - RelVaultNodeLink * childLink = s_nodes.Find(childId); - if (!childLink) + auto childIt = s_nodes.find(childId); + if (childIt == s_nodes.end()) { break; - + } + + RelVaultNodeLink* parentLink = parentIt->second; + RelVaultNodeLink* childLink = childIt->second; if (parentLink->node->IsParentOf(childId, 1)) { // We have the relationship, so make the callbacks if (s_suppressCallbacks == 0) { @@ -2022,7 +2043,7 @@ void VaultLocalFindNodes ( hsWeakRef templateNode, std::vector * nodeIds ) { - for (RelVaultNodeLink * link = s_nodes.Head(); link != nullptr; link = s_nodes.Next(link)) { + for (const auto& [nodeId, link] : s_nodes) { if (link->node->Matches(templateNode.Get())) nodeIds->emplace_back(link->node->GetNodeId()); } @@ -2056,7 +2077,7 @@ void VaultFetchNodesAndWait ( if (!force) { // See if we already have this node - if (RelVaultNodeLink * link = s_nodes.Find(nodeIds[i])) { + if (s_nodes.find(nodeIds[i]) != s_nodes.end()) { --nodeCount; continue; } @@ -4669,33 +4690,44 @@ void VaultCull (unsigned vaultId) { VaultCallbackSuppressor suppress; // Remove the node from the global table - if (RelVaultNodeLink * link = s_nodes.Find(vaultId)) { + auto nodeIt = s_nodes.find(vaultId); + if (nodeIt != s_nodes.end()) { + RelVaultNodeLink* link = nodeIt->second; LogMsg(kLogDebug, "Vault: Culling node {}", link->node->GetNodeId()); link->node->state->UnlinkFromRelatives(); + s_nodes.erase(nodeIt); delete link; } // Remove all orphaned nodes from the global table - for (RelVaultNodeLink * next, * link = s_nodes.Head(); link; link = next) { - next = s_nodes.Next(link); + for (auto it = s_nodes.begin(); it != s_nodes.end();) { + RelVaultNodeLink* link = it->second; - if (link->node->GetNodeType() > plVault::kNodeType_VNodeMgrLow && link->node->GetNodeType() < plVault::kNodeType_VNodeMgrHigh) + if (link->node->GetNodeType() > plVault::kNodeType_VNodeMgrLow && link->node->GetNodeType() < plVault::kNodeType_VNodeMgrHigh) { + ++it; continue; + } std::vector nodeIds; link->node->GetRootIds(&nodeIds); bool foundRoot = false; for (unsigned nodeId : nodeIds) { - RelVaultNodeLink * root = s_nodes.Find(nodeId); - if (root && root->node->GetNodeType() > plVault::kNodeType_VNodeMgrLow && root->node->GetNodeType() < plVault::kNodeType_VNodeMgrHigh) { - foundRoot = true; - break; + auto rootIt = s_nodes.find(nodeId); + if (rootIt != s_nodes.end()) { + RelVaultNodeLink* root = rootIt->second; + if (root->node->GetNodeType() > plVault::kNodeType_VNodeMgrLow && root->node->GetNodeType() < plVault::kNodeType_VNodeMgrHigh) { + foundRoot = true; + break; + } } } if (!foundRoot) { LogMsg(kLogDebug, "Vault: Culling node {}", link->node->GetNodeId()); link->node->state->UnlinkFromRelatives(); + it = s_nodes.erase(it); delete link; + } else { + ++it; } } } From a9a64e8db9d8efbf5ebe2004dccb18f410eec51a Mon Sep 17 00:00:00 2001 From: dgelessus Date: Mon, 14 Aug 2023 03:33:37 +0200 Subject: [PATCH 04/10] Convert s_callbacks pnUtList to std::list --- .../Plasma/PubUtilLib/plVault/CMakeLists.txt | 1 - Sources/Plasma/PubUtilLib/plVault/Pch.h | 1 - .../PubUtilLib/plVault/plVaultClientApi.cpp | 61 +++++++++---------- .../PubUtilLib/plVault/plVaultClientApi.h | 2 - 4 files changed, 29 insertions(+), 36 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plVault/CMakeLists.txt b/Sources/Plasma/PubUtilLib/plVault/CMakeLists.txt index e24eeefa8a..a2fdddb6c4 100644 --- a/Sources/Plasma/PubUtilLib/plVault/CMakeLists.txt +++ b/Sources/Plasma/PubUtilLib/plVault/CMakeLists.txt @@ -31,7 +31,6 @@ target_link_libraries( pnAsyncCore pnDispatch pnNucleusInc - pnUtils plGImage plMessage plNetCommon diff --git a/Sources/Plasma/PubUtilLib/plVault/Pch.h b/Sources/Plasma/PubUtilLib/plVault/Pch.h index 7ef02ffad5..05f271e931 100644 --- a/Sources/Plasma/PubUtilLib/plVault/Pch.h +++ b/Sources/Plasma/PubUtilLib/plVault/Pch.h @@ -50,7 +50,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pnAsyncCore/pnAsyncCore.h" #include "pnNetProtocol/pnNetProtocol.h" -#include "pnUtils/pnUtils.h" #include "plVault.h" #include "plDniCoordinateInfo.h" diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index a10021174a..b34b5990dd 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -55,11 +55,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com * ***/ -struct IVaultCallback { - LINK(IVaultCallback) link; - VaultCallback * cb; -}; - // A RelVaultNodeLink may be either stored in the global table, // or stored in an IRelVaultNode's parents or children table. struct RelVaultNodeLink { @@ -259,10 +254,7 @@ struct AddChildNodeFetchTrans { std::unordered_map s_nodes; -static LISTDECL( - IVaultCallback, - link -) s_callbacks; +std::list s_callbacks; // key: childId, value: parentId std::unordered_map s_notifyAfterDownload; @@ -316,8 +308,9 @@ static void VaultNodeAddedDownloadCallback(ENetError result, void * param) { } if (s_suppressCallbacks == 0) { - for (IVaultCallback* cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->AddedChildNode(parentLink->node, childLink->node); + for (auto cb : s_callbacks) { + cb->AddedChildNode(parentLink->node, childLink->node); + } } } } @@ -382,8 +375,9 @@ static void BuildNodeTree ( if (notifyNow || childNode->GetNodeType() != 0) { // We made a new link, so make the callbacks if (s_suppressCallbacks == 0) { - for (IVaultCallback* cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->AddedChildNode(parentNode, childNode); + for (auto cb : s_callbacks) { + cb->AddedChildNode(parentNode, childNode); + } } } else { @@ -554,8 +548,9 @@ static void ChangedVaultNodeFetched ( // probably not spurious. if (it != s_nodes.end()) { RelVaultNodeLink* savedLink = it->second; - for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->ChangedNode(savedLink->node); + for (auto cb : s_callbacks) { + cb->ChangedNode(savedLink->node); + } } } @@ -581,8 +576,9 @@ static void VaultNodeChanged ( // latest version of the node; no need to fetch it. However, we do need to fire off // the "hey this was saved" callback. if (s_suppressCallbacks == 0) { - for (IVaultCallback* cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->ChangedNode(link->node); + for (auto cb : s_callbacks) { + cb->ChangedNode(link->node); + } } } else { // We have the node and we weren't the one that changed it, so fetch it. @@ -650,8 +646,9 @@ static void VaultNodeAdded ( RelVaultNodeLink* childLink = s_nodes.at(childId); if (childLink->node->GetNodeType() != 0 && s_suppressCallbacks == 0) { - for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->AddedChildNode(parentLink->node, childLink->node); + for (auto cb : s_callbacks) { + cb->AddedChildNode(parentLink->node, childLink->node); + } } } @@ -677,8 +674,9 @@ static void VaultNodeRemoved ( RelVaultNodeLink* childLink = childIt->second; if (parentLink->node->IsParentOf(childId, 1) && s_suppressCallbacks == 0) { // We have the relationship, so make the callbacks - for (IVaultCallback * cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->RemovingChildNode(parentLink->node, childLink->node); + for (auto cb : s_callbacks) { + cb->RemovingChildNode(parentLink->node, childLink->node); + } } parentLink->node->state->Unlink(childLink->node); @@ -1043,8 +1041,9 @@ void IRelVaultNode::UnlinkFromRelatives () { // We have the relationship, so make the callbacks if (s_suppressCallbacks == 0) { - for (IVaultCallback* cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->RemovingChildNode(link->node, this->node); + for (auto cb : s_callbacks) { + cb->RemovingChildNode(link->node, this->node); + } } link->node->state->Unlink(node); @@ -1487,17 +1486,14 @@ hsRef RelVaultNode::GetParentAgeLink () { //============================================================================ void VaultRegisterCallback (VaultCallback * cb) { - IVaultCallback * internal = new IVaultCallback; - internal->cb = cb; - cb->internal = internal; - s_callbacks.Link(internal); + s_callbacks.emplace_back(cb); } //============================================================================ void VaultUnregisterCallback (VaultCallback * cb) { - ASSERT(cb->internal); - delete cb->internal; - cb->internal = nullptr; + auto it = std::find(s_callbacks.begin(), s_callbacks.end(), cb); + ASSERT(it != s_callbacks.end()); + s_callbacks.erase(it); } //============================================================================ @@ -1771,8 +1767,9 @@ void VaultRemoveChildNode ( if (parentLink->node->IsParentOf(childId, 1)) { // We have the relationship, so make the callbacks if (s_suppressCallbacks == 0) { - for (IVaultCallback* cb = s_callbacks.Head(); cb; cb = s_callbacks.Next(cb)) - cb->cb->RemovingChildNode(parentLink->node, childLink->node); + for (auto cb : s_callbacks) { + cb->RemovingChildNode(parentLink->node, childLink->node); + } } } diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.h b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.h index 3f069a33f3..90995cee57 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.h +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.h @@ -62,8 +62,6 @@ struct RelVaultNode; class plUUID; struct VaultCallback { - struct IVaultCallback * internal; - virtual ~VaultCallback() { } virtual void AddedChildNode ( From 18f6a2ba8b1ae3e126fbfedebf097cbf8d8cabc1 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Tue, 15 Aug 2023 00:57:45 +0200 Subject: [PATCH 05/10] Change s_nodes to store just a node ref and not a link The owner and seen info was never used here. It's not even clear what they would refer to, because every node appears exactly once in s_nodes, regardless of how many refs it has. --- .../PubUtilLib/plVault/plVaultClientApi.cpp | 212 +++++++++--------- 1 file changed, 102 insertions(+), 110 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index b34b5990dd..b59efd38aa 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -55,8 +55,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com * ***/ -// A RelVaultNodeLink may be either stored in the global table, -// or stored in an IRelVaultNode's parents or children table. +// A RelVaultNodeLink may be stored in an IRelVaultNode's parents or children table. struct RelVaultNodeLink { hsRef node; unsigned ownerId; @@ -252,7 +251,7 @@ struct AddChildNodeFetchTrans { * ***/ -std::unordered_map s_nodes; +std::unordered_map> s_nodes; std::list s_callbacks; @@ -297,19 +296,20 @@ static void VaultNodeAddedDownloadCallback(ENetError result, void * param) { auto childIt = s_nodes.find(childId); if (parentIt != s_nodes.end() && childIt != s_nodes.end()) { - RelVaultNodeLink* parentLink = parentIt->second; - RelVaultNodeLink* childLink = childIt->second; - if (childLink->node->GetNodeType() == plVault::kNodeType_TextNote) { - VaultTextNoteNode textNote(childLink->node); - if (textNote.GetNoteType() == plVault::kNoteType_Visit) - VaultProcessVisitNote(childLink->node); - else if (textNote.GetNoteType() == plVault::kNoteType_UnVisit) - VaultProcessUnvisitNote(childLink->node); + const hsRef& parentNode = parentIt->second; + const hsRef& childNode = childIt->second; + if (childNode->GetNodeType() == plVault::kNodeType_TextNote) { + VaultTextNoteNode textNote(childNode); + if (textNote.GetNoteType() == plVault::kNoteType_Visit) { + VaultProcessVisitNote(childNode); + } else if (textNote.GetNoteType() == plVault::kNoteType_UnVisit) { + VaultProcessUnvisitNote(childNode); + } } if (s_suppressCallbacks == 0) { for (auto cb : s_callbacks) { - cb->AddedChildNode(parentLink->node, childLink->node); + cb->AddedChildNode(parentNode, childNode); } } } @@ -329,47 +329,42 @@ static void BuildNodeTree ( for (unsigned i = 0; i < refCount; ++i) { // Find/Create global links auto parentIt = s_nodes.find(refs[i].parentId); - RelVaultNodeLink* parentLink; + hsRef parentNode; if (parentIt == s_nodes.end()) { newNodeIds->emplace_back(refs[i].parentId); - parentLink = new RelVaultNodeLink(false, 0); - parentLink->node->SetNodeId_NoDirty(refs[i].parentId); - s_nodes.emplace(refs[i].parentId, parentLink); + parentNode.Steal(new RelVaultNode()); + parentNode->SetNodeId_NoDirty(refs[i].parentId); + parentIt = s_nodes.emplace(refs[i].parentId, parentNode).first; } else { - parentLink = parentIt->second; + parentNode = parentIt->second; existingNodeIds->emplace_back(refs[i].parentId); } auto childIt = s_nodes.find(refs[i].childId); - RelVaultNodeLink* childLink; + hsRef childNode; if (childIt == s_nodes.end()) { newNodeIds->emplace_back(refs[i].childId); - childLink = new RelVaultNodeLink(refs[i].seen, refs[i].ownerId); - childLink->node->SetNodeId_NoDirty(refs[i].childId); - s_nodes.emplace(refs[i].childId, childLink); + childNode.Steal(new RelVaultNode()); + childNode->SetNodeId_NoDirty(refs[i].childId); + s_nodes.emplace(refs[i].childId, childNode); } else { - childLink = childIt->second; + childNode = childIt->second; existingNodeIds->emplace_back(refs[i].childId); - if (unsigned ownerId = refs[i].ownerId) - childLink->ownerId = ownerId; } - hsRef parentNode = parentLink->node; - hsRef childNode = childLink->node; - bool isImmediateParent = parentNode->IsParentOf(refs[i].childId, 1); bool isImmediateChild = childNode->IsChildOf(refs[i].parentId, 1); if (!isImmediateParent) { // Add parent to child's parents table - parentLink = new RelVaultNodeLink(false, 0, parentNode); + RelVaultNodeLink* parentLink = new RelVaultNodeLink(false, 0, parentNode); childNode->state->parents.emplace(parentNode->GetNodeId(), parentLink); LogMsg(kLogDebug, "Added relationship: p:{},c:{}", refs[i].parentId, refs[i].childId); } if (!isImmediateChild) { // Add child to parent's children table - childLink = new RelVaultNodeLink(refs[i].seen, refs[i].ownerId, childNode); + RelVaultNodeLink* childLink = new RelVaultNodeLink(refs[i].seen, refs[i].ownerId, childNode); parentNode->state->children.emplace(childNode->GetNodeId(), childLink); if (notifyNow || childNode->GetNodeType() != 0) { @@ -459,13 +454,15 @@ static void FetchNodesFromRefs ( // Fetch the nodes that do not yet have a nodetype unsigned prevId = 0; for (unsigned nodeId : nodeIds) { - RelVaultNodeLink* link = s_nodes.at(nodeId); - if (link->node->GetNodeType() != 0) + const hsRef& node = s_nodes.at(nodeId); + if (node->GetNodeType() != 0) { continue; + } // filter duplicates - if (link->node->GetNodeId() == prevId) + if (node->GetNodeId() == prevId) { continue; - prevId = link->node->GetNodeId(); + } + prevId = node->GetNodeId(); NetCliAuthVaultNodeFetch( nodeId, fetchCallback, @@ -513,18 +510,18 @@ static void VaultNodeFetched ( // Add to global node table auto it = s_nodes.find(node->GetNodeId()); - RelVaultNodeLink* link; + hsRef globalNode; if (it == s_nodes.end()) { - link = new RelVaultNodeLink(false, 0); - link->node->SetNodeId_NoDirty(node->GetNodeId()); - s_nodes.emplace(node->GetNodeId(), link); + globalNode.Steal(new RelVaultNode()); + globalNode->SetNodeId_NoDirty(node->GetNodeId()); + it = s_nodes.emplace(node->GetNodeId(), globalNode).first; } else { - link = it->second; + globalNode = it->second; } - link->node->CopyFrom(node); - InitFetchedNode(link->node); + globalNode->CopyFrom(node); + InitFetchedNode(globalNode); - link->node->Print("Fetched", 0); + globalNode->Print("Fetched", 0); } //============================================================================ @@ -547,9 +544,9 @@ static void ChangedVaultNodeFetched ( // that is to suppress spurious callbacks, but node changes are // probably not spurious. if (it != s_nodes.end()) { - RelVaultNodeLink* savedLink = it->second; + const hsRef& savedNode = it->second; for (auto cb : s_callbacks) { - cb->ChangedNode(savedLink->node); + cb->ChangedNode(savedNode); } } } @@ -569,15 +566,15 @@ static void VaultNodeChanged ( LogMsg(kLogDebug, "rcvd change notification for node {}, but node doesn't exist locally.", nodeId); return; } - RelVaultNodeLink* link = it->second; + const hsRef& node = it->second; - if (link->node->GetRevision() == revisionId) { + if (node->GetRevision() == revisionId) { // We are the party responsible for the change, so we already have the // latest version of the node; no need to fetch it. However, we do need to fire off // the "hey this was saved" callback. if (s_suppressCallbacks == 0) { for (auto cb : s_callbacks) { - cb->ChangedNode(link->node); + cb->ChangedNode(node); } } } else { @@ -620,13 +617,15 @@ static void VaultNodeAdded ( unsigned prevId = 0; unsigned i = 0; for (; i < nodeIds.size(); ++i) { - RelVaultNodeLink* link = s_nodes.at(nodeIds[i]); - if (link->node->GetNodeType() != 0) + const hsRef& node = s_nodes.at(nodeIds[i]); + if (node->GetNodeType() != 0) { continue; + } // filter duplicates - if (link->node->GetNodeId() == prevId) + if (node->GetNodeId() == prevId) { continue; - prevId = link->node->GetNodeId(); + } + prevId = node->GetNodeId(); VaultDownload( "NodeAdded", nodeIds[i], @@ -642,12 +641,12 @@ static void VaultNodeAdded ( } // if the added element is already downloaded then send the callbacks now - RelVaultNodeLink* parentLink = s_nodes.at(parentId); - RelVaultNodeLink* childLink = s_nodes.at(childId); + const hsRef& parentNode = s_nodes.at(parentId); + const hsRef& childNode = s_nodes.at(childId); - if (childLink->node->GetNodeType() != 0 && s_suppressCallbacks == 0) { + if (childNode->GetNodeType() != 0 && s_suppressCallbacks == 0) { for (auto cb : s_callbacks) { - cb->AddedChildNode(parentLink->node, childLink->node); + cb->AddedChildNode(parentNode, childNode); } } } @@ -670,17 +669,17 @@ static void VaultNodeRemoved ( break; } - RelVaultNodeLink* parentLink = parentIt->second; - RelVaultNodeLink* childLink = childIt->second; - if (parentLink->node->IsParentOf(childId, 1) && s_suppressCallbacks == 0) { + const hsRef& parentNode = parentIt->second; + const hsRef& childNode = childIt->second; + if (parentNode->IsParentOf(childId, 1) && s_suppressCallbacks == 0) { // We have the relationship, so make the callbacks for (auto cb : s_callbacks) { - cb->RemovingChildNode(parentLink->node, childLink->node); + cb->RemovingChildNode(parentNode, childNode); } } - - parentLink->node->state->Unlink(childLink->node); - childLink->node->state->Unlink(parentLink->node); + + parentNode->state->Unlink(childNode); + childNode->state->Unlink(parentNode); break; } } @@ -703,13 +702,13 @@ static void SaveDirtyNodes () { if (!s_nextSaveMs || signed(s_nextSaveMs - currTimeMs) <= 0) { s_nextSaveMs = (currTimeMs + kSaveUpdateIntervalMs) | 1; unsigned bytesWritten = 0; - for (const auto& [nodeId, link] : s_nodes) { + for (const auto& [nodeId, node] : s_nodes) { if (bytesWritten >= kMaxBytesPerSaveUpdate) break; - if (link->node->IsDirty()) { - if (unsigned bytes = NetCliAuthVaultNodeSave(link->node.Get(), nullptr, nullptr); bytes) { + if (node->IsDirty()) { + if (unsigned bytes = NetCliAuthVaultNodeSave(node.Get(), nullptr, nullptr); bytes) { bytesWritten += bytes; - link->node->Print("Saving", 0); + node->Print("Saving", 0); } } } @@ -778,7 +777,7 @@ void VaultCreateNodeTrans::VaultNodeFetched ( VaultCreateNodeTrans * trans = (VaultCreateNodeTrans *)param; if (IS_NET_SUCCESS(result)) { - trans->node = s_nodes.at(node->GetNodeId())->node; + trans->node = s_nodes.at(node->GetNodeId()); } else { trans->node = nullptr; } @@ -898,7 +897,7 @@ void VaultDownloadTrans::VaultNodeRefsFetched ( else { // root node has no child heirarchy? Make sure we still d/l the root node if necessary. auto rootNodeIt = s_nodes.find(trans->vaultId); - if (rootNodeIt == s_nodes.end() || rootNodeIt->second->node->GetNodeType() == 0) { + if (rootNodeIt == s_nodes.end() || rootNodeIt->second->GetNodeType() == 0) { NetCliAuthVaultNodeFetch( trans->vaultId, VaultDownloadTrans::VaultNodeFetched, @@ -1531,10 +1530,8 @@ void VaultDestroy () { VaultClearDeviceInboxMap(); for (auto it = s_nodes.begin(); it != s_nodes.end();) { - RelVaultNodeLink* link = it->second; - link->node->state->UnlinkFromRelatives(); + it->second->state->UnlinkFromRelatives(); it = s_nodes.erase(it); - delete link; } } @@ -1555,9 +1552,9 @@ hsRef VaultGetNode ( hsWeakRef templateNode ) { ASSERT(templateNode); - for (const auto& [nodeId, link] : s_nodes) { - if (link->node->Matches(templateNode.Get())) { - return link->node; + for (const auto& [nodeId, node] : s_nodes) { + if (node->Matches(templateNode.Get())) { + return node; } } return nullptr; @@ -1568,7 +1565,7 @@ hsRef VaultGetNode ( unsigned nodeId ) { auto it = s_nodes.find(nodeId); - return it == s_nodes.end() ? nullptr : it->second->node; + return it == s_nodes.end() ? nullptr : it->second; } //============================================================================ @@ -1592,18 +1589,15 @@ void VaultAddChildNode ( auto parentIt = s_nodes.find(parentId); if (parentIt != s_nodes.end()) { - RelVaultNodeLink* parentLink = parentIt->second; + const hsRef& parentNode = parentIt->second; auto childIt = s_nodes.find(childId); - RelVaultNodeLink* childLink; + hsRef childNode; if (childIt == s_nodes.end()) { - childLink = new RelVaultNodeLink(false, ownerId); - childLink->node->SetNodeId_NoDirty(childId); - s_nodes.emplace(childId, childLink); + childNode.Steal(new RelVaultNode()); + childNode->SetNodeId_NoDirty(childId); + s_nodes.emplace(childId, childNode); } else { - childLink = childIt->second; - if (ownerId) { - childLink->ownerId = ownerId; - } + childNode = childIt->second; } // We can do a sanity check for a would-be circular link, but it isn't @@ -1612,13 +1606,13 @@ void VaultAddChildNode ( // before the authoritative check, we're risking the local client operating // on bad, possibly harmful vault state. Not harmful in a national security // kinda way, but still harmful. - if (parentLink->node->IsChildOf(childId, 255)) { + if (parentNode->IsChildOf(childId, 255)) { LogMsg(kLogDebug, "Node relationship would be circular: p:{}, c:{}", parentId, childId); // callback now with error code if (callback) callback(kNetErrCircularReference, param); } - else if (childLink->node->IsParentOf(parentId, 255)) { + else if (childNode->IsParentOf(parentId, 255)) { LogMsg(kLogDebug, "Node relationship would be circular: p:{}, c:{}", parentId, childId); // callback now with error code if (callback) @@ -1634,10 +1628,10 @@ void VaultAddChildNode ( BuildNodeTree(refs, std::size(refs), &newNodeIds, &existingNodeIds); - if (!childLink->node->GetNodeType() || !parentLink->node->GetNodeType()) { + if (!childNode->GetNodeType() || !parentNode->GetNodeType()) { // One or more nodes need to be fetched before the callback is made AddChildNodeFetchTrans * trans = new AddChildNodeFetchTrans(callback, param); - if (!childLink->node->GetNodeType()) { + if (!childNode->GetNodeType()) { ++trans->opCount; NetCliAuthVaultNodeFetch( childId, @@ -1651,7 +1645,7 @@ void VaultAddChildNode ( trans ); } - if (!parentLink->node->GetNodeType()) { + if (!parentNode->GetNodeType()) { ++trans->opCount; NetCliAuthVaultNodeFetch( parentId, @@ -1762,19 +1756,19 @@ void VaultRemoveChildNode ( break; } - RelVaultNodeLink* parentLink = parentIt->second; - RelVaultNodeLink* childLink = childIt->second; - if (parentLink->node->IsParentOf(childId, 1)) { + const hsRef& parentNode = parentIt->second; + const hsRef& childNode = childIt->second; + if (parentNode->IsParentOf(childId, 1)) { // We have the relationship, so make the callbacks if (s_suppressCallbacks == 0) { for (auto cb : s_callbacks) { - cb->RemovingChildNode(parentLink->node, childLink->node); + cb->RemovingChildNode(parentNode, childNode); } } } - - parentLink->node->state->Unlink(childLink->node); - childLink->node->state->Unlink(parentLink->node); + + parentNode->state->Unlink(childNode); + childNode->state->Unlink(parentNode); break; } @@ -2040,9 +2034,10 @@ void VaultLocalFindNodes ( hsWeakRef templateNode, std::vector * nodeIds ) { - for (const auto& [nodeId, link] : s_nodes) { - if (link->node->Matches(templateNode.Get())) - nodeIds->emplace_back(link->node->GetNodeId()); + for (const auto& [nodeId, node] : s_nodes) { + if (node->Matches(templateNode.Get())) { + nodeIds->emplace_back(node->GetNodeId()); + } } } @@ -4689,40 +4684,37 @@ void VaultCull (unsigned vaultId) { // Remove the node from the global table auto nodeIt = s_nodes.find(vaultId); if (nodeIt != s_nodes.end()) { - RelVaultNodeLink* link = nodeIt->second; - LogMsg(kLogDebug, "Vault: Culling node {}", link->node->GetNodeId()); - link->node->state->UnlinkFromRelatives(); + LogMsg(kLogDebug, "Vault: Culling node {}", nodeIt->first); + nodeIt->second->state->UnlinkFromRelatives(); s_nodes.erase(nodeIt); - delete link; } // Remove all orphaned nodes from the global table for (auto it = s_nodes.begin(); it != s_nodes.end();) { - RelVaultNodeLink* link = it->second; + const hsRef& node = it->second; - if (link->node->GetNodeType() > plVault::kNodeType_VNodeMgrLow && link->node->GetNodeType() < plVault::kNodeType_VNodeMgrHigh) { + if (node->GetNodeType() > plVault::kNodeType_VNodeMgrLow && node->GetNodeType() < plVault::kNodeType_VNodeMgrHigh) { ++it; continue; } std::vector nodeIds; - link->node->GetRootIds(&nodeIds); + node->GetRootIds(&nodeIds); bool foundRoot = false; for (unsigned nodeId : nodeIds) { auto rootIt = s_nodes.find(nodeId); if (rootIt != s_nodes.end()) { - RelVaultNodeLink* root = rootIt->second; - if (root->node->GetNodeType() > plVault::kNodeType_VNodeMgrLow && root->node->GetNodeType() < plVault::kNodeType_VNodeMgrHigh) { + const hsRef& root = rootIt->second; + if (root->GetNodeType() > plVault::kNodeType_VNodeMgrLow && root->GetNodeType() < plVault::kNodeType_VNodeMgrHigh) { foundRoot = true; break; } } } if (!foundRoot) { - LogMsg(kLogDebug, "Vault: Culling node {}", link->node->GetNodeId()); - link->node->state->UnlinkFromRelatives(); + LogMsg(kLogDebug, "Vault: Culling node {}", it->first); + node->state->UnlinkFromRelatives(); it = s_nodes.erase(it); - delete link; } else { ++it; } From 32a9e6b073018fe599b86edcd698c3e658d3d66c Mon Sep 17 00:00:00 2001 From: dgelessus Date: Tue, 15 Aug 2023 01:22:40 +0200 Subject: [PATCH 06/10] Change IRelVaultNode::parents to store just a node ref and not a link As with s_nodes, the owner and seen info was never used here. The fields were never filled in either, even though here it's clear which values they should have. --- .../PubUtilLib/plVault/plVaultClientApi.cpp | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index b59efd38aa..0c07cb9a05 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -55,7 +55,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com * ***/ -// A RelVaultNodeLink may be stored in an IRelVaultNode's parents or children table. +// A RelVaultNodeLink is stored in an IRelVaultNode's children table. struct RelVaultNodeLink { hsRef node; unsigned ownerId; @@ -73,8 +73,8 @@ struct RelVaultNodeLink { struct IRelVaultNode { hsWeakRef node; - - std::unordered_map parents; + + std::unordered_map> parents; std::unordered_map children; IRelVaultNode(hsWeakRef node); @@ -357,8 +357,7 @@ static void BuildNodeTree ( if (!isImmediateParent) { // Add parent to child's parents table - RelVaultNodeLink* parentLink = new RelVaultNodeLink(false, 0, parentNode); - childNode->state->parents.emplace(parentNode->GetNodeId(), parentLink); + childNode->state->parents.emplace(parentNode->GetNodeId(), parentNode); LogMsg(kLogDebug, "Added relationship: p:{},c:{}", refs[i].parentId, refs[i].childId); } @@ -1035,17 +1034,17 @@ IRelVaultNode::~IRelVaultNode () { void IRelVaultNode::UnlinkFromRelatives () { for (auto it = parents.begin(); it != parents.end();) { // Advance the iterator before calling Unlink so that it doesn't get invalidated - RelVaultNodeLink* link = it->second; + hsRef parentNode = it->second; ++it; // We have the relationship, so make the callbacks if (s_suppressCallbacks == 0) { for (auto cb : s_callbacks) { - cb->RemovingChildNode(link->node, this->node); + cb->RemovingChildNode(parentNode, this->node); } } - link->node->state->Unlink(node); + parentNode->state->Unlink(node); } for (auto it = children.begin(); it != children.end();) { // Advance the iterator before calling Unlink so that it doesn't get invalidated @@ -1065,13 +1064,12 @@ void IRelVaultNode::Unlink(hsWeakRef other) { auto parentIt = parents.find(other->GetNodeId()); if (parentIt != parents.end()) { - // Copy the link pointer - the erase call will invalidate the iterator! - RelVaultNodeLink* link = parentIt->second; + // Grab the node ref - the erase call will invalidate the iterator! + hsRef parentNode = std::move(parentIt->second); // make them non-findable in our parents table parents.erase(parentIt); // remove us from other's tables. - link->node->state->Unlink(node); - delete link; + parentNode->state->Unlink(node); } auto childIt = children.find(other->GetNodeId()); @@ -1124,9 +1122,11 @@ bool RelVaultNode::IsChildOf (unsigned parentId, unsigned maxDepth) { return false; if (state->parents.find(parentId) != state->parents.end()) return true; - for (const auto& [nodeId, link] : state->parents) - if (link->node->IsChildOf(parentId, maxDepth - 1)) + for (const auto& [nodeId, node] : state->parents) { + if (node->IsChildOf(parentId, maxDepth - 1)) { return true; + } + } return false; } @@ -1135,8 +1135,8 @@ void RelVaultNode::GetRootIds (std::vector * nodeIds) { if (state->parents.empty()) { nodeIds->emplace_back(GetNodeId()); } else { - for (const auto& [nodeId, link] : state->parents) { - link->node->GetRootIds(nodeIds); + for (const auto& [nodeId, node] : state->parents) { + node->GetRootIds(nodeIds); } } } @@ -1167,9 +1167,9 @@ void RelVaultNode::GetParentNodeIds ( ) { if (!maxDepth) return; - for (const auto& [nodeId, link] : state->parents) { - nodeIds->emplace_back(link->node->GetNodeId()); - link->node->GetParentNodeIds(nodeIds, maxDepth-1); + for (const auto& [nodeId, node] : state->parents) { + nodeIds->emplace_back(node->GetNodeId()); + node->GetParentNodeIds(nodeIds, maxDepth-1); } } @@ -1182,14 +1182,16 @@ hsRef RelVaultNode::GetParentNode ( if (maxDepth == 0) return nullptr; - for (const auto& [nodeId, link] : state->parents) { - if (link->node->Matches(templateNode.Get())) - return link->node; + for (const auto& [nodeId, node] : state->parents) { + if (node->Matches(templateNode.Get())) { + return node; + } } - for (const auto& [nodeId, link] : state->parents) { - if (hsRef node = link->node->GetParentNode(templateNode, maxDepth - 1)) - return node; + for (const auto& [nodeId, node] : state->parents) { + if (hsRef parentNode = node->GetParentNode(templateNode, maxDepth - 1)) { + return parentNode; + } } return nullptr; @@ -1334,9 +1336,9 @@ unsigned RelVaultNode::GetRefOwnerId (unsigned parentId) { // find our parents' link to us and return its ownerId auto parentIt = state->parents.find(parentId); if (parentIt != state->parents.end()) { - RelVaultNodeLink* parentLink = parentIt->second; - auto childIt = parentLink->node->state->children.find(GetNodeId()); - if (childIt != parentLink->node->state->children.end()) { + const hsRef& parentNode = parentIt->second; + auto childIt = parentNode->state->children.find(GetNodeId()); + if (childIt != parentNode->state->children.end()) { RelVaultNodeLink* childLink = childIt->second; return childLink->ownerId; } @@ -1349,9 +1351,9 @@ bool RelVaultNode::BeenSeen (unsigned parentId) const { // find our parents' link to us and return its seen flag auto parentIt = state->parents.find(parentId); if (parentIt != state->parents.end()) { - RelVaultNodeLink* parentLink = parentIt->second; - auto childIt = parentLink->node->state->children.find(GetNodeId()); - if (childIt != parentLink->node->state->children.end()) { + const hsRef& parentNode = parentIt->second; + auto childIt = parentNode->state->children.find(GetNodeId()); + if (childIt != parentNode->state->children.end()) { RelVaultNodeLink* childLink = childIt->second; return childLink->seen; } @@ -1364,9 +1366,9 @@ void RelVaultNode::SetSeen (unsigned parentId, bool seen) { // find our parents' link to us and set its seen flag auto parentIt = state->parents.find(parentId); if (parentIt != state->parents.end()) { - RelVaultNodeLink* parentLink = parentIt->second; - auto childIt = parentLink->node->state->children.find(GetNodeId()); - if (childIt != parentLink->node->state->children.end()) { + const hsRef& parentNode = parentIt->second; + auto childIt = parentNode->state->children.find(GetNodeId()); + if (childIt != parentNode->state->children.end()) { RelVaultNodeLink* childLink = childIt->second; if (childLink->seen != seen) { childLink->seen = seen; From 5084f0bcce1f7d8bc253d6dcad6fa8b6a3db8478 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Tue, 15 Aug 2023 01:29:09 +0200 Subject: [PATCH 07/10] Store IRelVaultNode::children links by value instead of pointer --- .../PubUtilLib/plVault/plVaultClientApi.cpp | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index 0c07cb9a05..ee24dbaab4 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -75,7 +75,7 @@ struct IRelVaultNode { hsWeakRef node; std::unordered_map> parents; - std::unordered_map children; + std::unordered_map children; IRelVaultNode(hsWeakRef node); ~IRelVaultNode (); @@ -363,8 +363,7 @@ static void BuildNodeTree ( if (!isImmediateChild) { // Add child to parent's children table - RelVaultNodeLink* childLink = new RelVaultNodeLink(refs[i].seen, refs[i].ownerId, childNode); - parentNode->state->children.emplace(childNode->GetNodeId(), childLink); + parentNode->state->children.emplace(childNode->GetNodeId(), RelVaultNodeLink(refs[i].seen, refs[i].ownerId, childNode)); if (notifyNow || childNode->GetNodeType() != 0) { // We made a new link, so make the callbacks @@ -1048,9 +1047,9 @@ void IRelVaultNode::UnlinkFromRelatives () { } for (auto it = children.begin(); it != children.end();) { // Advance the iterator before calling Unlink so that it doesn't get invalidated - RelVaultNodeLink* link = it->second; + hsRef childNode = it->second.node; ++it; - link->node->state->Unlink(node); + childNode->state->Unlink(node); } ASSERT(parents.empty()); @@ -1074,13 +1073,12 @@ void IRelVaultNode::Unlink(hsWeakRef other) { auto childIt = children.find(other->GetNodeId()); if (childIt != children.end()) { - // Copy the link pointer - the erase call will invalidate the iterator! - RelVaultNodeLink* link = childIt->second; + // Grab the node ref - the erase call will invalidate the iterator! + hsRef childNode = std::move(childIt->second.node); // make them non-findable in our children table children.erase(childIt); // remove us from other's tables. - link->node->state->Unlink(node); - delete link; + childNode->state->Unlink(node); } } @@ -1108,9 +1106,11 @@ bool RelVaultNode::IsParentOf (unsigned childId, unsigned maxDepth) { return false; if (state->children.find(childId) != state->children.end()) return true; - for (const auto& [nodeId, link] : state->children) - if (link->node->IsParentOf(childId, maxDepth - 1)) + for (const auto& [nodeId, link] : state->children) { + if (link.node->IsParentOf(childId, maxDepth - 1)) { return true; + } + } return false; } @@ -1155,8 +1155,8 @@ void RelVaultNode::GetChildNodeIds ( if (!maxDepth) return; for (const auto& [nodeId, link] : state->children) { - nodeIds->emplace_back(link->node->GetNodeId()); - link->node->GetChildNodeIds(nodeIds, maxDepth-1); + nodeIds->emplace_back(link.node->GetNodeId()); + link.node->GetChildNodeIds(nodeIds, maxDepth-1); } } @@ -1206,13 +1206,15 @@ hsRef RelVaultNode::GetChildNode ( return nullptr; for (const auto& [nodeId, link] : state->children) { - if (link->node->Matches(templateNode.Get())) - return link->node; + if (link.node->Matches(templateNode.Get())) { + return link.node; + } } for (const auto& [nodeId, link] : state->children) { - if (hsRef node = link->node->GetChildNode(templateNode, maxDepth-1)) + if (hsRef node = link.node->GetChildNode(templateNode, maxDepth - 1)) { return node; + } } return nullptr; @@ -1273,8 +1275,8 @@ void RelVaultNode::GetChildNodes ( return; for (const auto& [nodeId, link] : state->children) { - nodes->push_back(link->node); - link->node->GetChildNodes( + nodes->push_back(link.node); + link.node->GetChildNodes( maxDepth - 1, nodes ); @@ -1288,10 +1290,11 @@ void RelVaultNode::GetChildNodes ( RelVaultNode::RefList * nodes ) { for (const auto& [nodeId, link] : state->children) { - if (link->node->Matches(templateNode.Get())) - nodes->push_back(link->node); + if (link.node->Matches(templateNode.Get())) { + nodes->push_back(link.node); + } - link->node->GetChildNodes( + link.node->GetChildNodes( templateNode, maxDepth - 1, nodes @@ -1339,8 +1342,7 @@ unsigned RelVaultNode::GetRefOwnerId (unsigned parentId) { const hsRef& parentNode = parentIt->second; auto childIt = parentNode->state->children.find(GetNodeId()); if (childIt != parentNode->state->children.end()) { - RelVaultNodeLink* childLink = childIt->second; - return childLink->ownerId; + return childIt->second.ownerId; } } return 0; @@ -1354,8 +1356,7 @@ bool RelVaultNode::BeenSeen (unsigned parentId) const { const hsRef& parentNode = parentIt->second; auto childIt = parentNode->state->children.find(GetNodeId()); if (childIt != parentNode->state->children.end()) { - RelVaultNodeLink* childLink = childIt->second; - return childLink->seen; + return childIt->second.seen; } } return true; @@ -1369,9 +1370,9 @@ void RelVaultNode::SetSeen (unsigned parentId, bool seen) { const hsRef& parentNode = parentIt->second; auto childIt = parentNode->state->children.find(GetNodeId()); if (childIt != parentNode->state->children.end()) { - RelVaultNodeLink* childLink = childIt->second; - if (childLink->seen != seen) { - childLink->seen = seen; + RelVaultNodeLink& childLink = childIt->second; + if (childLink.seen != seen) { + childLink.seen = seen; NetCliAuthVaultSetSeen(parentId, GetNodeId(), seen); } } @@ -1455,7 +1456,7 @@ void RelVaultNode::Print (const ST::string& tag, unsigned level) { void RelVaultNode::PrintTree (unsigned level) { Print("", level); for (const auto& [nodeId, link] : state->children) { - link->node->PrintTree(level + 1); + link.node->PrintTree(level + 1); } } From 0703c8d9f2ce3553683bb53ab491557fe34ef4f8 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Tue, 15 Aug 2023 01:32:41 +0200 Subject: [PATCH 08/10] Remove no longer used pnUtHash (HASHTABLEDECL, HASHLINK) --- .../Plasma/NucleusLib/pnUtils/CMakeLists.txt | 2 - .../NucleusLib/pnUtils/pnUtAllIncludes.h | 1 - .../Plasma/NucleusLib/pnUtils/pnUtHash.cpp | 93 --- Sources/Plasma/NucleusLib/pnUtils/pnUtHash.h | 610 ------------------ 4 files changed, 706 deletions(-) delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/pnUtHash.cpp delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/pnUtHash.h diff --git a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt index 082a91842c..65c510611b 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt +++ b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt @@ -4,7 +4,6 @@ set(pnUtils_HEADERS pnUtCoreLib.h pnUtAllIncludes.h pnUtCrypt.h - pnUtHash.h pnUtList.h pnUtStr.h pnUtTime.h @@ -12,7 +11,6 @@ set(pnUtils_HEADERS set(pnUtils_SOURCES pnUtCrypt.cpp - pnUtHash.cpp pnUtList.cpp pnUtStr.cpp pnUtTime.cpp diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h b/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h index a5afd7e99d..9fdffb9c68 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h +++ b/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h @@ -51,7 +51,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pnUtCoreLib.h" // must be first in list #include "pnUtList.h" -#include "pnUtHash.h" #include "pnUtTime.h" #include "pnUtStr.h" #include "pnUtCrypt.h" diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtHash.cpp b/Sources/Plasma/NucleusLib/pnUtils/pnUtHash.cpp deleted file mode 100644 index 9b5e63696a..0000000000 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtHash.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtHash.cpp -* -***/ - -#include "Pch.h" -#include "pnUtHash.h" - -/**************************************************************************** -* -* CHashValue -* -***/ - -// These random values were generated by the radioactive decay based -// random number generator at www.fourmilab.ch -const uint32_t CHashValue::s_hashTable[] = { - 0xe8fd2035, 0xaf1add63, 0x049fb872, 0xcf9bb8eb, 0xc30d2a72, 0x15efaec1, 0xd250c7d9, 0xaf3c60a8, - 0x17ae32ff, 0x4089cd9e, 0x91dd6936, 0x093f880d, 0x9608ae8f, 0x452c0e11, 0xb6840ffd, 0x3e36c913, - 0x393114fd, 0xa72556b2, 0x7c338fb7, 0x4e445027, 0x2864eace, 0x9b0a17d6, 0x108da74b, 0xf2c479c1, - 0x288a43ac, 0x241e8411, 0x12ace782, 0xfb015799, 0x8b4dd597, 0x97199bc0, 0x621f0cce, 0x1658553e, - 0x99697839, 0xe3efb551, 0xbc1a2625, 0x54583c22, 0x9693d685, 0x612f910a, 0x080ccee8, 0xd00a43c9, - 0x86e6984d, 0x793245cf, 0x5335afa0, 0xdb8734d8, 0xfe5ab506, 0x3aae2ec1, 0x0aac22a3, 0xf3cd2c16, - 0x3d3039d1, 0x070b576d, 0x3a624bff, 0x0e185383, 0x78316efa, 0xafbef9ad, 0x556130cc, 0x54813111, - 0xc0e59be8, 0x30010241, 0x2cfa9040, 0x5a039832, 0x68a8a31d, 0xac786303, 0xe81b7dea, 0x2e3d7f5a, - 0xabb30a5c, 0xab08fef0, 0xf88cdc9d, 0x962d8361, 0x82ae270c, 0xc45a6e9c, 0x506a3f62, 0xed7c8f10, - 0x64631545, 0xea26488a, 0xd39f06f7, 0xafa35b6b, 0xdd1f83fb, 0x60b57a99, 0x636373ee, 0x05e82732, - 0xb2eaf275, 0x4763208c, 0x49499166, 0x8e436c6a, 0x3a4f831a, 0x57b7c11e, 0xbd751298, 0x6217ffbc, - 0x789efe70, 0x91d695cc, 0xa7e9049e, 0x12b74cdb, 0x40a2d8e6, 0x4dd33013, 0x506ec265, 0x81b2a421, - 0xdf98bac4, 0x554e33d0, 0x514decf9, 0x4374274c, 0x70b09e64, 0xac951473, 0xd6bb35eb, 0xa65ed4cf, - 0x71f724ac, 0x91e8da43, 0xe386dcee, 0x45bc6b20, 0x08ddf47a, 0xadac9571, 0x44d3cddf, 0x535ace85, - 0x5ac801cc, 0x89e90941, 0xa0507200, 0xe4b2a9b2, 0x00922b39, 0x2848f374, 0xfbe97b80, 0x77ea2e00, - 0x05eea617, 0x2bf0baf7, 0x0c97f929, 0x4d3190c0, 0x31f58de0, 0x7cae5dc4, 0x39f33590, 0x9cd39b3f, - 0x98b0bf46, 0x393169f1, 0x9f8271da, 0x0b85462f, 0xb8b81857, 0xed66ce2c, 0x6f97f3bb, 0x87e8c7dd, - 0x55741d88, 0x9ccd43b8, 0xe537d98a, 0x64a28550, 0x165ba5bf, 0xe4229568, 0x1af7c624, 0x059b9f7a, - 0x38129d4a, 0x73dca9ba, 0xe0185118, 0x48560fdb, 0xb7d0ec6b, 0x1acd6d4b, 0x84ab7a10, 0xcd9bf830, - 0x539d6be2, 0xfdcb65f4, 0x183a4dd7, 0xc4425aa4, 0xa3934d5f, 0xf71b8023, 0x30c109f7, 0x512e5128, - 0x7decdea5, 0xd3aded88, 0x34288710, 0x0c07a16e, 0xec0299da, 0x1e738f1b, 0xd7b898e1, 0x1b7318fd, - 0x3b67392d, 0x60da77b3, 0x614d4804, 0xb854468a, 0x4dbfc9fd, 0x85185833, 0x56095260, 0xb85d0771, - 0xbfe579e7, 0x51ca011b, 0xcebd2983, 0x4d56cda1, 0x5ec08b9a, 0x6bf9aa6f, 0x7da1e2c0, 0x4499dd84, - 0x95ca5ba3, 0xd0f9e77b, 0x5d099253, 0xbe943272, 0x1a87fe96, 0x29584d77, 0x0344f269, 0x2bdafede, - 0x4ababc94, 0x7a06acb7, 0x0a4c1efe, 0x8699f00f, 0x0f74e313, 0x0469ac17, 0x80f17875, 0xa6aecf16, - 0x0d772a15, 0x60eb0850, 0xa852be33, 0xe1574793, 0x7847204c, 0x1cea62ac, 0xb5948e41, 0x0e574ae9, - 0xdeb24de3, 0xe6472a0b, 0xaaaaf355, 0xa271aeae, 0xf3d5d209, 0x4f8fa676, 0x25ff71c9, 0x3f38d7df, - 0x0a8cd458, 0x5c6ad602, 0x06d0c0ec, 0x0d84ac0f, 0xf3cc4a59, 0xd6f04d8c, 0x1b3c3229, 0xc8281f6d, - 0x9410dd7c, 0x502519d1, 0x4449a76a, 0x88ba67b6, 0x8f710894, 0x7b63230e, 0xc095db28, 0x155a4ac7, - 0x0d418a5d, 0xe2b69e59, 0xeab4ac50, 0x0de06aae, 0x60f272fa, 0x408aefd8, 0x01c3435a, 0x0880c1e3, - 0x4f23137b, 0x9dfd6434, 0xd1e25d94, 0xbad4c88a, 0x0746edf9, 0x8103a9aa, 0xc8c73617, 0xe0f2759a, - 0x00161c79, 0xd4545360, 0x1763cc5b, 0x296361fa, 0xbc35858d, 0xdaed5e93, 0x0b9d0aed, 0x01c45a64, -}; - diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtHash.h b/Sources/Plasma/NucleusLib/pnUtils/pnUtHash.h deleted file mode 100644 index 0bbf04dcaf..0000000000 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtHash.h +++ /dev/null @@ -1,610 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtHash.h -* -***/ - -#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTHASH_H -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTHASH_H - -#include "pnUtList.h" -#include "pnUtStr.h" - -/**************************************************************************** -* -* Macros -* -***/ - -// Define a field inside an object that is used to link it into a hash table -#define HASHLINK(object) THashLink< object > - -// Define a hash table: -// - starts with kSlotMinCount rows -// - can grow to kDefaultSlotMaxCount rows -// (hash table grows when a row contains more than kGrowOnListSize entries -#define HASHTABLEDECL(object,key,link) THashTableDecl< object, key, offsetof(object,link), 0 > - - -#if defined(_MSC_VER) -#define forceinline __forceinline -#else -#define forceinline inline -#endif - - -/**************************************************************************** -* -* Forward declarations -* -***/ - -template -class THashLink; - -template -class TBaseHashTable; - - -/**************************************************************************** -* -* CHashValue -* -***/ - -class CHashValue { -private: - static const uint32_t s_hashTable[]; - - uint32_t m_result; - - inline void Construct () { m_result = 0x325d1eae; } - -public: - static uint32_t LookupHashBits (unsigned value) { ASSERT(value < 0x100); return s_hashTable[value]; } - - inline CHashValue () { Construct() ; } - inline CHashValue (const CHashValue & source) { m_result = source.m_result; } - inline CHashValue (const void * data, unsigned bytes) { Construct(); Hash(data, bytes); } - inline CHashValue & operator= (const CHashValue & source) { m_result = source.m_result; return *this; } - inline bool operator== (const CHashValue & source) const { return (m_result == source.m_result); } - - inline uint32_t GetHash () const { return m_result; } - - forceinline void Hash (const void * data, unsigned bytes); - forceinline void Hash8 (unsigned data); - forceinline void Hash16 (unsigned data); - forceinline void Hash32 (unsigned data); - -}; - -//=========================================================================== -void CHashValue::Hash (const void * data, unsigned bytes) { - for (const uint8_t * curr = (const uint8_t *)data, * term = curr + bytes; curr != term; ++curr) - Hash8(*curr); -} - -//=========================================================================== -void CHashValue::Hash8 (unsigned data) { - m_result += s_hashTable[m_result >> 24] ^ (m_result >> 6) ^ s_hashTable[data & 0xff]; -} - -//=========================================================================== -void CHashValue::Hash16 (unsigned data) { - Hash8(data); - Hash8(data >> 8); -} - -//=========================================================================== -void CHashValue::Hash32 (unsigned data) { - Hash8(data); - Hash8(data >> 8); - Hash8(data >> 16); - Hash8(data >> 24); -} - - -/**************************************************************************** -* -* THashLink -* -***/ - -template -class THashLink { - friend class TBaseHashTable; - -private: - unsigned m_hash; - LINK(T) m_linkToFull; - LINK(T) m_linkToSlot; - -public: - THashLink() : m_hash(0) { } - - inline bool IsLinked () const; - inline T * Next (); - inline const T * Next () const; - inline T * Prev (); - inline const T * Prev () const; - inline void Unlink (); -}; - -//=========================================================================== -template -bool THashLink::IsLinked () const { - return m_linkToFull.IsLinked(); -} - -//=========================================================================== -template -T * THashLink::Next () { - return m_linkToFull.Next(); -} - -//=========================================================================== -template -const T * THashLink::Next () const { - return m_linkToFull.Next(); -} - -//=========================================================================== -template -T * THashLink::Prev () { - return m_linkToFull.Prev(); -} - -//=========================================================================== -template -const T * THashLink::Prev () const { - return m_linkToFull.Prev(); -} - -//=========================================================================== -template -void THashLink::Unlink () { - m_linkToFull.Unlink(); - m_linkToSlot.Unlink(); -} - - -/**************************************************************************** -* -* TBaseHashTable -* -***/ - -template -class TBaseHashTable { - -private: - enum { kSlotMinCount = 8 }; - enum { kDefaultSlotMaxCount = 1024 }; - enum { kGrowOnListSize = 5 }; - - LIST(T) m_fullList; - int m_linkOffset; - std::vector m_slotListArray; - unsigned m_slotMask; // always set to a power of two minus one - unsigned m_slotMaxCount; - - inline bool CheckGrowTable (LIST(T) * slotList); - inline const THashLink & GetLink (const T * object) const; - inline THashLink & GetLink (T * object); - inline void SetSlotCount (unsigned count); - -protected: - inline unsigned GetHash (const T * object) const; - inline unsigned & GetHash (T * object); - inline const LIST(T) & GetSlotList (unsigned hash) const; - inline LIST(T) & GetSlotList (unsigned hash); - inline void SetLinkOffset (int linkOffset, unsigned maxSize); - inline void SetSlotMaxCount (unsigned count); - -public: - inline TBaseHashTable (); - inline TBaseHashTable (const TBaseHashTable & source); - inline TBaseHashTable & operator= (const TBaseHashTable & source); - - inline void Add (T * object, unsigned hash); - inline void Clear (); - inline void Delete (T * object); - inline T * Head (); - inline const T * Head () const; - inline T * Next (const T * object); - inline const T * Next (const T * object) const; - inline void Order (T * linkedObject, ELinkType linkType, T * existingObject); - inline T * Prev (const T * object); - inline const T * Prev (const T * object) const; - inline T * Tail (); - inline const T * Tail () const; - inline void Unlink (T * object); - -}; - -//=========================================================================== -template -TBaseHashTable::TBaseHashTable () - : m_slotMask(), m_slotMaxCount(kDefaultSlotMaxCount), m_linkOffset() { - // more initialization done during call to SetLinkOffset() -} - -//=========================================================================== -template -TBaseHashTable::TBaseHashTable (const TBaseHashTable & source) { -#ifdef HS_DEBUGGING - FATAL("No copy constructor"); -#endif - TBaseHashTable(); -} - -//=========================================================================== -template -TBaseHashTable & TBaseHashTable::operator= (const TBaseHashTable & source) { -#ifdef HS_DEBUGGING - FATAL("No assignment operator"); -#endif - return *this; -} - -//=========================================================================== -template -void TBaseHashTable::Add (T * object, unsigned hash) { - GetHash(object) = hash; - - LIST(T) * list = &GetSlotList(hash); - if (CheckGrowTable(list)) - list = &GetSlotList(hash); - - m_fullList.Link(object); - list->Link(object); -} - -//=========================================================================== -template -bool TBaseHashTable::CheckGrowTable (LIST(T) * list) { - - unsigned nextCount = (m_slotMask + 1) * 2; - if (nextCount > m_slotMaxCount) - return false; - - unsigned listCount = 0; - for (T * curr = list->Head(); curr; curr = list->Next(curr)) - ++listCount; - - if (listCount + 1 < kGrowOnListSize) - return false; - - SetSlotCount(nextCount); - - return true; -} - -//=========================================================================== -template -void TBaseHashTable::Clear () { - m_fullList.Clear(); -} - -//=========================================================================== -template -void TBaseHashTable::Delete (T * object) { - delete object; -} - -//=========================================================================== -template -unsigned TBaseHashTable::GetHash (const T * object) const { - return GetLink(object).m_hash; -} - -//=========================================================================== -template -unsigned & TBaseHashTable::GetHash (T * object) { - return GetLink(object).m_hash; -} - -//=========================================================================== -template -const THashLink & TBaseHashTable::GetLink (const T * object) const { - return *(const THashLink *)((const uint8_t *)object + m_linkOffset); -} - -//=========================================================================== -template -THashLink & TBaseHashTable::GetLink (T * object) { - return *(THashLink *)((uint8_t *)object + m_linkOffset); -} - -//=========================================================================== -template -const LIST(T) & TBaseHashTable::GetSlotList (unsigned hash) const { - return m_slotListArray[hash & m_slotMask]; -} - -//=========================================================================== -template -LIST(T) & TBaseHashTable::GetSlotList (unsigned hash) { - return m_slotListArray[hash & m_slotMask]; -} - -//=========================================================================== -template -T * TBaseHashTable::Head () { - return m_fullList.Head(); -} - -//=========================================================================== -template -const T * TBaseHashTable::Head () const { - return m_fullList.Head(); -} - -//=========================================================================== -template -T * TBaseHashTable::Next (const T * object) { - return m_fullList.Next(object); -} - -//=========================================================================== -template -const T * TBaseHashTable::Next (const T * object) const { - return m_fullList.Next(object); -} - -//=========================================================================== -template -void TBaseHashTable::Order (T * linkedObject, ELinkType linkType, T * existingObject) { - THashLink & link = GetLink(linkedObject); - ASSERT(link.m_linkToFull.IsLinked()); - m_fullList.Link(linkedObject, linkType, existingObject); -} - -//=========================================================================== -template -T * TBaseHashTable::Prev (const T * object) { - return m_fullList.Prev(object); -} - -//=========================================================================== -template -const T * TBaseHashTable::Prev (const T * object) const { - return m_fullList.Prev(object); -} - -//=========================================================================== -template -void TBaseHashTable::SetLinkOffset (int linkOffset, unsigned maxSize) { - ASSERT(!m_fullList.Head()); - ASSERT(m_slotListArray.empty()); - ASSERT(!m_slotMask); - - m_linkOffset = linkOffset; - m_fullList.SetLinkOffset(m_linkOffset + offsetof(THashLink, m_linkToFull)); - - if (!m_slotMask) { - // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 - uint32_t v = maxSize - 1; - v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; - v++; - - SetSlotCount(std::max(static_cast(kSlotMinCount), v)); - } -} - -//=========================================================================== -template -void TBaseHashTable::SetSlotCount (unsigned count) { - ASSERT(!(count & (count - 1))); // power of two - ASSERT(count >= 2); - - if (count == m_slotMask + 1) - return; - m_slotMask = count - 1; - - m_slotListArray.clear(); - m_slotListArray.resize(count); - for (unsigned loop = 0; loop < count; ++loop) - m_slotListArray[loop].SetLinkOffset(m_linkOffset + offsetof(THashLink, m_linkToSlot)); - - for (T * curr = Head(); curr; curr = Next(curr)) - GetSlotList(GetHash(curr)).Link(curr); -} - -//=========================================================================== -template -void TBaseHashTable::SetSlotMaxCount (unsigned count) { - if (count) - m_slotMaxCount = std::max(static_cast(kSlotMinCount), count); -} - -//=========================================================================== -template -T * TBaseHashTable::Tail () { - return m_fullList.Tail(); -} - -//=========================================================================== -template -const T * TBaseHashTable::Tail () const { - return m_fullList.Tail(); -} - -//=========================================================================== -template -void TBaseHashTable::Unlink (T * object) { - THashLink & link = GetLink(object); - link.Unlink(); -} - - -/**************************************************************************** -* -* THashTable -* -***/ - -template -class THashTable : public TBaseHashTable { - -public: - inline void Add (T * object); - inline void Add (T * object, unsigned hash); - inline T * Find (const K & key); - inline T * FindNext (const K & key, T * object); - inline const T * Find (const K & key) const; - inline const T * FindNext (const K & key, const T * object) const; - inline T * Unduplicate (T * object, const K & key); - -}; - -//=========================================================================== -template -inline void THashTable::Add (T * object) { - TBaseHashTable::Add(object, object->GetHash()); -} - -//=========================================================================== -template -inline void THashTable::Add (T * object, unsigned hash) { - TBaseHashTable::Add(object, hash); -} - -//=========================================================================== -template -T * THashTable::Find (const K & key) { - return (T *)((const THashTable *)this)->Find(key); -} - -//=========================================================================== -template -T * THashTable::FindNext (const K & key, T * object) { - return (T *)((const THashTable *)this)->FindNext(key, object); -} - -//=========================================================================== -template -const T * THashTable::Find (const K & key) const { - unsigned hash = key.GetHash(); - const LIST(T) & slotList = this->GetSlotList(hash); - for (const T * curr = slotList.Head(); curr; curr = slotList.Next(curr)) - if ((this->GetHash(curr) == hash) && (*curr == key)) - return curr; - return nullptr; -} - -//=========================================================================== -template -const T * THashTable::FindNext (const K & key, const T * object) const { - unsigned hash = key.GetHash(); - const LIST(T) & slotList = this->GetSlotList(hash); - for (const T * curr = slotList.Next(object); curr; curr = slotList.Next(curr)) - if ((this->GetHash(curr) == hash) && (*curr == key)) - return curr; - return nullptr; -} - -//=========================================================================== -template -T * THashTable::Unduplicate (T * object, const K & key) { - T * existing = Find(key); - if (existing) { - delete object; - return existing; - } - else { - Add(object); - return object; - } -} - - -/**************************************************************************** -* -* THashTableDecl -* -***/ - -template -class THashTableDecl : public THashTable { - -public: - inline THashTableDecl (); - -}; - -//=========================================================================== -template -THashTableDecl::THashTableDecl () { - this->SetLinkOffset(linkOffset, maxSize); - this->SetSlotMaxCount(maxSize); -} - - -/**************************************************************************** -* -* THashKeyVal -* -***/ - -template -class THashKeyVal { -public: - THashKeyVal () : m_value(0) { } - THashKeyVal (const T & value) : m_value(value) { } - bool operator== (const THashKeyVal & rhs) const { - return m_value == rhs.m_value; - } - unsigned GetHash () const { - CHashValue hash(&m_value, sizeof(m_value)); - return hash.GetHash(); - } - const T & GetValue () const { return m_value; } - void SetValue (const T & value) { m_value = value; } - -protected: - T m_value; -}; - -#endif From 22f8306c44878a2609e557d890150241e64d42d6 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Tue, 15 Aug 2023 01:36:46 +0200 Subject: [PATCH 09/10] Remove no longer used RelVaultNodeLink constructor --- Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index ee24dbaab4..8f1697e186 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -61,10 +61,6 @@ struct RelVaultNodeLink { unsigned ownerId; bool seen; - RelVaultNodeLink(bool seen, unsigned ownerId) - : node(new RelVaultNode, hsStealRef), ownerId(ownerId), seen(seen) - { } - RelVaultNodeLink(bool seen, unsigned ownerId, hsRef node) : node(std::move(node)), ownerId(ownerId), seen(seen) { } From b760a5474b48f6472178cbcfa1b9a632acdc25e3 Mon Sep 17 00:00:00 2001 From: dgelessus Date: Thu, 17 Aug 2023 21:55:43 +0200 Subject: [PATCH 10/10] Avoid temporarily bumping RelVaultNode refcounts in a few places --- .../PubUtilLib/plVault/plVaultClientApi.cpp | 42 ++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index 8f1697e186..04dc8a5ea5 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -325,28 +325,26 @@ static void BuildNodeTree ( for (unsigned i = 0; i < refCount; ++i) { // Find/Create global links auto parentIt = s_nodes.find(refs[i].parentId); - hsRef parentNode; if (parentIt == s_nodes.end()) { newNodeIds->emplace_back(refs[i].parentId); - parentNode.Steal(new RelVaultNode()); - parentNode->SetNodeId_NoDirty(refs[i].parentId); - parentIt = s_nodes.emplace(refs[i].parentId, parentNode).first; + hsRef newParentNode(new RelVaultNode(), hsStealRef); + newParentNode->SetNodeId_NoDirty(refs[i].parentId); + parentIt = s_nodes.emplace(refs[i].parentId, std::move(newParentNode)).first; } else { - parentNode = parentIt->second; existingNodeIds->emplace_back(refs[i].parentId); } + const hsRef& parentNode = parentIt->second; auto childIt = s_nodes.find(refs[i].childId); - hsRef childNode; if (childIt == s_nodes.end()) { newNodeIds->emplace_back(refs[i].childId); - childNode.Steal(new RelVaultNode()); - childNode->SetNodeId_NoDirty(refs[i].childId); - s_nodes.emplace(refs[i].childId, childNode); + hsRef newChildNode(new RelVaultNode(), hsStealRef); + newChildNode->SetNodeId_NoDirty(refs[i].childId); + childIt = s_nodes.emplace(refs[i].childId, std::move(newChildNode)).first; } else { - childNode = childIt->second; existingNodeIds->emplace_back(refs[i].childId); } + const hsRef& childNode = childIt->second; bool isImmediateParent = parentNode->IsParentOf(refs[i].childId, 1); bool isImmediateChild = childNode->IsChildOf(refs[i].parentId, 1); @@ -504,14 +502,12 @@ static void VaultNodeFetched ( // Add to global node table auto it = s_nodes.find(node->GetNodeId()); - hsRef globalNode; if (it == s_nodes.end()) { - globalNode.Steal(new RelVaultNode()); - globalNode->SetNodeId_NoDirty(node->GetNodeId()); - it = s_nodes.emplace(node->GetNodeId(), globalNode).first; - } else { - globalNode = it->second; + hsRef newGlobalNode(new RelVaultNode(), hsStealRef); + newGlobalNode->SetNodeId_NoDirty(node->GetNodeId()); + it = s_nodes.emplace(node->GetNodeId(), std::move(newGlobalNode)).first; } + const hsRef& globalNode = it->second; globalNode->CopyFrom(node); InitFetchedNode(globalNode); @@ -1029,7 +1025,7 @@ IRelVaultNode::~IRelVaultNode () { void IRelVaultNode::UnlinkFromRelatives () { for (auto it = parents.begin(); it != parents.end();) { // Advance the iterator before calling Unlink so that it doesn't get invalidated - hsRef parentNode = it->second; + hsWeakRef parentNode = it->second; ++it; // We have the relationship, so make the callbacks @@ -1043,7 +1039,7 @@ void IRelVaultNode::UnlinkFromRelatives () { } for (auto it = children.begin(); it != children.end();) { // Advance the iterator before calling Unlink so that it doesn't get invalidated - hsRef childNode = it->second.node; + hsWeakRef childNode = it->second.node; ++it; childNode->state->Unlink(node); } @@ -1590,14 +1586,12 @@ void VaultAddChildNode ( if (parentIt != s_nodes.end()) { const hsRef& parentNode = parentIt->second; auto childIt = s_nodes.find(childId); - hsRef childNode; if (childIt == s_nodes.end()) { - childNode.Steal(new RelVaultNode()); - childNode->SetNodeId_NoDirty(childId); - s_nodes.emplace(childId, childNode); - } else { - childNode = childIt->second; + hsRef newChildNode(new RelVaultNode(), hsStealRef); + newChildNode->SetNodeId_NoDirty(childId); + childIt = s_nodes.emplace(childId, std::move(newChildNode)).first; } + const hsRef& childNode = childIt->second; // We can do a sanity check for a would-be circular link, but it isn't // authoritative. The db will prevent circular links from entering into