From 2b8dec07fe2566bb7ecafc95048db23f2de5384c Mon Sep 17 00:00:00 2001 From: Paul Saab <ps@mu.org> Date: Wed, 24 Sep 2014 15:21:45 -0700 Subject: [PATCH] Use atomics to track peermap size --- tracker/models/peermap.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tracker/models/peermap.go b/tracker/models/peermap.go index 26e476b..0a24d76 100644 --- a/tracker/models/peermap.go +++ b/tracker/models/peermap.go @@ -7,6 +7,7 @@ package models import ( "net" "sync" + "sync/atomic" "github.com/chihaya/chihaya/config" "github.com/chihaya/chihaya/stats" @@ -18,6 +19,7 @@ type PeerMap struct { Peers map[string]map[PeerKey]Peer `json:"peers"` Seeders bool `json:"seeders"` Config config.SubnetConfig `json:"config"` + Size int32 sync.RWMutex } @@ -96,6 +98,10 @@ func (pm *PeerMap) Put(p Peer) { if !exists { pm.Peers[maskedIP] = make(map[PeerKey]Peer) } + _, exists = pm.Peers[maskedIP][p.Key()] + if !exists { + atomic.AddInt32(&(pm.Size), 1) + } pm.Peers[maskedIP][p.Key()] = p } @@ -105,19 +111,16 @@ func (pm *PeerMap) Delete(pk PeerKey) { defer pm.Unlock() maskedIP := pm.mask(pk.IP()) - delete(pm.Peers[maskedIP], pk) + _, exists := pm.Peers[maskedIP][pk] + if exists { + atomic.AddInt32(&(pm.Size), -1) + delete(pm.Peers[maskedIP], pk) + } } // Len returns the number of peers within a PeerMap. func (pm *PeerMap) Len() int { - pm.RLock() - defer pm.RUnlock() - - var count int - for _, subnetmap := range pm.Peers { - count += len(subnetmap) - } - return count + return int(atomic.LoadInt32(&pm.Size)) } // Purge iterates over all of the peers within a PeerMap and deletes them if @@ -129,6 +132,7 @@ func (pm *PeerMap) Purge(unixtime int64) { for _, subnetmap := range pm.Peers { for key, peer := range subnetmap { if peer.LastAnnounce <= unixtime { + atomic.AddInt32(&(pm.Size), -1) delete(subnetmap, key) if pm.Seeders { stats.RecordPeerEvent(stats.ReapedSeed, peer.HasIPv6())