1package main
2
3import (
4 "errors"
5 "sync"
6)
7
8type MailPair struct {
9 old, new *Mail
10}
11
12type MailDatabase struct {
13 msgMtx *sync.Mutex
14
15 newMsgs []*Mail
16 modMsgs []*MailPair
17 oldMsgs map[string]*Mail
18}
19
20func NewMailDatabase() *MailDatabase {
21 db := new(MailDatabase)
22 db.msgMtx = new(sync.Mutex)
23 db.oldMsgs = make(map[string]*Mail)
24 return db
25}
26
27func (db *MailDatabase) AddOldMessage(mail *Mail) error {
28 csum, err := mail.Checksum()
29 if err != nil {
30 return err
31 }
32
33 db.msgMtx.Lock()
34 defer db.msgMtx.Unlock()
35
36 if _, ok := db.oldMsgs[csum]; ok {
37 return errors.New("hash collision")
38 }
39 db.oldMsgs[csum] = mail
40
41 return nil
42}
43
44func (db *MailDatabase) GetOldMessage(mail *Mail) (*Mail, error) {
45 csum, err := mail.Checksum()
46 if err != nil {
47 return nil, err
48 }
49
50 db.msgMtx.Lock()
51 defer db.msgMtx.Unlock()
52
53 mail, ok := db.oldMsgs[csum]
54 if !ok {
55 return nil, nil
56 }
57
58 return mail, nil
59}
60
61func (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}