File: message_hashmap.go

package info (click to toggle)
golang-github-protonmail-gluon 0.17.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 16,020 kB
  • sloc: sh: 55; makefile: 5
file content (57 lines) | stat: -rw-r--r-- 1,301 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package utils

import (
	"sync"

	"github.com/ProtonMail/gluon/imap"
	"github.com/ProtonMail/gluon/rfc822"
)

// MessageHashesMap tracks the hashes for a literal and it's associated internal IMAP ID.
type MessageHashesMap struct {
	lock     sync.Mutex
	idToHash map[imap.InternalMessageID]string
	hashes   map[string]struct{}
}

func NewMessageHashesMap() *MessageHashesMap {
	return &MessageHashesMap{
		idToHash: make(map[imap.InternalMessageID]string),
		hashes:   make(map[string]struct{}),
	}
}

// Insert inserts the hash of the current message literal into the map and return true if an existing value was already
// present.
func (m *MessageHashesMap) Insert(id imap.InternalMessageID, literal []byte) (bool, error) {
	literalHashStr, err := rfc822.GetMessageHash(literal)
	if err != nil {
		return false, err
	}

	m.lock.Lock()
	defer m.lock.Unlock()

	if _, ok := m.hashes[literalHashStr]; ok {
		return true, nil
	}

	m.idToHash[id] = literalHashStr
	m.hashes[literalHashStr] = struct{}{}

	return false, nil
}

// Erase removes the info associated with a given id.
func (m *MessageHashesMap) Erase(ids ...imap.InternalMessageID) {
	m.lock.Lock()
	defer m.lock.Unlock()

	for _, id := range ids {
		if v, ok := m.idToHash[id]; ok {
			delete(m.hashes, v)
		}

		delete(m.idToHash, id)
	}
}