aerc/worker/imap/seqmap.go
Tim Culverhouse fb5558da81 seqmap: sync seqNum to uid after expunge
This patch updates the seqNums after an Expunge operation. When an
expunge operation occurs, the seqNum of the deleted message is reported.
The Imap spec [0] states that an immediate decrement of all seqnums greater
than the deleted occurs, even before the next reporting of an expunge
update.

[0]: https://datatracker.ietf.org/doc/html/rfc3501#section-7.4.1

Fixes: https://todo.sr.ht/~rjarry/aerc/61
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
2022-07-24 23:06:10 +02:00

60 lines
1 KiB
Go

package imap
import (
"sync"
)
type SeqMap struct {
lock sync.Mutex
// map of IMAP sequence numbers to message UIDs
m map[uint32]uint32
}
func (s *SeqMap) Size() int {
s.lock.Lock()
size := len(s.m)
s.lock.Unlock()
return size
}
func (s *SeqMap) Get(seqnum uint32) (uint32, bool) {
s.lock.Lock()
uid, found := s.m[seqnum]
s.lock.Unlock()
return uid, found
}
func (s *SeqMap) Put(seqnum, uid uint32) {
s.lock.Lock()
if s.m == nil {
s.m = make(map[uint32]uint32)
}
s.m[seqnum] = uid
s.lock.Unlock()
}
func (s *SeqMap) Pop(seqnum uint32) (uint32, bool) {
s.lock.Lock()
uid, found := s.m[seqnum]
if found {
m := make(map[uint32]uint32)
for s, u := range s.m {
if s > seqnum {
// All sequence numbers greater than the removed one must be decremented by one
// https://datatracker.ietf.org/doc/html/rfc3501#section-7.4.1
m[s-1] = u
} else if s < seqnum {
m[s] = u
}
}
s.m = m
}
s.lock.Unlock()
return uid, found
}
func (s *SeqMap) Clear() {
s.lock.Lock()
s.m = make(map[uint32]uint32)
s.lock.Unlock()
}