github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/peer/peerstore.go (about) 1 package peer 2 3 import ( 4 "errors" 5 "sync" 6 7 u "github.com/jbenet/go-ipfs/util" 8 9 ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore" 10 ) 11 12 // Peerstore provides a threadsafe collection for peers. 13 type Peerstore interface { 14 Get(ID) (Peer, error) 15 Add(Peer) (Peer, error) 16 Delete(ID) error 17 All() (*Map, error) 18 } 19 20 type peerstore struct { 21 sync.RWMutex 22 peers ds.Datastore 23 } 24 25 // NewPeerstore creates a threadsafe collection of peers. 26 func NewPeerstore() Peerstore { 27 return &peerstore{ 28 peers: ds.NewMapDatastore(), 29 } 30 } 31 32 func (p *peerstore) Get(i ID) (Peer, error) { 33 p.Lock() 34 defer p.Unlock() 35 36 if i == nil { 37 panic("wat") 38 } 39 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: 50 peer := &peer{id: i} 51 if err := p.peers.Put(k, peer); err != nil { 52 return nil, err 53 } 54 return peer, nil 55 56 // no error, got it back fine 57 case nil: 58 peer, ok := val.(*peer) 59 if !ok { 60 return nil, errors.New("stored value was not a Peer") 61 } 62 return peer, nil 63 } 64 } 65 66 func (p *peerstore) Add(peer Peer) (Peer, error) { 67 p.Lock() 68 defer p.Unlock() 69 70 k := peer.Key().DsKey() 71 val, err := p.peers.Get(k) 72 switch err { 73 // some other datastore error 74 default: 75 return nil, err 76 77 // not found? just add and return. 78 case ds.ErrNotFound: 79 err := p.peers.Put(k, peer) 80 return peer, err 81 82 // no error, already here. 83 case nil: 84 peer2, ok := val.(Peer) 85 if !ok { 86 return nil, errors.New("stored value was not a Peer") 87 } 88 89 if peer == peer2 { 90 return peer, nil 91 } 92 93 // must do some merging. 94 peer2.Update(peer) 95 return peer2, nil 96 } 97 } 98 99 func (p *peerstore) Delete(i ID) error { 100 p.Lock() 101 defer p.Unlock() 102 103 k := u.Key(i).DsKey() 104 return p.peers.Delete(k) 105 } 106 107 func (p *peerstore) All() (*Map, error) { 108 p.RLock() 109 defer p.RUnlock() 110 111 l, err := p.peers.KeyList() 112 if err != nil { 113 return nil, err 114 } 115 116 ps := &Map{} 117 for _, k := range l { 118 val, err := p.peers.Get(k) 119 if err != nil { 120 continue 121 } 122 123 pval, ok := val.(*peer) 124 if ok { 125 (*ps)[pval.Key()] = pval 126 } 127 } 128 return ps, nil 129 }