File: move.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 (130 lines) | stat: -rw-r--r-- 3,255 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
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())
}