@@ -12,23 +12,34 @@ type Allocator struct {
12
12
totalMemoryMax uint64
13
13
perPeerMax uint64
14
14
15
- allocLk sync.Mutex
16
- total uint64
17
- nextAllocIndex uint64
18
- peerStatuses map [peer.ID ]* peerStatus
19
- peerStatusQueue pq.PQ
15
+ allocLk sync.RWMutex
16
+ totalAllocatedAllPeers uint64
17
+ nextAllocIndex uint64
18
+ peerStatuses map [peer.ID ]* peerStatus
19
+ peerStatusQueue pq.PQ
20
20
}
21
21
22
22
func NewAllocator (totalMemoryMax uint64 , perPeerMax uint64 ) * Allocator {
23
23
return & Allocator {
24
- totalMemoryMax : totalMemoryMax ,
25
- perPeerMax : perPeerMax ,
26
- total : 0 ,
27
- peerStatuses : make (map [peer.ID ]* peerStatus ),
28
- peerStatusQueue : pq .New (makePeerStatusCompare (perPeerMax )),
24
+ totalMemoryMax : totalMemoryMax ,
25
+ perPeerMax : perPeerMax ,
26
+ totalAllocatedAllPeers : 0 ,
27
+ peerStatuses : make (map [peer.ID ]* peerStatus ),
28
+ peerStatusQueue : pq .New (makePeerStatusCompare (perPeerMax )),
29
29
}
30
30
}
31
31
32
+ func (a * Allocator ) AllocatedForPeer (p peer.ID ) uint64 {
33
+ a .allocLk .RLock ()
34
+ defer a .allocLk .RUnlock ()
35
+
36
+ status , ok := a .peerStatuses [p ]
37
+ if ! ok {
38
+ return 0
39
+ }
40
+ return status .totalAllocated
41
+ }
42
+
32
43
func (a * Allocator ) AllocateBlockMemory (p peer.ID , amount uint64 ) <- chan error {
33
44
responseChan := make (chan error , 1 )
34
45
a .allocLk .Lock ()
@@ -44,8 +55,8 @@ func (a *Allocator) AllocateBlockMemory(p peer.ID, amount uint64) <-chan error {
44
55
a .peerStatuses [p ] = status
45
56
}
46
57
47
- if (a .total + amount <= a .totalMemoryMax ) && (status .totalAllocated + amount <= a .perPeerMax ) && len (status .pendingAllocations ) == 0 {
48
- a .total += amount
58
+ if (a .totalAllocatedAllPeers + amount <= a .totalMemoryMax ) && (status .totalAllocated + amount <= a .perPeerMax ) && len (status .pendingAllocations ) == 0 {
59
+ a .totalAllocatedAllPeers += amount
49
60
status .totalAllocated += amount
50
61
responseChan <- nil
51
62
} else {
@@ -65,8 +76,16 @@ func (a *Allocator) ReleaseBlockMemory(p peer.ID, amount uint64) error {
65
76
if ! ok {
66
77
return errors .New ("cannot deallocate from peer with no allocations" )
67
78
}
68
- status .totalAllocated -= amount
69
- a .total -= amount
79
+ if status .totalAllocated > amount {
80
+ status .totalAllocated -= amount
81
+ } else {
82
+ status .totalAllocated = 0
83
+ }
84
+ if a .totalAllocatedAllPeers > amount {
85
+ a .totalAllocatedAllPeers -= amount
86
+ } else {
87
+ a .totalAllocatedAllPeers = 0
88
+ }
70
89
a .peerStatusQueue .Update (status .Index ())
71
90
a .processPendingAllocations ()
72
91
return nil
@@ -84,7 +103,7 @@ func (a *Allocator) ReleasePeerMemory(p peer.ID) error {
84
103
for _ , pendingAllocation := range status .pendingAllocations {
85
104
pendingAllocation .response <- errors .New ("Peer has been deallocated" )
86
105
}
87
- a .total -= status .totalAllocated
106
+ a .totalAllocatedAllPeers -= status .totalAllocated
88
107
a .processPendingAllocations ()
89
108
return nil
90
109
}
@@ -111,13 +130,13 @@ func (a *Allocator) processPendingAllocations() {
111
130
112
131
func (a * Allocator ) processNextPendingAllocationForPeer (nextPeer * peerStatus ) bool {
113
132
pendingAllocation := nextPeer .pendingAllocations [0 ]
114
- if a .total + pendingAllocation .amount > a .totalMemoryMax {
133
+ if a .totalAllocatedAllPeers + pendingAllocation .amount > a .totalMemoryMax {
115
134
return false
116
135
}
117
136
if nextPeer .totalAllocated + pendingAllocation .amount > a .perPeerMax {
118
137
return false
119
138
}
120
- a .total += pendingAllocation .amount
139
+ a .totalAllocatedAllPeers += pendingAllocation .amount
121
140
nextPeer .totalAllocated += pendingAllocation .amount
122
141
nextPeer .pendingAllocations = nextPeer .pendingAllocations [1 :]
123
142
pendingAllocation .response <- nil
0 commit comments