peerstore.go 1.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
package peer

import (
	"errors"
	"sync"

	u "github.com/jbenet/go-ipfs/util"

	ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
)

// Peerstore provides a threadsafe collection for peers.
type Peerstore interface {
	Get(ID) (*Peer, error)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
15 16 17
	Put(*Peer) error
	Delete(ID) error
	All() (*Map, error)
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
}

type peerstore struct {
	sync.RWMutex
	peers ds.Datastore
}

// NewPeerstore creates a threadsafe collection of peers.
func NewPeerstore() Peerstore {
	return &peerstore{
		peers: ds.NewMapDatastore(),
	}
}

func (p *peerstore) Get(i ID) (*Peer, error) {
	p.RLock()
	defer p.RUnlock()

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
36 37
	k := ds.NewKey(string(i))
	val, err := p.peers.Get(k)
38 39 40 41 42 43 44 45 46 47 48
	if err != nil {
		return nil, err
	}

	peer, ok := val.(*Peer)
	if !ok {
		return nil, errors.New("stored value was not a Peer")
	}
	return peer, nil
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
49
func (p *peerstore) Put(peer *Peer) error {
50 51 52 53 54 55 56
	p.Lock()
	defer p.Unlock()

	k := ds.NewKey(string(peer.ID))
	return p.peers.Put(k, peer)
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
57
func (p *peerstore) Delete(i ID) error {
58 59 60 61 62 63 64
	p.Lock()
	defer p.Unlock()

	k := ds.NewKey(string(i))
	return p.peers.Delete(k)
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
65
func (p *peerstore) All() (*Map, error) {
66 67 68 69 70 71 72 73
	p.RLock()
	defer p.RUnlock()

	l, err := p.peers.KeyList()
	if err != nil {
		return nil, err
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
74
	ps := &Map{}
75 76 77 78 79 80 81 82 83 84 85 86 87
	for _, k := range l {
		val, err := p.peers.Get(k)
		if err != nil {
			continue
		}

		pval, ok := val.(*Peer)
		if ok {
			(*ps)[u.Key(k.String())] = pval
		}
	}
	return ps, nil
}