Skip to content

Remove all usage of ImapSet in Protocol

ImapSet is a relict of the old days when Akonadi still had an IMAP-like text-based protocol and so ImapSet was used to pass a set of independent contiguous ID ranges via the protocol (same as e.g. UID FETCH in IMAP). We kept the ImapSet during the switch to the binary protocol, even though it brings us barely any benefit at a cost of more complex processing. This change replaces the ImapSet (+ImapInterval) usage in Akonadi with a simple QList. This have simplified handling of the IDs in many places across the code.

Additional problem that we were facing was the SQL: we were converting the ImapSet into a complex WHERE condition like

(id >= 1 AND id <= 4) OR (id == 6) OR (id >= 8 AND id <= 12) ...

This is very expensive to build and sometimes we hit an upper limit on the maximum complexity of a WHERE condition supported by SQL engines (especially SQLite). With a list we can very cheaply convert that into SQL "IN" condition, which is also probably faster to optimize and evaluate.

This also discovered a few small bugs that worked "by accident" especially around handling root collection (ID) that has worked only as a side-effect of how the ImapSet worked, but those cases are now handled properly in the code.

Finally, the ImapSet and ImapInterval, sadly, cannot be removed yet completely, since they are still used to (de)serialize some Item and Collection attributes. If we can ever migrate those to some other format (like JSON), we could most likely remove those too, although there's no hurry at this point.

Merge request reports