✨ Improve SequenceSet with Set, Range, Enumerable methods #239
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The version of SequenceSet in net-imap prior to this PR is merely a placeholder, needed in order to complete
tagged-extfor #225.This updates it with a full API, inspired by Set, Range, and Array. This allows it to be more broadly useful, e.g. for storing and working with mailbox state. A better API for working with
sequence-setis also a prerequisite for properly supportingESEARCH(#115, #121). NOTE: The API added here is documented as experimental, but I'd like to remove that label when v0.5.0 is released.In addition to Integer, Range, and enumerables, any object with
#to_sequence_setcan now be used to create a sequence set. For compatibility with MessageSet,ThreadMember#to_sequence_setcollects all child seqno into a SequenceSet.Because mailbox state can be very large, inputs are stored in an internal sorted array of ranges. These are stored as
[start, stop]tuples, not Range objects, for simpler manipulation. A future optimization could convert all tuples to a flat one-dimensional Array (to reduce object allocations). Storing the data in sorted range tuples allows many of the important operations to beO(lg n).Although updates do use
Array#insertandArray#slice!—which are technicallyO(n)—they tend to be fast until the number of elements is very large. Count and index-based methods are alsoO(n). A future optimization could cache the count and compose larger sets from a balanced tree of smaller sets, to preserveO(lg n)for most operations.SequenceSet will be used to replace MessageSet (which is used internally to validate, format, and send certain command args). Some notable differences between the two:
sequence-setbug has been fixed.TODO list:
For now, everything except for
::[]and#valid_stringis marked as "experimental". I don't expect any big changes though.::[]to create a validated immutable sequence set::try_convertto safely coerce other objects into SequenceSetSequenceSet#to_sequence_set-- itselfMessageSet#validate#send_dataThreadMember#to_sequence_set#==#eql?and#hash#===#cover?#include?,#member?#include_star?#intersect?#disjoint?#empty?#valid?-- i.e: not empty#full?SetAPI#replace#complement!#addand#<<#add?#merge#clear#delete#delete?#subtract#limit!SetAPI#freezelhs + rhs,lhs | rhs(#union)lhs - rhs(#difference)lhs & rhs(#intersection)lhs ^ rhs(#xor)~set(#complement)#limit#elements,#to_a#each_element#ranges#each_range#numbers#each_number#to_setmin,max,minmax#count#at#[],#slice#slice!: remove a number or numbers at a given index or indices#find_index: get the index of a number in the set#delete_at: remove a number or numbers at a given index or indices#valid_string- raises an exception when the set is empty#string- isnilwhen the set is empty#string=- can be set tonilto clear the set#to_s- is empty string when empty#normalize,normalize!#inspect- special cases for frozen and emptyO(lg n)performance.TODO (later):
#pretty_print#find_index_lte,#find_index_gteMessageSet.