store: add ErrResourceDoesNotExist and update memory implementation

This commit is contained in:
Leo Balduf 2016-05-01 17:56:07 -04:00
parent a081e5195b
commit 468eefee57
10 changed files with 81 additions and 29 deletions

View file

@ -21,30 +21,36 @@ type IPStore interface {
AddNetwork(network string) error AddNetwork(network string) error
// HasIP returns whether the given IP address is contained in the IPStore // HasIP returns whether the given IP address is contained in the IPStore
// or belong to any of the stored networks. // or belongs to any of the stored networks.
HasIP(ip net.IP) (bool, error) HasIP(ip net.IP) (bool, error)
// HasAnyIP returns whether any of the given IP addresses are contained in // HasAnyIP returns whether any of the given IP addresses are contained
// the IPStore or belong to any of the stored networks. // in the IPStore or belongs to any of the stored networks.
HasAnyIP(ips []net.IP) (bool, error) HasAnyIP(ips []net.IP) (bool, error)
// HassAllIPs returns whether all of the given IP addresses are contained in // HassAllIPs returns whether all of the given IP addresses are
// the IPStore or belong to any of the stored networks. // contained in the IPStore or belongs to any of the stored networks.
HasAllIPs(ips []net.IP) (bool, error) HasAllIPs(ips []net.IP) (bool, error)
// RemoveIP removes a single IP address from the IPStore. // RemoveIP removes a single IP address from the IPStore.
// //
// This wil not remove the given address from any networks it belongs to // This wil not remove the given address from any networks it belongs to
// that are stored in the IPStore. // that are stored in the IPStore.
//
// Returns ErrResourceDoesNotExist if the given IP address is not
// contained in the store.
RemoveIP(ip net.IP) error RemoveIP(ip net.IP) error
// RemoveNetwork removes a range of IP addresses that was previously added // RemoveNetwork removes a range of IP addresses that was previously
// through AddNetwork. // added through AddNetwork.
// //
// The given network must not, as a string, match the previously added // The given network must not, as a string, match the previously added
// network, but rather denote the same network, e.g. if the network // network, but rather denote the same network, e.g. if the network
// 192.168.22.255/24 was added, removing the network 192.168.22.123/24 // 192.168.22.255/24 was added, removing the network 192.168.22.123/24
// will succeed. // will succeed.
//
// Returns ErrResourceDoesNotExist if the given network is not
// contained in the store.
RemoveNetwork(network string) error RemoveNetwork(network string) error
} }

View file

