1package main23import (4 "errors"5 "sync"6)78type MailPair struct {9 old, new *Mail10}1112type MailDatabase struct {13 msgMtx *sync.Mutex1415 newMsgs []*Mail16 modMsgs []*MailPair17 oldMsgs map[string]*Mail18}1920func NewMailDatabase() *MailDatabase {21 db := new(MailDatabase)22 db.msgMtx = new(sync.Mutex)23 db.oldMsgs = make(map[string]*Mail)24 return db25}2627func (db *MailDatabase) AddOldMessage(mail *Mail) error {28 csum, err := mail.Checksum()29 if err != nil {30 return err31 }3233 db.msgMtx.Lock()34 defer db.msgMtx.Unlock()3536 if _, ok := db.oldMsgs[csum]; ok {37 return errors.New("hash collision")38 }39 db.oldMsgs[csum] = mail4041 return nil42}4344func (db *MailDatabase) GetOldMessage(mail *Mail) (*Mail, error) {45 csum, err := mail.Checksum()46 if err != nil {47 return nil, err48 }4950 db.msgMtx.Lock()51 defer db.msgMtx.Unlock()5253 mail, ok := db.oldMsgs[csum]54 if !ok {55 return nil, nil56 }5758 return mail, nil59}6061func (db *MailDatabase) AddNewMessage(old *Mail, new *Mail) {62 db.msgMtx.Lock()63 if old == nil {64 db.newMsgs = append(db.newMsgs, new)65 } else {66 db.modMsgs = append(db.modMsgs, &MailPair{old, new})67 }68 db.msgMtx.Unlock()69}