From c08b895851001efe6a014bd20612128feb7b9de3 Mon Sep 17 00:00:00 2001
From: Juan Batiz-Benet <juan@benet.ai>
Date: Tue, 16 Sep 2014 05:06:27 -0700
Subject: [PATCH] Peerstore - threadsafe peer collection

will have persistence later on as a datastore passed in.
---
 peer/peerstore.go | 86 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 peer/peerstore.go

diff --git a/peer/peerstore.go b/peer/peerstore.go
new file mode 100644
index 00000000..b41ee1eb
--- /dev/null
+++ b/peer/peerstore.go
@@ -0,0 +1,86 @@
+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)
+	Add(*Peer) error
+	Remove(ID) error
+	All() (*map[u.Key]*Peer, error)
+}
+
+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()
+
+	val, err := p.peers.Get(ds.NewKey(string(i)))
+	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
+}
+
+func (p *peerstore) Add(peer *Peer) error {
+	p.Lock()
+	defer p.Unlock()
+
+	k := ds.NewKey(string(peer.ID))
+	return p.peers.Put(k, peer)
+}
+
+func (p *peerstore) Remove(i ID) error {
+	p.Lock()
+	defer p.Unlock()
+
+	k := ds.NewKey(string(i))
+	return p.peers.Delete(k)
+}
+
+func (p *peerstore) All() (*map[u.Key]*Peer, error) {
+	p.RLock()
+	defer p.RUnlock()
+
+	l, err := p.peers.KeyList()
+	if err != nil {
+		return nil, err
+	}
+
+	ps := &map[u.Key]*Peer{}
+	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
+}
-- 
GitLab