@ -57,14 +57,14 @@ func key(ip net.IP) [16]byte {
} }
func (s *ipStore) AddNetwork(network string) error { func (s *ipStore) AddNetwork(network string) error {
s.Lock()
defer s.Unlock()
key, length, err := netmatch.ParseNetwork(network) key, length, err := netmatch.ParseNetwork(network)
if err != nil { if err != nil {
return err return err
} }
s.Lock()
defer s.Unlock()
return s.networks.Add(key, length) return s.networks.Add(key, length)
} }
@ -78,9 +78,9 @@ func (s *ipStore) AddIP(ip net.IP) error {
} }
func (s *ipStore) HasIP(ip net.IP) (bool, error) { func (s *ipStore) HasIP(ip net.IP) (bool, error) {
key := key(ip)
s.RLock() s.RLock()
defer s.RUnlock() defer s.RUnlock()
key := key(ip)
_, ok := s.ips[key] _, ok := s.ips[key]
if ok { if ok {
@ -138,22 +138,31 @@ func (s *ipStore) HasAllIPs(ips []net.IP) (bool, error) {
} }
func (s *ipStore) RemoveIP(ip net.IP) error { func (s *ipStore) RemoveIP(ip net.IP) error {
key := key(ip)
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
delete(s.ips, key(ip)) if _, ok := s.ips[key]; !ok {
return store.ErrResourceDoesNotExist
}
delete(s.ips, key)
return nil return nil
} }
func (s *ipStore) RemoveNetwork(network string) error { func (s *ipStore) RemoveNetwork(network string) error {
s.Lock()
defer s.Unlock()
key, length, err := netmatch.ParseNetwork(network) key, length, err := netmatch.ParseNetwork(network)
if err != nil { if err != nil {
return err return err
} }
return s.networks.Remove(key, length) s.Lock()
defer s.Unlock()
err = s.networks.Remove(key, length)
if err != nil && err == netmatch.ErrNotContained {
return store.ErrResourceDoesNotExist
}
return err
} }

View file

@ -9,6 +9,7 @@ import (
"testing" "testing"
"github.com/chihaya/chihaya/server/store" "github.com/chihaya/chihaya/server/store"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -64,7 +65,7 @@ func TestIPStore(t *testing.T) {
// check removes // check removes
err = s.RemoveIP(v6) err = s.RemoveIP(v6)
assert.Nil(t, err) assert.NotNil(t, err)
err = s.RemoveIP(v4s) err = s.RemoveIP(v4s)
assert.Nil(t, err) assert.Nil(t, err)

View file

@ -119,10 +119,16 @@ func (s *peerStore) DeleteSeeder(infoHash chihaya.InfoHash, p chihaya.Peer) erro
defer shard.Unlock() defer shard.Unlock()
if shard.peers[key] == nil { if shard.peers[key] == nil {
return nil return store.ErrResourceDoesNotExist
} }
delete(shard.peers[key], peerKey(p)) pk := peerKey(p)
if _, ok := shard.peers[key][pk]; !ok {
return store.ErrResourceDoesNotExist
}
delete(shard.peers[key], pk)
if len(shard.peers[key]) == 0 { if len(shard.peers[key]) == 0 {
delete(shard.peers, key) delete(shard.peers, key)
@ -156,10 +162,16 @@ func (s *peerStore) DeleteLeecher(infoHash chihaya.InfoHash, p chihaya.Peer) err
defer shard.Unlock() defer shard.Unlock()
if shard.peers[key] == nil { if shard.peers[key] == nil {
return nil return store.ErrResourceDoesNotExist
} }
delete(shard.peers[key], peerKey(p)) pk := peerKey(p)
if _, ok := shard.peers[key][pk]; !ok {
return store.ErrResourceDoesNotExist
}
delete(shard.peers[key], pk)
if len(shard.peers[key]) == 0 { if len(shard.peers[key]) == 0 {
delete(shard.peers, key) delete(shard.peers, key)

View file

@ -51,6 +51,10 @@ func (ss *stringStore) RemoveString(s string) error {
ss.Lock() ss.Lock()
defer ss.Unlock() defer ss.Unlock()
if _, ok := ss.strings[s]; !ok {
return store.ErrResourceDoesNotExist
}
delete(ss.strings, s) delete(ss.strings, s)
return nil return nil

View file

@ -5,9 +5,11 @@
package memory package memory
import ( import (
"github.com/chihaya/chihaya/server/store"
"github.com/stretchr/testify/assert"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/chihaya/chihaya/server/store"
) )
var ( var (
@ -30,7 +32,7 @@ func TestStringStore(t *testing.T) {
assert.False(t, has) assert.False(t, has)
err = ss.RemoveString(s1) err = ss.RemoveString(s1)
assert.Nil(t, err) assert.NotNil(t, err)
err = ss.PutString(s1) err = ss.PutString(s1)
assert.Nil(t, err) assert.Nil(t, err)

View file

@ -18,11 +18,17 @@ type PeerStore interface {
// PutSeeder adds a seeder for the infoHash to the PeerStore. // PutSeeder adds a seeder for the infoHash to the PeerStore.
PutSeeder(infoHash chihaya.InfoHash, p chihaya.Peer) error PutSeeder(infoHash chihaya.InfoHash, p chihaya.Peer) error
// DeleteSeeder removes a seeder for the infoHash from the PeerStore. // DeleteSeeder removes a seeder for the infoHash from the PeerStore.
//
// Returns ErrResourceDoesNotExist if the infoHash or peer does not
// exist.
DeleteSeeder(infoHash chihaya.InfoHash, p chihaya.Peer) error DeleteSeeder(infoHash chihaya.InfoHash, p chihaya.Peer) error
// PutLeecher adds a leecher for the infoHash to the PeerStore. // PutLeecher adds a leecher for the infoHash to the PeerStore.
PutLeecher(infoHash chihaya.InfoHash, p chihaya.Peer) error PutLeecher(infoHash chihaya.InfoHash, p chihaya.Peer) error
// DeleteLeecher removes a leecher for the infoHash from the PeerStore. // DeleteLeecher removes a leecher for the infoHash from the PeerStore.
//
// Returns ErrResourceDoesNotExist if the infoHash or peer does not
// exist.
DeleteLeecher(infoHash chihaya.InfoHash, p chihaya.Peer) error DeleteLeecher(infoHash chihaya.InfoHash, p chihaya.Peer) error
// GraduateLeecher promotes a peer from a leecher to a seeder for the // GraduateLeecher promotes a peer from a leecher to a seeder for the
@ -32,11 +38,11 @@ type PeerStore interface {
// announce. // announce.
// //
// If seeder is true then the peers returned will only be leechers, the // If seeder is true then the peers returned will only be leechers, the
// ammount of leechers returned will be the smaller value of numWant or the // ammount of leechers returned will be the smaller value of numWant or
// available leechers. // the available leechers.
// If it is false then seeders will be returned up until numWant or the // If it is false then seeders will be returned up until numWant or the
// available seeders, whichever is smaller. If the available seeders is less // available seeders, whichever is smaller. If the available seeders is
// than numWant then peers are returned until numWant or they run out. // less than numWant then peers are returned until numWant or they run out.
AnnouncePeers(infoHash chihaya.InfoHash, seeder bool, numWant int, peer4, peer6 chihaya.Peer) (peers, peers6 []chihaya.Peer, err error) AnnouncePeers(infoHash chihaya.InfoHash, seeder bool, numWant int, peer4, peer6 chihaya.Peer) (peers, peers6 []chihaya.Peer, err error)
// CollectGarbage deletes peers from the peerStore which are older than the // CollectGarbage deletes peers from the peerStore which are older than the
// cutoff time. // cutoff time.

View file

@ -23,6 +23,10 @@ func init() {
server.Register("store", constructor) server.Register("store", constructor)
} }
// ErrResourceDoesNotExist is the error returned by all delete methods in the
// store if the requested resource does not exist.
var ErrResourceDoesNotExist = errors.New("resource does not exist")
func constructor(srvcfg *chihaya.ServerConfig, tkr *tracker.Tracker) (server.Server, error) { func constructor(srvcfg *chihaya.ServerConfig, tkr *tracker.Tracker) (server.Server, error) {
if theStore == nil { if theStore == nil {
cfg, err := newConfig(srvcfg) cfg, err := newConfig(srvcfg)

View file

@ -10,8 +10,16 @@ var stringStoreDrivers = make(map[string]StringStoreDriver)
// StringStore represents an interface for manipulating strings. // StringStore represents an interface for manipulating strings.
type StringStore interface { type StringStore interface {
// PutString adds the given string to the StringStore.
PutString(s string) error PutString(s string) error
// HasString returns whether or not the StringStore contains the given
// string.
HasString(s string) (bool, error) HasString(s string) (bool, error)
// RemoveString removes the string from the string store.
// Returns ErrResourceDoesNotExist if the given string is not contained
// in the store.
RemoveString(s string) error RemoveString(s string) error
} }

View file

@ -8,8 +8,8 @@ package tracker
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/chihaya/chihaya" "github.com/chihaya/chihaya"
) )