mirror of https://github.com/oxen-io/lokinet
Merge branch 'master' of https://github.com/majestrate/llarp
commit
3241655ed9
@ -0,0 +1,63 @@
|
||||
#ifndef LLARP_PATHSET_HPP
|
||||
#define LLARP_PATHSET_HPP
|
||||
|
||||
#include <llarp/path_types.hpp>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace path
|
||||
{
|
||||
enum PathStatus
|
||||
{
|
||||
ePathBuilding,
|
||||
ePathEstablished,
|
||||
ePathTimeout,
|
||||
ePathExpired
|
||||
};
|
||||
// forward declare
|
||||
struct Path;
|
||||
|
||||
/// a set of paths owned by an entity
|
||||
struct PathSet
|
||||
{
|
||||
/// construct
|
||||
/// @params numPaths the number of paths to maintain
|
||||
PathSet(size_t numPaths);
|
||||
|
||||
void
|
||||
RemovePath(Path* path);
|
||||
|
||||
void
|
||||
HandlePathBuilt(Path* path);
|
||||
|
||||
void
|
||||
AddPath(Path* path);
|
||||
|
||||
Path*
|
||||
GetByUpstream(const RouterID& remote, const PathID_t& rxid);
|
||||
|
||||
void
|
||||
ExpirePaths(llarp_time_t now);
|
||||
|
||||
size_t
|
||||
NumInStatus(PathStatus st) const;
|
||||
|
||||
/// return true if we should build another path
|
||||
bool
|
||||
ShouldBuildMore() const;
|
||||
|
||||
private:
|
||||
typedef std::map< PathID_t, Path* > PathMap_t;
|
||||
// (tx,rx)
|
||||
typedef std::tuple< PathMap_t, PathMap_t > PathContainer_t;
|
||||
|
||||
size_t m_NumPaths;
|
||||
PathContainer_t m_Paths;
|
||||
};
|
||||
|
||||
} // namespace path
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
@ -0,0 +1,74 @@
|
||||
#ifndef LLARP_CODEL_QUEUE_HPP
|
||||
#define LLARP_CODEL_QUEUE_HPP
|
||||
#include <llarp/time.h>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
template < typename T, typename GetTime, llarp_time_t dropMs = 20,
|
||||
llarp_time_t initialIntervalMs = 100 >
|
||||
struct CoDelQueue
|
||||
{
|
||||
struct CoDelCompare
|
||||
{
|
||||
GetTime getTime = GetTime();
|
||||
bool
|
||||
operator()(const T& left, const T& right) const
|
||||
{
|
||||
return getTime(left) < getTime(right);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
Put(T* item)
|
||||
{
|
||||
std::unique_lock< std::mutex > lock(m_QueueMutex);
|
||||
m_Queue.push(*item);
|
||||
}
|
||||
|
||||
void
|
||||
Process(std::queue< T >& result)
|
||||
{
|
||||
llarp_time_t lowest = 0xFFFFFFFFFFFFFFFFUL;
|
||||
auto start = llarp_time_now_ms();
|
||||
std::unique_lock< std::mutex > lock(m_QueueMutex);
|
||||
while(m_Queue.size())
|
||||
{
|
||||
const auto& item = m_Queue.top();
|
||||
auto dlt = start - getTime(item);
|
||||
lowest = std::min(dlt, lowest);
|
||||
if(m_Queue.size() == 1)
|
||||
{
|
||||
if(lowest > dropMs)
|
||||
{
|
||||
// drop
|
||||
nextTickInterval = initialIntervalMs / std::sqrt(++dropNum);
|
||||
m_Queue.pop();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextTickInterval = initialIntervalMs;
|
||||
dropNum = 0;
|
||||
}
|
||||
}
|
||||
result.push(item);
|
||||
m_Queue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
GetTime getTime = GetTime();
|
||||
size_t dropNum = 0;
|
||||
llarp_time_t nextTickInterval = initialIntervalMs;
|
||||
std::mutex m_QueueMutex;
|
||||
std::priority_queue< T, std::vector< T >, CoDelCompare > m_Queue;
|
||||
};
|
||||
} // namespace util
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
@ -0,0 +1,97 @@
|
||||
#include <llarp/path.hpp>
|
||||
#include <llarp/pathset.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace path
|
||||
{
|
||||
PathSet::PathSet(size_t num) : m_NumPaths(num)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
PathSet::ShouldBuildMore() const
|
||||
{
|
||||
return std::get< 0 >(m_Paths).size() < m_NumPaths;
|
||||
}
|
||||
|
||||
void
|
||||
PathSet::ExpirePaths(llarp_time_t now)
|
||||
{
|
||||
{
|
||||
auto& map = std::get< 0 >(m_Paths);
|
||||
auto itr = map.begin();
|
||||
while(itr != map.end())
|
||||
{
|
||||
if(itr->second->Expired(now))
|
||||
{
|
||||
itr = map.erase(itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
auto& map = std::get< 1 >(m_Paths);
|
||||
auto itr = map.begin();
|
||||
while(itr != map.end())
|
||||
{
|
||||
if(itr->second->Expired(now))
|
||||
{
|
||||
// delete path on second iteration
|
||||
delete itr->second;
|
||||
itr = map.erase(itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
PathSet::NumInStatus(PathStatus st) const
|
||||
{
|
||||
size_t count = 0;
|
||||
auto& map = std::get< 0 >(m_Paths);
|
||||
auto itr = map.begin();
|
||||
while(itr != map.end())
|
||||
{
|
||||
if(itr->second->status == st)
|
||||
++count;
|
||||
++itr;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
PathSet::AddPath(Path* path)
|
||||
{
|
||||
std::get< 0 >(m_Paths).emplace(path->TXID(), path);
|
||||
std::get< 1 >(m_Paths).emplace(path->RXID(), path);
|
||||
}
|
||||
|
||||
void
|
||||
PathSet::RemovePath(Path* path)
|
||||
{
|
||||
std::get< 0 >(m_Paths).erase(path->TXID());
|
||||
std::get< 1 >(m_Paths).erase(path->RXID());
|
||||
}
|
||||
|
||||
Path*
|
||||
PathSet::GetByUpstream(const RouterID& remote, const PathID_t& rxid)
|
||||
{
|
||||
auto& set = std::get< 1 >(m_Paths);
|
||||
auto itr = set.begin();
|
||||
while(itr != set.end())
|
||||
{
|
||||
if(itr->second->Upstream() == remote)
|
||||
return itr->second;
|
||||
++itr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
PathSet::HandlePathBuilt(Path* path)
|
||||
{
|
||||
// TODO: implement me
|
||||
}
|
||||
|
||||
} // namespace path
|
||||
} // namespace llarp
|
Loading…
Reference in New Issue