package memory import ( "sync" "time" peering "forge.cadoles.com/wpetit/go-http-peering" ) type Store struct { peers map[peering.PeerID]*peering.Peer mutex sync.RWMutex } func (s *Store) Create(id peering.PeerID, attrs peering.PeerAttributes) (*peering.Peer, error) { s.mutex.Lock() defer s.mutex.Unlock() if _, exists := s.peers[id]; exists { return nil, peering.ErrPeerExists } peer := &peering.Peer{ PeerHeader: peering.PeerHeader{ ID: id, Status: peering.StatusPending, }, Attributes: attrs, } s.peers[id] = peer return copy(peer), nil } func (s *Store) Get(id peering.PeerID) (*peering.Peer, error) { s.mutex.RLock() defer s.mutex.RUnlock() peer, exists := s.peers[id] if !exists { return nil, peering.ErrPeerNotFound } return copy(peer), nil } func (s *Store) List() ([]peering.PeerHeader, error) { s.mutex.RLock() defer s.mutex.RUnlock() headers := make([]peering.PeerHeader, len(s.peers)) i := 0 for _, p := range s.peers { headers[i] = p.PeerHeader i++ } return headers, nil } func (s *Store) UpdateAttributes(id peering.PeerID, attrs peering.PeerAttributes) error { s.mutex.Lock() defer s.mutex.Unlock() peer, exists := s.peers[id] if !exists { return peering.ErrPeerNotFound } peer.Attributes = attrs return nil } func (s *Store) UpdateLastContact(id peering.PeerID, remoteAddress string, ts time.Time) error { s.mutex.Lock() defer s.mutex.Unlock() peer, exists := s.peers[id] if !exists { return peering.ErrPeerNotFound } peer.LastAddress = remoteAddress peer.LastContact = ts return nil } func (s *Store) UpdatePublicKey(id peering.PeerID, publicKey []byte) error { s.mutex.Lock() defer s.mutex.Unlock() peer, exists := s.peers[id] if !exists { return peering.ErrPeerNotFound } peer.PublicKey = publicKey return nil } func (s *Store) Delete(id peering.PeerID) error { s.mutex.Lock() defer s.mutex.Unlock() if _, exists := s.peers[id]; !exists { return peering.ErrPeerNotFound } delete(s.peers, id) return nil } func (s *Store) Accept(id peering.PeerID) error { return s.updateStatus(id, peering.StatusPeered) } func (s *Store) Forget(id peering.PeerID) error { return s.updateStatus(id, peering.StatusPending) } func (s *Store) Reject(id peering.PeerID) error { return s.updateStatus(id, peering.StatusRejected) } func (s *Store) updateStatus(id peering.PeerID, status peering.PeerStatus) error { s.mutex.Lock() defer s.mutex.Unlock() peer, exists := s.peers[id] if !exists { return peering.ErrPeerNotFound } peer.Status = status return nil } func NewStore() *Store { return &Store{ peers: make(map[peering.PeerID]*peering.Peer), } } func copy(p *peering.Peer) *peering.Peer { copy := *p return © }