mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-10-06 12:08:52 +00:00
store bucket's node in map rather than list
This commit is contained in:
@@ -40,12 +40,14 @@ namespace torrents
|
||||
|
||||
bool Bucket::ContainsNode (const NodeID& id) const
|
||||
{
|
||||
auto it = std::find_if (nodes.begin (), nodes.end (),
|
||||
[&id](const NodeID& nodeID)
|
||||
{
|
||||
return nodeID == id;
|
||||
});
|
||||
return it != nodes.end ();
|
||||
return nodes.contains (id);
|
||||
}
|
||||
|
||||
void Bucket::UpdateNode (const NodeID& id)
|
||||
{
|
||||
auto it = nodes.find (id);
|
||||
if (it != nodes.end ())
|
||||
it->second = i2p::util::GetMonotonicSeconds ();
|
||||
}
|
||||
|
||||
std::optional<NodeID> Bucket::GetMiddleID () const
|
||||
@@ -68,15 +70,11 @@ namespace torrents
|
||||
auto it = nodes.begin ();
|
||||
while (it != nodes.end ())
|
||||
{
|
||||
if (*it < *middleID)
|
||||
if (it->first < *middleID)
|
||||
it++; // stay in old bucket
|
||||
else
|
||||
{
|
||||
// move to new bucket
|
||||
auto node = *it;
|
||||
it = nodes.erase (it);
|
||||
newBucket->nodes.push_back (node);
|
||||
}
|
||||
newBucket->nodes.insert (nodes.extract (it++));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -160,7 +158,11 @@ namespace torrents
|
||||
if (id == m_OurNode) return false;
|
||||
auto bucket = FindBucket (id);
|
||||
if (!bucket) return false;
|
||||
if (bucket->ContainsNode (id)) return true;
|
||||
if (bucket->ContainsNode (id))
|
||||
{
|
||||
bucket->UpdateNode (id);
|
||||
return true;
|
||||
}
|
||||
if (bucket->IsFull ())
|
||||
{
|
||||
if (!bucket->IsInBucket (m_OurNode)) return false;
|
||||
@@ -172,7 +174,7 @@ namespace torrents
|
||||
while (bucket->IsFull ());
|
||||
}
|
||||
if (bucket)
|
||||
bucket->nodes.emplace_back (id);
|
||||
bucket->nodes.emplace (id, i2p::util::GetMonotonicSeconds ());
|
||||
RemoveEmptyBuckets ();
|
||||
return true;
|
||||
}
|
||||
@@ -187,13 +189,13 @@ namespace torrents
|
||||
{
|
||||
for (auto it: bucket->nodes)
|
||||
{
|
||||
auto nodeDistance = it ^ infoHash;
|
||||
auto nodeDistance = it.first ^ infoHash;
|
||||
auto it1 = std::find_if (ret.begin (), ret.end (),
|
||||
[&nodeDistance](const std::pair<NodeID, Distance>& alreadyFound)
|
||||
{
|
||||
return nodeDistance < alreadyFound.second;
|
||||
});
|
||||
ret.insert (it1, { it, nodeDistance } );
|
||||
ret.insert (it1, { it.first, nodeDistance } );
|
||||
}
|
||||
if (ret.size () > num) ret.resize (num);
|
||||
}
|
||||
@@ -218,7 +220,7 @@ namespace torrents
|
||||
{
|
||||
auto middleID = bucket->GetMiddleID ();
|
||||
if (middleID && !bucket->ContainsNode (*middleID)) // TODO: pick another id
|
||||
ret.emplace_back (std::make_pair(*middleID, bucket->nodes.front ()));
|
||||
ret.emplace_back (std::make_pair(*middleID, bucket->nodes.begin ()->first));
|
||||
}
|
||||
bucket = bucket->next;
|
||||
}
|
||||
@@ -229,7 +231,7 @@ namespace torrents
|
||||
{
|
||||
auto bucket = FindBucket (target);
|
||||
if (!bucket || bucket->nodes.empty ()) return m_OurNode;
|
||||
return bucket->nodes.front ();
|
||||
return bucket->nodes.begin ()->first;
|
||||
}
|
||||
|
||||
std::string DHTTorrent::GetBEncodedPeers () const
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace torrents
|
||||
struct Bucket
|
||||
{
|
||||
Bucket * next;
|
||||
std::list<NodeID> nodes;
|
||||
std::map<NodeID, uint64_t> nodes; // nodeID->update time in monotonic seconds
|
||||
NodeID start;
|
||||
|
||||
Bucket (): next (nullptr), start{} {}
|
||||
@@ -93,6 +93,7 @@ namespace torrents
|
||||
bool IsFull () const { return nodes.size () >= MAX_BUCKET_CAPACITY; }
|
||||
bool IsInBucket (const NodeID& id) const { return id >= start && (!next || id < next->start); }
|
||||
bool ContainsNode (const NodeID& id) const;
|
||||
void UpdateNode (const NodeID& id);
|
||||
std::optional<NodeID> GetMiddleID () const;
|
||||
bool Split ();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user