@@ -17,21 +17,25 @@ import TSFUtility
17
17
18
18
19
19
/// A simple in-memory implementation of the `LLBCASDatabase` protocol.
20
- public final class LLBInMemoryCASDatabase {
21
- /// The content.
22
- private var content = [ LLBDataID: LLBCASObject] ( )
20
+ public final class LLBInMemoryCASDatabase : Sendable {
21
+ struct State : Sendable {
22
+ /// The content.
23
+ var content = [ LLBDataID: LLBCASObject] ( )
23
24
24
- /// Threads capable of running futures.
25
- public var group : LLBFuturesDispatchGroup
25
+ var totalDataBytes : Int = 0
26
+ }
27
+
28
+ private let state : NIOLockedValueBox < State > = NIOLockedValueBox ( State ( ) )
26
29
27
- /// The lock protecting content .
28
- let lock = NIOConcurrencyHelpers . NIOLock ( )
30
+ /// Threads capable of running futures .
31
+ public let group : LLBFuturesDispatchGroup
29
32
30
33
/// The total number of data bytes in the database (this does not include the size of refs).
31
34
public var totalDataBytes : Int {
32
- return lock. withLock { _totalDataBytes }
35
+ return self . state. withLockedValue { state in
36
+ return state. totalDataBytes
37
+ }
33
38
}
34
- fileprivate var _totalDataBytes : Int = 0
35
39
36
40
/// Create an in-memory database.
37
41
public init ( group: LLBFuturesDispatchGroup ) {
@@ -41,23 +45,23 @@ public final class LLBInMemoryCASDatabase {
41
45
/// Delete the data in the database.
42
46
/// Intentionally not exposed via the CASDatabase protocol.
43
47
public func delete( _ id: LLBDataID , recursive: Bool ) -> LLBFuture < Void > {
44
- lock . withLockVoid {
45
- unsafeDelete ( id, recursive: recursive)
48
+ self . state . withLockedValue { state in
49
+ unsafeDelete ( state : & state , id, recursive: recursive)
46
50
}
47
51
return group. next ( ) . makeSucceededFuture ( ( ) )
48
52
}
49
- private func unsafeDelete( _ id: LLBDataID , recursive: Bool ) {
50
- guard let object = content [ id] else {
53
+ private func unsafeDelete( state : inout State , _ id: LLBDataID , recursive: Bool ) {
54
+ guard let object = state . content [ id] else {
51
55
return
52
56
}
53
- _totalDataBytes -= object. data. readableBytes
57
+ state . totalDataBytes -= object. data. readableBytes
54
58
55
59
guard recursive else {
56
60
return
57
61
}
58
62
59
63
for ref in object. refs {
60
- unsafeDelete ( ref, recursive: recursive)
64
+ unsafeDelete ( state : & state , ref, recursive: recursive)
61
65
}
62
66
}
63
67
}
@@ -68,12 +72,14 @@ extension LLBInMemoryCASDatabase: LLBCASDatabase {
68
72
}
69
73
70
74
public func contains( _ id: LLBDataID , _ ctx: Context ) -> LLBFuture < Bool > {
71
- let result = lock. withLock { self . content. index ( forKey: id) != nil }
75
+ let result = self . state. withLockedValue { state in
76
+ state. content. index ( forKey: id) != nil
77
+ }
72
78
return group. next ( ) . makeSucceededFuture ( result)
73
79
}
74
80
75
81
public func get( _ id: LLBDataID , _ ctx: Context ) -> LLBFuture < LLBCASObject ? > {
76
- let result = lock . withLock { self . content [ id] }
82
+ let result = self . state . withLockedValue { state in state . content [ id] }
77
83
return group. next ( ) . makeSucceededFuture ( result)
78
84
}
79
85
@@ -86,13 +92,13 @@ extension LLBInMemoryCASDatabase: LLBCASDatabase {
86
92
}
87
93
88
94
public func put( knownID id: LLBDataID , refs: [ LLBDataID ] = [ ] , data: LLBByteBuffer , _ ctx: Context ) -> LLBFuture < LLBDataID > {
89
- lock . withLockVoid {
90
- guard content [ id] == nil else {
91
- assert ( content [ id] ? . data == data, " put data for id doesn't match " )
95
+ self . state . withLockedValue { state in
96
+ guard state . content [ id] == nil else {
97
+ assert ( state . content [ id] ? . data == data, " put data for id doesn't match " )
92
98
return
93
99
}
94
- _totalDataBytes += data. readableBytes
95
- content [ id] = LLBCASObject ( refs: refs, data: data)
100
+ state . totalDataBytes += data. readableBytes
101
+ state . content [ id] = LLBCASObject ( refs: refs, data: data)
96
102
}
97
103
return group. next ( ) . makeSucceededFuture ( id)
98
104
}
0 commit comments