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
}