forked from bytemaster/tornet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkad.hpp
93 lines (73 loc) · 2.83 KB
/
kad.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#ifndef _TORNET_NET_KAD_HPP_
#define _TORNET_NET_KAD_HPP_
#include <tornet/net/node.hpp>
namespace tornet {
/**
* @class kad_search
* @breif Maintains state durring KAD node lookup.
*
* Doing a KAD lookup is not an exact science and is something that will be extended by derived
* classes that deal with 'special cases' such as finding a chunk or
* a particular service and where near matches count.
*
* The general algorithm is to perform the lookup in parallel of 3 to
* reduce latency. The algorithm will exit when the closest known node
* fails to return any closer nodes or when the target node is found.
*
*/
class kad_search : public boost::enable_shared_from_this<kad_search> {
public:
typedef boost::shared_ptr<kad_search> ptr;
enum status {
idle,
searching,
canceled,
done
};
/**
* @param N - the number of results to return, default 20
* @param P - the level of parallelism, default 3
*/
kad_search( const node::ptr& local_node, const node::id_type& target, uint32_t N = 20, uint32_t P = 3 );
virtual ~kad_search(){}
void start();
void cancel();
void wait( const boost::chrono::microseconds& s = boost::chrono::microseconds::max() );
const scrypt::sha1& target()const;
status get_status()const;
/**
* Returns a map of 'distance-to-target' to 'node_id'. This map is updated every time
* new results are returned. If the target is found, it will be the first item in
* the map.
*
* TODO: Document the thread this update occurs in...
*/
const std::map<node::id_type,node::id_type>& current_results()const {
return m_current_results;
}
const node::ptr& get_node()const { return m_node; }
protected:
/**
* This method can be overloaded by derived classes to perform
* operations on each node in the search path.
*
*/
virtual void filter( const node::id_type& id ){};
void set_status( status s ) { m_cur_status = s; }
uint32_t m_n;
uint32_t m_p;
private:
void search_thread();
node::ptr m_node;
node::id_type m_target;
node::id_type m_target_dist;
// all pending operations that must complete
// before the search is marked as 'done'
std::vector< boost::cmt::future<void> > m_pending;
status m_cur_status;
/// stores endpoints that are on deck ordered by distance.
std::map<node::id_type, node::endpoint> m_search_queue;
std::map<node::id_type, node::id_type> m_current_results;
};
} // namespace tornet
#endif