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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
package imap_benchmarks
import (
"context"
"flag"
"fmt"
"net"
"github.com/ProtonMail/gluon/benchmarks/gluon_bench/benchmark"
"github.com/ProtonMail/gluon/benchmarks/gluon_bench/flags"
"github.com/bradenaw/juniper/xslices"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
)
var (
moveListFlag = flag.String("imap-move-list", "", "Use a list of predefined sequences to move rather than random generated.")
moveAllFlag = flag.Bool("imap-move-all", false, "If set, perform a move of the all messages.")
moveIntoSameDstFlag = flag.Bool("imap-move-into-same-dst", false, "If set, rather than moving each unique mailbox into separate unique mailboxes, move all messages into one common destination mailbox.")
)
type Move struct {
*stateTracker
seqSets *ParallelSeqSet
srcMailboxes []string
dstMailboxes []string
}
func NewMove() benchmark.Benchmark {
return NewIMAPBenchmarkRunner(&Move{stateTracker: newStateTracker()})
}
func (*Move) Name() string {
return "imap-move"
}
func (m *Move) Setup(ctx context.Context, addr net.Addr) error {
if *flags.IMAPMessageCount == 0 {
return fmt.Errorf("move benchmark requires a message count > 0")
}
return WithClient(addr, func(cl *client.Client) error {
m.srcMailboxes = make([]string, 0, *flags.IMAPParallelClients)
m.dstMailboxes = make([]string, 0, *flags.IMAPParallelClients)
for i := uint(0); i < *flags.IMAPParallelClients; i++ {
mbox, err := m.createAndFillRandomMBox(cl)
if err != nil {
return err
}
m.srcMailboxes = append(m.srcMailboxes, mbox)
}
var dstMboxCount uint
if *moveIntoSameDstFlag {
dstMboxCount = 1
} else {
dstMboxCount = *flags.IMAPParallelClients
}
for i := uint(0); i < dstMboxCount; i++ {
mbox, err := m.createRandomMBox(cl)
if err != nil {
return err
}
m.dstMailboxes = append(m.dstMailboxes, mbox)
}
seqSets, err := NewParallelSeqSet(uint32(*flags.IMAPMessageCount),
*flags.IMAPParallelClients,
*moveListFlag,
*moveAllFlag,
*flags.IMAPRandomSeqSetIntervals,
true,
*flags.IMAPUIDMode)
if err != nil {
return err
}
m.seqSets = seqSets
return nil
})
}
func (m *Move) TearDown(ctx context.Context, addr net.Addr) error {
return m.cleanupWithAddr(addr)
}
func (m *Move) Run(ctx context.Context, addr net.Addr) error {
mboxInfos := xslices.Map(m.srcMailboxes, func(name string) MailboxInfo {
return MailboxInfo{
Name: name,
ReadOnly: true,
}
})
RunParallelClientsWithMailboxes(addr, mboxInfos, func(cl *client.Client, index uint) {
var moveFn func(*client.Client, *imap.SeqSet, string) error
if *flags.IMAPUIDMode {
moveFn = func(cl *client.Client, set *imap.SeqSet, mailbox string) error {
return cl.UidMove(set, mailbox)
}
} else {
moveFn = func(cl *client.Client, set *imap.SeqSet, mailbox string) error {
return cl.Move(set, mailbox)
}
}
for _, v := range m.seqSets.Get(index) {
if *moveIntoSameDstFlag {
if err := moveFn(cl, v, m.dstMailboxes[0]); err != nil {
panic(err)
}
} else {
if err := moveFn(cl, v, m.dstMailboxes[index]); err != nil {
panic(err)
}
}
}
})
return nil
}
func init() {
benchmark.RegisterBenchmark(NewMove())
}
|