From 76452b4e281b83a93c923a9e144b10797f7d4066 Mon Sep 17 00:00:00 2001
From: Adam Ierymenko <adam.ierymenko@gmail.com>
Date: Thu, 1 Jun 2017 07:39:31 -0700
Subject: Data structure fixup.

---
 node/Node.cpp | 69 ++++++++++++++++++++++++++++++++---------------------------
 node/Node.hpp | 32 +++++++++++----------------
 2 files changed, 49 insertions(+), 52 deletions(-)

(limited to 'node')

diff --git a/node/Node.cpp b/node/Node.cpp
index 8849e0f4..bc4b858e 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -238,10 +238,13 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,uint64_t now,volatile uint
 			std::vector< SharedPtr<Network> > needConfig;
 			{
 				Mutex::Lock _l(_networks_m);
-				for(std::vector< std::pair< uint64_t,SharedPtr<Network> > >::const_iterator n(_networks.begin());n!=_networks.end();++n) {
-					if (((now - n->second->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!n->second->hasConfig()))
-						needConfig.push_back(n->second);
-					n->second->sendUpdatesToMembers(tptr);
+				Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(_networks);
+				uint64_t *k = (uint64_t *)0;
+				SharedPtr<Network> *v = (SharedPtr<Network> *)0;
+				while (i.next(k,v)) {
+					if (((now - (*v)->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!(*v)->hasConfig()))
+						needConfig.push_back(*v);
+					(*v)->sendUpdatesToMembers(tptr);
 				}
 			}
 			for(std::vector< SharedPtr<Network> >::const_iterator n(needConfig.begin());n!=needConfig.end();++n)
@@ -306,34 +309,30 @@ ZT_ResultCode Node::processBackgroundTasks(void *tptr,uint64_t now,volatile uint
 ZT_ResultCode Node::join(uint64_t nwid,void *uptr,void *tptr)
 {
 	Mutex::Lock _l(_networks_m);
-	SharedPtr<Network> nw = _network(nwid);
-	if(!nw) {
-		const std::pair< uint64_t,SharedPtr<Network> > nn(nwid,SharedPtr<Network>(new Network(RR,tptr,nwid,uptr)));
-		_networks.insert(std::upper_bound(_networks.begin(),_networks.end(),nn),nn);
-	}
+	SharedPtr<Network> &nw = _networks[nwid];
+	if (!nw)
+		nw = SharedPtr<Network>(new Network(RR,tptr,nwid,uptr));
 	return ZT_RESULT_OK;
 }
 
 ZT_ResultCode Node::leave(uint64_t nwid,void **uptr,void *tptr)
 {
 	ZT_VirtualNetworkConfig ctmp;
-	std::vector< std::pair< uint64_t,SharedPtr<Network> > > newn;
 	void **nUserPtr = (void **)0;
-	Mutex::Lock _l(_networks_m);
 
-	for(std::vector< std::pair< uint64_t,SharedPtr<Network> > >::const_iterator n(_networks.begin());n!=_networks.end();++n) {
-		if (n->first != nwid) {
-			newn.push_back(*n);
-		} else {
-			if (uptr)
-				*uptr = *n->second->userPtr();
-			n->second->externalConfig(&ctmp);
-			n->second->destroy();
-			nUserPtr = n->second->userPtr();
-		}
+	{
+		Mutex::Lock _l(_networks_m);
+		SharedPtr<Network> *nw = _networks.get(nwid);
+		if (!nw)
+			return ZT_RESULT_OK;
+		if (uptr)
+			*uptr = (*nw)->userPtr();
+		(*nw)->externalConfig(&ctmp);
+		(*nw)->destroy();
+		nUserPtr = (*nw)->userPtr();
+		_networks.erase(nwid);
 	}
-	_networks.swap(newn);
- 
+
 	if (nUserPtr)
 		RR->node->configureVirtualNetworkPort(tptr,nwid,nUserPtr,ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
 
@@ -431,10 +430,10 @@ ZT_PeerList *Node::peers() const
 ZT_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const
 {
 	Mutex::Lock _l(_networks_m);
-	SharedPtr<Network> nw = _network(nwid);
-	if(nw) {
+	const SharedPtr<Network> *nw = _networks.get(nwid);
+	if (nw) {
 		ZT_VirtualNetworkConfig *nc = (ZT_VirtualNetworkConfig *)::malloc(sizeof(ZT_VirtualNetworkConfig));
-		nw->externalConfig(nc);
+		(*nw)->externalConfig(nc);
 		return nc;
 	}
 	return (ZT_VirtualNetworkConfig *)0;
@@ -451,8 +450,11 @@ ZT_VirtualNetworkList *Node::networks() const
 	nl->networks = (ZT_VirtualNetworkConfig *)(buf + sizeof(ZT_VirtualNetworkList));
 
 	nl->networkCount = 0;
-	for(std::vector< std::pair< uint64_t,SharedPtr<Network> > >::const_iterator n(_networks.begin());n!=_networks.end();++n)
-		n->second->externalConfig(&(nl->networks[nl->networkCount++]));
+	Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(*const_cast< Hashtable< uint64_t,SharedPtr<Network> > *>(&_networks));
+	uint64_t *k = (uint64_t *)0;
+	SharedPtr<Network> *v = (SharedPtr<Network> *)0;
+	while (i.next(k,v))
+		(*v)->externalConfig(&(nl->networks[nl->networkCount++]));
 
 	return nl;
 }
@@ -601,10 +603,13 @@ bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,cons
 
 	{
 		Mutex::Lock _l(_networks_m);
-		for(std::vector< std::pair< uint64_t, SharedPtr<Network> > >::const_iterator i=_networks.begin();i!=_networks.end();++i) {
-			if (i->second->hasConfig()) {
-				for(unsigned int k=0;k<i->second->config().staticIpCount;++k) {
-					if (i->second->config().staticIps[k].containsAddress(remoteAddress))
+		Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(_networks);
+		uint64_t *k = (uint64_t *)0;
+		SharedPtr<Network> *v = (SharedPtr<Network> *)0;
+		while (i.next(k,v)) {
+			if ((*v)->hasConfig()) {
+				for(unsigned int k=0;k<(*v)->config().staticIpCount;++k) {
+					if ((*v)->config().staticIps[k].containsAddress(remoteAddress))
 						return false;
 				}
 			}
diff --git a/node/Node.hpp b/node/Node.hpp
index 006551fa..92e830c5 100644
--- a/node/Node.hpp
+++ b/node/Node.hpp
@@ -46,6 +46,7 @@
 #include "Path.hpp"
 #include "Salsa20.hpp"
 #include "NetworkController.hpp"
+#include "Hashtable.hpp"
 
 #undef TRACE
 #ifdef ZT_TRACE
@@ -154,26 +155,27 @@ public:
 	inline SharedPtr<Network> network(uint64_t nwid) const
 	{
 		Mutex::Lock _l(_networks_m);
-		return _network(nwid);
+		const SharedPtr<Network> *n = _networks.get(nwid);
+		if (n)
+			return *n;
+		return SharedPtr<Network>();
 	}
 
 	inline bool belongsToNetwork(uint64_t nwid) const
 	{
 		Mutex::Lock _l(_networks_m);
-		for(std::vector< std::pair< uint64_t, SharedPtr<Network> > >::const_iterator i=_networks.begin();i!=_networks.end();++i) {
-			if (i->first == nwid)
-				return true;
-		}
-		return false;
+		return _networks.contains(nwid);
 	}
 
 	inline std::vector< SharedPtr<Network> > allNetworks() const
 	{
 		std::vector< SharedPtr<Network> > nw;
 		Mutex::Lock _l(_networks_m);
-		nw.reserve(_networks.size());
-		for(std::vector< std::pair< uint64_t, SharedPtr<Network> > >::const_iterator i=_networks.begin();i!=_networks.end();++i)
-			nw.push_back(i->second);
+		Hashtable< uint64_t,SharedPtr<Network> >::Iterator i(*const_cast< Hashtable< uint64_t,SharedPtr<Network> > * >(&_networks));
+		uint64_t *k = (uint64_t *)0;
+		SharedPtr<Network> *v = (SharedPtr<Network> *)0;
+		while (i.next(k,v))
+			nw.push_back(*v);
 		return nw;
 	}
 
@@ -266,16 +268,6 @@ public:
 	virtual void ncSendError(uint64_t nwid,uint64_t requestPacketId,const Address &destination,NetworkController::ErrorCode errorCode);
 
 private:
-	inline SharedPtr<Network> _network(uint64_t nwid) const
-	{
-		// assumes _networks_m is locked
-		for(std::vector< std::pair< uint64_t, SharedPtr<Network> > >::const_iterator i=_networks.begin();i!=_networks.end();++i) {
-			if (i->first == nwid)
-				return i->second;
-		}
-		return SharedPtr<Network>();
-	}
-
 	RuntimeEnvironment _RR;
 	RuntimeEnvironment *RR;
 	void *_uPtr; // _uptr (lower case) is reserved in Visual Studio :P
@@ -288,7 +280,7 @@ private:
 	// Time of last identity verification indexed by InetAddress.rateGateHash() -- used in IncomingPacket::_doHELLO() via rateGateIdentityVerification()
 	uint64_t _lastIdentityVerification[16384];
 
-	std::vector< std::pair< uint64_t, SharedPtr<Network> > > _networks;
+	Hashtable< uint64_t,SharedPtr<Network> > _networks;
 	Mutex _networks_m;
 
 	std::vector<InetAddress> _directPaths;
-- 
cgit v1.2.3