From a0f46d92e3434b88a62b5e592299a400e9d72825 Mon Sep 17 00:00:00 2001 From: nick evans Date: Sun, 27 Sep 2026 13:29:17 -0400 Subject: [PATCH 1/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20`SequenceSe?= =?UTF-8?q?t#at`=20and=20`#ordered=5Fat`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This extracts a private inner API layer for number indexing and does the input/output conversion in the public API layer. The private API will be more convenient to work with internally, since we don't need to worry about accidentally comparing integers to `:*`. This comes at the small cost of some duplication. That duplication is considered less important here because 1) it's very simple, and 2) the implementations may drift apart: * `#at` converts _indexable_ runs into indexable nums, * `#ordered_at` converts _enumerable_ runs into indexable nums. --- lib/net/imap/sequence_set.rb | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/net/imap/sequence_set.rb b/lib/net/imap/sequence_set.rb index 827d331fe..054858b4c 100644 --- a/lib/net/imap/sequence_set.rb +++ b/lib/net/imap/sequence_set.rb @@ -1720,7 +1720,7 @@ def find_ordered_index(number) # # Related: #[], #slice, #ordered_at def at(index) - seek_number_in_minmaxes(minmaxes, index) + export_num sorted_set_num_at Integer index.to_int end # :call-seq: ordered_at(index) -> integer or nil @@ -1733,7 +1733,7 @@ def at(index) # # Related: #[], #slice, #ordered_at def ordered_at(index) - seek_number_in_minmaxes(each_entry_minmax, index) + export_num ordered_list_num_at Integer index.to_int end # :call-seq: @@ -2377,15 +2377,22 @@ def bsearch_range(num) = (min, max = bsearch_minmax(num)) && (min..max) ######################################################################{{{2 # Number indexing methods + def sorted_set_num_at(index) + seek_number_in_minmaxes(minmaxes, index) + end + + def ordered_list_num_at(index) + seek_number_in_minmaxes(each_entry_minmax, index) + end + def seek_number_in_minmaxes(minmaxes, index) - index = Integer(index.to_int) if index.negative? reverse_each_minmax_with_index(minmaxes) do |min, max, idx_min, idx_max| - idx_min <= index and return export_num(min + (index - idx_min)) + idx_min <= index and return min + (index - idx_min) end else each_minmax_with_index(minmaxes) do |min, _, idx_min, idx_max| - index <= idx_max and return export_num(min + (index - idx_min)) + index <= idx_max and return min + (index - idx_min) end end nil From bb3db985b65a5f8876e5fe00972c4ee82ca86ec6 Mon Sep 17 00:00:00 2001 From: nick evans Date: Sun, 27 Sep 2026 15:57:02 -0400 Subject: [PATCH 2/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20`SequenceSe?= =?UTF-8?q?t#slice`=20internals?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/net/imap/sequence_set.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/net/imap/sequence_set.rb b/lib/net/imap/sequence_set.rb index 054858b4c..0b7e59ace 100644 --- a/lib/net/imap/sequence_set.rb +++ b/lib/net/imap/sequence_set.rb @@ -2421,8 +2421,8 @@ def slice_length(start, length) start = Integer(start.to_int) length = Integer(length.to_int) raise ArgumentError, "length must be positive" unless length.positive? - last = start + length - 1 unless start.negative? && start.abs <= length - slice_range(start..last) + stop = start + length unless start.negative? && start.abs <= length + slice_range(start...stop) end def slice_range(range) From 4bf5bb4b6e348470cafd122baa367febb32c75e1 Mon Sep 17 00:00:00 2001 From: nick evans Date: Mon, 28 Sep 2026 11:35:32 -0400 Subject: [PATCH 3/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Don't=20special-case?= =?UTF-8?q?=20`SequenceSet[start...2**32]`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since `set[2**32]` will _always_ be out of bounds, this makes no difference to the semantics. And it should have no effect on performance. Future performance optimizations can special case when we _know_ we must be scanning to the end, but that would check for `STAR_INT <= last`. --- lib/net/imap/sequence_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/net/imap/sequence_set.rb b/lib/net/imap/sequence_set.rb index 0b7e59ace..28a51fc9c 100644 --- a/lib/net/imap/sequence_set.rb +++ b/lib/net/imap/sequence_set.rb @@ -2430,7 +2430,7 @@ def slice_range(range) last = range.end || -1 if range.exclude_end? return remain_frozen_empty if last.zero? - last -= 1 if range.end && last != STAR_INT + last -= 1 if range.end end if (first * last).positive? && last < first remain_frozen_empty