@@ -919,17 +919,23 @@ where
919
919
///
920
920
/// The result of this operation is delivered in a
921
921
/// reported via [`KademliaEvent::OutboundQueryCompleted{QueryResult::GetProviders}`].
922
- pub fn get_providers ( & mut self , key : record:: Key ) -> QueryId {
922
+ pub fn get_providers ( & mut self , key : record:: Key , limit : ProviderLimit ) -> QueryId {
923
923
let providers = self
924
924
. store
925
925
. providers ( & key)
926
926
. into_iter ( )
927
927
. filter ( |p| !p. is_expired ( Instant :: now ( ) ) )
928
- . map ( |p| p. provider )
929
- . collect ( ) ;
928
+ . map ( |p| p. provider ) ;
929
+
930
+ let providers = match limit {
931
+ ProviderLimit :: None => providers. collect ( ) ,
932
+ ProviderLimit :: N ( limit) => providers. take ( limit. into ( ) ) . collect ( ) ,
933
+ } ;
934
+
930
935
let info = QueryInfo :: GetProviders {
931
936
key : key. clone ( ) ,
932
937
providers,
938
+ limit,
933
939
} ;
934
940
let target = kbucket:: Key :: new ( key) ;
935
941
let peers = self . kbuckets . closest_keys ( & target) ;
@@ -1258,17 +1264,19 @@ where
1258
1264
} ) ) ,
1259
1265
} ) ,
1260
1266
1261
- QueryInfo :: GetProviders { key, providers } => {
1262
- Some ( KademliaEvent :: OutboundQueryCompleted {
1263
- id : query_id,
1264
- stats : result. stats ,
1265
- result : QueryResult :: GetProviders ( Ok ( GetProvidersOk {
1266
- key,
1267
- providers,
1268
- closest_peers : result. peers . collect ( ) ,
1269
- } ) ) ,
1270
- } )
1271
- }
1267
+ QueryInfo :: GetProviders {
1268
+ key,
1269
+ providers,
1270
+ limit : _,
1271
+ } => Some ( KademliaEvent :: OutboundQueryCompleted {
1272
+ id : query_id,
1273
+ stats : result. stats ,
1274
+ result : QueryResult :: GetProviders ( Ok ( GetProvidersOk {
1275
+ key,
1276
+ providers,
1277
+ closest_peers : result. peers . collect ( ) ,
1278
+ } ) ) ,
1279
+ } ) ,
1272
1280
1273
1281
QueryInfo :: AddProvider {
1274
1282
context,
@@ -1553,17 +1561,19 @@ where
1553
1561
} ) ) ,
1554
1562
} ) ,
1555
1563
1556
- QueryInfo :: GetProviders { key, providers } => {
1557
- Some ( KademliaEvent :: OutboundQueryCompleted {
1558
- id : query_id,
1559
- stats : result. stats ,
1560
- result : QueryResult :: GetProviders ( Err ( GetProvidersError :: Timeout {
1561
- key,
1562
- providers,
1563
- closest_peers : result. peers . collect ( ) ,
1564
- } ) ) ,
1565
- } )
1566
- }
1564
+ QueryInfo :: GetProviders {
1565
+ key,
1566
+ providers,
1567
+ limit : _,
1568
+ } => Some ( KademliaEvent :: OutboundQueryCompleted {
1569
+ id : query_id,
1570
+ stats : result. stats ,
1571
+ result : QueryResult :: GetProviders ( Err ( GetProvidersError :: Timeout {
1572
+ key,
1573
+ providers,
1574
+ closest_peers : result. peers . collect ( ) ,
1575
+ } ) ) ,
1576
+ } ) ,
1567
1577
}
1568
1578
}
1569
1579
@@ -2331,6 +2341,31 @@ where
2331
2341
{
2332
2342
query. on_success ( & peer_id, vec ! [ ] )
2333
2343
}
2344
+
2345
+ if let QueryInfo :: GetProviders {
2346
+ key : _,
2347
+ providers,
2348
+ limit,
2349
+ } = & query. inner . info
2350
+ {
2351
+ match limit {
2352
+ ProviderLimit :: None => {
2353
+ // No limit, so wait for enough peers to respond.
2354
+ }
2355
+ ProviderLimit :: N ( n) => {
2356
+ // Check if we have enough providers.
2357
+ if usize:: from ( * n) <= providers. len ( ) {
2358
+ debug ! (
2359
+ "found enough providers {}/{}, finishing" ,
2360
+ providers. len( ) ,
2361
+ n
2362
+ ) ;
2363
+ query. finish ( ) ;
2364
+ }
2365
+ }
2366
+ }
2367
+ }
2368
+
2334
2369
if self . connected_peers . contains ( & peer_id) {
2335
2370
self . queued_events
2336
2371
. push_back ( NetworkBehaviourAction :: NotifyHandler {
@@ -2363,6 +2398,15 @@ where
2363
2398
}
2364
2399
}
2365
2400
2401
+ /// Specifies the number of provider records fetched.
2402
+ #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
2403
+ pub enum ProviderLimit {
2404
+ /// No limit on the number of records.
2405
+ None ,
2406
+ /// Finishes the query as soon as this many records have been found.
2407
+ N ( NonZeroUsize ) ,
2408
+ }
2409
+
2366
2410
/// A quorum w.r.t. the configured replication factor specifies the minimum
2367
2411
/// number of distinct nodes that must be successfully contacted in order
2368
2412
/// for a query to succeed.
@@ -2862,6 +2906,8 @@ pub enum QueryInfo {
2862
2906
key : record:: Key ,
2863
2907
/// The found providers.
2864
2908
providers : HashSet < PeerId > ,
2909
+ /// The limit of how many providers to find,
2910
+ limit : ProviderLimit ,
2865
2911
} ,
2866
2912
2867
2913
/// A (repeated) query initiated by [`Kademlia::start_providing`].
0 commit comments