diff options
author | Bernd Fix <brf@hoi-polloi.org> | 2022-06-07 09:31:22 +0200 |
---|---|---|
committer | Bernd Fix <brf@hoi-polloi.org> | 2022-06-07 09:31:22 +0200 |
commit | 7a6ae8f61ee7efde161db98462259ea9bbb23386 (patch) | |
tree | 990de3aab9cec74f74185883a5ca3d2941b18dff /src/gnunet/service/dht/routingtable.go | |
parent | de577428a69a0002c3194afdf0562cf5a4dc1bdc (diff) | |
download | gnunet-go-7a6ae8f61ee7efde161db98462259ea9bbb23386.tar.gz gnunet-go-7a6ae8f61ee7efde161db98462259ea9bbb23386.zip |
Improved transport and module code.v0.1.24
Diffstat (limited to 'src/gnunet/service/dht/routingtable.go')
-rw-r--r-- | src/gnunet/service/dht/routingtable.go | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/src/gnunet/service/dht/routingtable.go b/src/gnunet/service/dht/routingtable.go index 0078b71..2933e6a 100644 --- a/src/gnunet/service/dht/routingtable.go +++ b/src/gnunet/service/dht/routingtable.go | |||
@@ -101,7 +101,7 @@ type RoutingTable struct { | |||
101 | ref *PeerAddress // reference address for distance | 101 | ref *PeerAddress // reference address for distance |
102 | buckets []*Bucket // list of buckets | 102 | buckets []*Bucket // list of buckets |
103 | list map[*PeerAddress]struct{} // keep list of peers | 103 | list map[*PeerAddress]struct{} // keep list of peers |
104 | rwlock sync.RWMutex // lock for write operations | 104 | mtx sync.RWMutex // lock for write operations |
105 | l2nse float64 // log2 of estimated network size | 105 | l2nse float64 // log2 of estimated network size |
106 | inProcess bool // flag if Process() is running | 106 | inProcess bool // flag if Process() is running |
107 | } | 107 | } |
@@ -131,8 +131,8 @@ func NewRoutingTable(ref *PeerAddress) *RoutingTable { | |||
131 | // Returns true if the entry was added, false otherwise. | 131 | // Returns true if the entry was added, false otherwise. |
132 | func (rt *RoutingTable) Add(p *PeerAddress) bool { | 132 | func (rt *RoutingTable) Add(p *PeerAddress) bool { |
133 | // ensure one write and no readers | 133 | // ensure one write and no readers |
134 | rt.rwlock.Lock() | 134 | rt.lock(false) |
135 | defer rt.rwlock.Unlock() | 135 | defer rt.unlock(false) |
136 | 136 | ||
137 | // check if peer is already known | 137 | // check if peer is already known |
138 | if _, ok := rt.list[p]; ok { | 138 | if _, ok := rt.list[p]; ok { |
@@ -153,8 +153,8 @@ func (rt *RoutingTable) Add(p *PeerAddress) bool { | |||
153 | // Returns true if the entry was removed, false otherwise. | 153 | // Returns true if the entry was removed, false otherwise. |
154 | func (rt *RoutingTable) Remove(p *PeerAddress) bool { | 154 | func (rt *RoutingTable) Remove(p *PeerAddress) bool { |
155 | // ensure one write and no readers | 155 | // ensure one write and no readers |
156 | rt.rwlock.Lock() | 156 | rt.lock(false) |
157 | defer rt.rwlock.Unlock() | 157 | defer rt.unlock(false) |
158 | 158 | ||
159 | // compute distance (bucket index) and remove entry from bucket | 159 | // compute distance (bucket index) and remove entry from bucket |
160 | _, idx := p.Distance(rt.ref) | 160 | _, idx := p.Distance(rt.ref) |
@@ -170,10 +170,15 @@ func (rt *RoutingTable) Remove(p *PeerAddress) bool { | |||
170 | //---------------------------------------------------------------------- | 170 | //---------------------------------------------------------------------- |
171 | 171 | ||
172 | // Process a function f in the locked context of a routing table | 172 | // Process a function f in the locked context of a routing table |
173 | func (rt *RoutingTable) Process(f func() error) error { | 173 | func (rt *RoutingTable) Process(f func() error, readonly bool) error { |
174 | // ensure one write and no readers | 174 | // handle locking |
175 | rt.rwlock.Lock() | 175 | rt.lock(readonly) |
176 | defer rt.rwlock.Unlock() | 176 | rt.inProcess = true |
177 | defer func() { | ||
178 | rt.inProcess = false | ||
179 | rt.unlock(readonly) | ||
180 | }() | ||
181 | // call function in unlocked context | ||
177 | return f() | 182 | return f() |
178 | } | 183 | } |
179 | 184 | ||
@@ -184,8 +189,8 @@ func (rt *RoutingTable) Process(f func() error) error { | |||
184 | // SelectClosestPeer for a given peer address and bloomfilter. | 189 | // SelectClosestPeer for a given peer address and bloomfilter. |
185 | func (rt *RoutingTable) SelectClosestPeer(p *PeerAddress, bf *PeerBloomFilter) (n *PeerAddress) { | 190 | func (rt *RoutingTable) SelectClosestPeer(p *PeerAddress, bf *PeerBloomFilter) (n *PeerAddress) { |
186 | // no writer allowed | 191 | // no writer allowed |
187 | rt.rwlock.RLock() | 192 | rt.mtx.RLock() |
188 | defer rt.rwlock.RUnlock() | 193 | defer rt.mtx.RUnlock() |
189 | 194 | ||
190 | // find closest address | 195 | // find closest address |
191 | var dist *math.Int | 196 | var dist *math.Int |
@@ -204,8 +209,8 @@ func (rt *RoutingTable) SelectClosestPeer(p *PeerAddress, bf *PeerBloomFilter) ( | |||
204 | // included in the bloomfilter) | 209 | // included in the bloomfilter) |
205 | func (rt *RoutingTable) SelectRandomPeer(bf *PeerBloomFilter) *PeerAddress { | 210 | func (rt *RoutingTable) SelectRandomPeer(bf *PeerBloomFilter) *PeerAddress { |
206 | // no writer allowed | 211 | // no writer allowed |
207 | rt.rwlock.RLock() | 212 | rt.mtx.RLock() |
208 | defer rt.rwlock.RUnlock() | 213 | defer rt.mtx.RUnlock() |
209 | 214 | ||
210 | // select random entry from list | 215 | // select random entry from list |
211 | if size := len(rt.list); size > 0 { | 216 | if size := len(rt.list); size > 0 { |
@@ -279,11 +284,35 @@ func (rt *RoutingTable) heartbeat(ctx context.Context) { | |||
279 | } | 284 | } |
280 | } | 285 | } |
281 | return nil | 286 | return nil |
282 | }); err != nil { | 287 | }, false); err != nil { |
283 | logger.Println(logger.ERROR, "[dht] RT heartbeat: "+err.Error()) | 288 | logger.Println(logger.ERROR, "[dht] RT heartbeat: "+err.Error()) |
284 | } | 289 | } |
285 | } | 290 | } |
286 | 291 | ||
292 | //---------------------------------------------------------------------- | ||
293 | |||
294 | // lock with given mode (if not in processing function) | ||
295 | func (rt *RoutingTable) lock(readonly bool) { | ||
296 | if !rt.inProcess { | ||
297 | if readonly { | ||
298 | rt.mtx.RLock() | ||
299 | } else { | ||
300 | rt.mtx.Lock() | ||
301 | } | ||
302 | } | ||
303 | } | ||
304 | |||
305 | // lock with given mode (if not in processing function) | ||
306 | func (rt *RoutingTable) unlock(readonly bool) { | ||
307 | if !rt.inProcess { | ||
308 | if readonly { | ||
309 | rt.mtx.RUnlock() | ||
310 | } else { | ||
311 | rt.mtx.Unlock() | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
287 | //====================================================================== | 316 | //====================================================================== |
288 | // Routing table buckets | 317 | // Routing table buckets |
289 | //====================================================================== | 318 | //====================================================================== |