summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--worker/imap/seqmap.go16
-rw-r--r--worker/imap/seqmap_test.go9
2 files changed, 20 insertions, 5 deletions
diff --git a/worker/imap/seqmap.go b/worker/imap/seqmap.go
index 2752cc8..093bbc5 100644
--- a/worker/imap/seqmap.go
+++ b/worker/imap/seqmap.go
@@ -1,6 +1,8 @@
package imap
-import "sync"
+import (
+ "sync"
+)
type SeqMap struct {
lock sync.Mutex
@@ -35,7 +37,17 @@ func (s *SeqMap) Pop(seqnum uint32) (uint32, bool) {
s.lock.Lock()
uid, found := s.m[seqnum]
if found {
- delete(s.m, seqnum)
+ 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
diff --git a/worker/imap/seqmap_test.go b/worker/imap/seqmap_test.go
index 0ee0738..0fa8711 100644
--- a/worker/imap/seqmap_test.go
+++ b/worker/imap/seqmap_test.go
@@ -39,12 +39,15 @@ func TestSeqMap(t *testing.T) {
assert.Equal(found, true)
assert.Equal(seqmap.Size(), 2)
+ // Repop the same seqnum should work because of the syncing
_, found = seqmap.Pop(1)
- assert.Equal(found, false)
- assert.Equal(seqmap.Size(), 2)
+ assert.Equal(found, true)
+ assert.Equal(seqmap.Size(), 1)
+ // sync means we already have a 1. This is replacing that UID so the size
+ // shouldn't increase
seqmap.Put(1, 7331)
- assert.Equal(seqmap.Size(), 3)
+ assert.Equal(seqmap.Size(), 1)
seqmap.Clear()
assert.Equal(seqmap.Size(), 0)