@cryptotaxi247 / kubo / commits / 1e007791a

refactor(peer) impl peerstore with map

License: MIT Signed-off-by: Brian Tiger Chow <brian@perfmode.com>

Brian Tiger Chow committed Dec 8, 2014 at 00:25 UTC 1e007791a56aeb542f52ba045eed91ee97c5a11c
1 file changed +29 -78
peer/peerstore.go
+29 -78
@@ -1,12 +1,9 @@
1 package peer
2
3 import (
4 - "errors"
4 "sync"
5
6 u "github.com/jbenet/go-ipfs/util"
8 -
9 - ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
7 )
8
9 // Peerstore provides a threadsafe collection for peers.
@@ -19,34 +16,26 @@ type Peerstore interface {
16
17 type peerstore struct {
18 sync.RWMutex
22 - peers ds.Datastore
19 + data map[string]Peer // key is string(ID)
20 }
21
22 // NewPeerstore creates a threadsafe collection of peers.
23 func NewPeerstore() Peerstore {
24 return &peerstore{
28 - peers: ds.NewMapDatastore(),
25 + data: make(map[string]Peer),
26 }
27 }
28
32 -func (p *peerstore) Get(i ID) (Peer, error) {
33 - p.Lock()
34 - defer p.Unlock()
29 +func (ps *peerstore) Get(i ID) (Peer, error) {
30 + ps.Lock()
31 + defer ps.Unlock()
32
33 if i == nil {
34 panic("wat")
35 }
36
40 - k := u.Key(i).DsKey()
41 - val, err := p.peers.Get(k)
42 - switch err {
43 -
44 - // some other datastore error
45 - default:
46 - return nil, err
47 -
48 - // not found, construct it ourselves, add it to datastore, and return.
49 - case ds.ErrNotFound:
37 + p, ok := ps.data[i.String()]
38 + if !ok { // not found, construct it ourselves, add it to datastore, and return.
39
40 // TODO(brian) kinda dangerous, no? If ID is invalid and doesn't
41 // correspond to an actual valid peer ID, this peerstore will return an
@@ -57,84 +46,46 @@ func (p *peerstore) Get(i ID) (Peer, error) {
46 //
47 // Potential bad case: Suppose values arrive from untrusted providers
48 // in the DHT.
60 -
61 - peer := &peer{id: i}
62 - if err := p.peers.Put(k, peer); err != nil {
63 - return nil, err
64 - }
65 - return peer, nil
49 + p = &peer{id: i}
50 + ps.data[i.String()] = p
51 + }
52
53 // no error, got it back fine
68 - case nil:
69 - peer, ok := val.(*peer)
70 - if !ok {
71 - return nil, errors.New("stored value was not a Peer")
72 - }
73 - return peer, nil
74 - }
54 + return p, nil
55 }
56
57 func (p *peerstore) Add(peer Peer) (Peer, error) {
58 p.Lock()
59 defer p.Unlock()
60
81 - k := peer.Key().DsKey()
82 - val, err := p.peers.Get(k)
83 - switch err {
84 - // some other datastore error
85 - default:
86 - return nil, err
87 -
88 - // not found? just add and return.
89 - case ds.ErrNotFound:
90 - err := p.peers.Put(k, peer)
91 - return peer, err
92 -
93 - // no error, already here.
94 - case nil:
95 - peer2, ok := val.(Peer)
96 - if !ok {
97 - return nil, errors.New("stored value was not a Peer")
98 - }
99 -
100 - if peer == peer2 {
101 - return peer, nil
102 - }
103 -
104 - // must do some merging.
105 - peer2.Update(peer)
106 - return peer2, nil
61 + existing, ok := p.data[peer.Key().String()]
62 + if !ok { // not found? just add and return.
63 + p.data[peer.Key().String()] = peer
64 + return peer, nil
65 + }
66 + // already here.
67 + if peer == existing {
68 + return peer, nil
69 }
70 + existing.Update(peer) // must do some merging.
71 + return existing, nil
72 }
73
74 func (p *peerstore) Delete(i ID) error {
75 p.Lock()
76 defer p.Unlock()
77
114 - k := u.Key(i).DsKey()
115 - return p.peers.Delete(k)
78 + delete(p.data, i.String())
79 + return nil
80 }
81
82 func (p *peerstore) All() (*Map, error) {
119 - p.RLock()
120 - defer p.RUnlock()
121 -
122 - l, err := p.peers.KeyList()
123 - if err != nil {
124 - return nil, err
125 - }
83 + p.Lock()
84 + defer p.Unlock()
85
127 - ps := &Map{}
128 - for _, k := range l {
129 - val, err := p.peers.Get(k)
130 - if err != nil {
131 - continue
132 - }
133 -
134 - pval, ok := val.(*peer)
135 - if ok {
136 - (*ps)[pval.Key()] = pval
137 - }
86 + ps := Map{}
87 + for k, v := range p.data {
88 + ps[u.Key(k)] = v
89 }
139 - return ps, nil
90 + return &ps, nil
91 }