mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			86 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Swift
		
	
| // Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
 | |
| 
 | |
| import Foundation
 | |
| import SessionUtilitiesKit
 | |
| 
 | |
| public enum SwarmDrainBehaviour {
 | |
|     case alwaysRandom
 | |
|     case limitedReuse(
 | |
|         count: UInt,
 | |
|         targetSnode: LibSession.Snode?,
 | |
|         targetUseCount: Int,
 | |
|         usedSnodes: Set<LibSession.Snode>,
 | |
|         swarmHash: Int
 | |
|     )
 | |
|     
 | |
|     public static func limitedReuse(count: UInt) -> SwarmDrainBehaviour {
 | |
|         guard count > 1 else { return .alwaysRandom }
 | |
|         
 | |
|         return .limitedReuse(count: count, targetSnode: nil, targetUseCount: 0, usedSnodes: [], swarmHash: 0)
 | |
|     }
 | |
|     
 | |
|     // MARK: - Convenience
 | |
|     
 | |
|     func use(snode: LibSession.Snode, from swarm: Set<LibSession.Snode>) -> SwarmDrainBehaviour {
 | |
|         switch self {
 | |
|             case .alwaysRandom: return .alwaysRandom
 | |
|             case .limitedReuse(let count, let targetSnode, let targetUseCount, let usedSnodes, _):
 | |
|                 // If we are using a new snode then reset everything
 | |
|                 guard targetSnode == snode else {
 | |
|                     return .limitedReuse(
 | |
|                         count: count,
 | |
|                         targetSnode: snode,
 | |
|                         targetUseCount: 1,
 | |
|                         usedSnodes: usedSnodes.inserting(snode),
 | |
|                         swarmHash: swarm.hashValue
 | |
|                     )
 | |
|                 }
 | |
|                 
 | |
|                 // Increment the use count and clear the target if it's been used too many times
 | |
|                 let updatedUseCount: Int = (targetUseCount + 1)
 | |
|                 
 | |
|                 return .limitedReuse(
 | |
|                     count: count,
 | |
|                     targetSnode: (updatedUseCount < count ? snode : nil),
 | |
|                     targetUseCount: updatedUseCount,
 | |
|                     usedSnodes: usedSnodes,
 | |
|                     swarmHash: swarm.hashValue
 | |
|                 )
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     public func clearTargetSnode() -> SwarmDrainBehaviour {
 | |
|         switch self {
 | |
|             case .alwaysRandom: return .alwaysRandom
 | |
|             case .limitedReuse(let count, _, _, let usedSnodes, let swarmHash):
 | |
|                 return .limitedReuse(
 | |
|                     count: count,
 | |
|                     targetSnode: nil,
 | |
|                     targetUseCount: 0,
 | |
|                     usedSnodes: usedSnodes,
 | |
|                     swarmHash: swarmHash
 | |
|                 )
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     public func reset() -> SwarmDrainBehaviour {
 | |
|         switch self {
 | |
|             case .alwaysRandom: return .alwaysRandom
 | |
|             case .limitedReuse(let count, _, _, _, _):
 | |
|                 return .limitedReuse(
 | |
|                     count: count,
 | |
|                     targetSnode: nil,
 | |
|                     targetUseCount: 0,
 | |
|                     usedSnodes: [],
 | |
|                     swarmHash: 0
 | |
|                 )
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| // MARK: - Convenience
 | |
| 
 | |
| public extension Atomic where Value == SwarmDrainBehaviour {
 | |
|     static var alwaysRandom: Atomic<SwarmDrainBehaviour> { Atomic(.alwaysRandom) }
 | |
| }
 |