1
// libTorrent - BitTorrent library
2
// Copyright (C) 2005-2007, Jari Sundell
4
// This program is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
// In addition, as a special exception, the copyright holders give
19
// permission to link the code of portions of this program with the
20
// OpenSSL library under certain conditions as described in each
21
// individual source file, and distribute linked combinations
24
// You must obey the GNU General Public License in all respects for
25
// all of the code used other than OpenSSL. If you modify file(s)
26
// with this exception, you may extend this exception to your version
27
// of the file(s), but you are not obligated to do so. If you do not
28
// wish to do so, delete this exception statement from your version.
29
// If you delete this exception statement from all source files in the
30
// program, then also delete it here.
32
// Contact: Jari Sundell <jaris@ifi.uio.no>
35
// 3185 Skoppum, NORWAY
37
#ifndef LIBTORRENT_DHT_HASH_MAP_H
38
#define LIBTORRENT_DHT_HASH_MAP_H
43
#include <tr1/unordered_map>
48
#include "torrent/hash_string.h"
51
#include "dht_tracker.h"
56
// Hash functions for HashString keys, and dereferencing HashString pointers.
58
// Since the first few bits are very similar if not identical (since the IDs
59
// will be close to our own node ID), we use an offset of 64 bits in the hash
60
// string. These bits will be uniformly distributed until the number of DHT
61
// nodes on the planet approaches 2^64 which is... unlikely.
62
// An offset of 64 bits provides 96 significant bits which is fine as long as
63
// the size of size_t does not exceed 12 bytes, while still having correctly
64
// aligned 64-bit access.
65
static const unsigned int hashstring_hash_ofs = 8;
67
struct hashstring_ptr_hash : public std::unary_function<const HashString*, size_t> {
68
size_t operator () (const HashString* n) const
69
{ return *(size_t*)(n->data() + hashstring_hash_ofs); }
72
struct hashstring_hash : public std::unary_function<HashString, size_t> {
73
size_t operator () (const HashString& n) const
74
{ return *(size_t*)(n.data() + hashstring_hash_ofs); }
77
// Compare HashString pointers by dereferencing them.
78
struct hashstring_ptr_equal : public std::binary_function<const HashString*, const HashString*, bool> {
79
size_t operator () (const HashString* one, const HashString* two) const
80
{ return *one == *two; }
83
class DhtNodeList : public std::tr1::unordered_map<const HashString*, DhtNode*, hashstring_ptr_hash, hashstring_ptr_equal> {
85
typedef std::tr1::unordered_map<const HashString*, DhtNode*, hashstring_ptr_hash, hashstring_ptr_equal> base_type;
87
// Define accessor iterator with more convenient access to the key and
88
// element values. Allows changing the map definition more easily if needed.
90
struct accessor_wrapper : public T {
91
accessor_wrapper(const T& itr) : T(itr) { }
93
const HashString& id() const { return *(**this).first; }
94
DhtNode* node() const { return (**this).second; }
97
typedef accessor_wrapper<const_iterator> const_accessor;
98
typedef accessor_wrapper<iterator> accessor;
100
DhtNode* add_node(DhtNode* n);
104
class DhtTrackerList : public std::tr1::unordered_map<HashString, DhtTracker*, hashstring_hash> {
106
typedef std::tr1::unordered_map<HashString, DhtTracker*, hashstring_hash> base_type;
109
struct accessor_wrapper : public T {
110
accessor_wrapper(const T& itr) : T(itr) { }
112
const HashString& id() const { return (**this).first; }
113
DhtTracker* tracker() const { return (**this).second; }
116
typedef accessor_wrapper<const_iterator> const_accessor;
117
typedef accessor_wrapper<iterator> accessor;
123
// Compare HashString pointers by dereferencing them.
124
struct hashstring_ptr_less : public std::binary_function<const HashString*, const HashString*, bool> {
125
size_t operator () (const HashString* one, const HashString* two) const
126
{ return *one < *two; }
129
class DhtNodeList : public std::map<const HashString*, DhtNode*, hashstring_ptr_less> {
131
typedef std::map<const HashString*, DhtNode*, hashstring_ptr_less> base_type;
133
// Define accessor iterator with more convenient access to the key and
134
// element values. Allows changing the map definition more easily if needed.
136
struct accessor_wrapper : public T {
137
accessor_wrapper(const T& itr) : T(itr) { }
139
const HashString& id() const { return *(**this).first; }
140
DhtNode* node() const { return (**this).second; }
143
typedef accessor_wrapper<const_iterator> const_accessor;
144
typedef accessor_wrapper<iterator> accessor;
146
DhtNode* add_node(DhtNode* n);
150
class DhtTrackerList : public std::map<HashString, DhtTracker*> {
152
typedef std::map<HashString, DhtTracker*> base_type;
155
struct accessor_wrapper : public T {
156
accessor_wrapper(const T& itr) : T(itr) { }
158
const HashString& id() const { return (**this).first; }
159
DhtTracker* tracker() const { return (**this).second; }
162
typedef accessor_wrapper<const_iterator> const_accessor;
163
typedef accessor_wrapper<iterator> accessor;
169
DhtNode* DhtNodeList::add_node(DhtNode* n) {
170
insert(std::make_pair<const HashString*, DhtNode*>(n, n));