Class: Karafka::Web::Ui::Lib::Paginations::Paginators::Sets
- Defined in:
- lib/karafka/web/ui/lib/paginations/paginators/sets.rb
Overview
Paginator that allows us to take several lists/sets and iterate over them in a round-robin fashion.
It does not have to iterate over all the elements from each set for higher pages making it much more effective than the naive implementation.
Class Method Summary collapse
-
.call(counts, current_page) ⇒ Hash<Integer, Range>
Hash with integer keys indicating the count location and the range needed to be taken of elements (counting backwards) for each partition.
Methods inherited from Base
Class Method Details
.call(counts, current_page) ⇒ Hash<Integer, Range>
Returns hash with integer keys indicating the count location and the range needed to be taken of elements (counting backwards) for each partition.
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 |
# File 'lib/karafka/web/ui/lib/paginations/paginators/sets.rb', line 21 def call(counts, current_page) return {} if current_page < 1 lists = counts.dup.map.with_index { |el, i| [i, el] } curr_item_index = 0 curr_list_index = 0 items_to_skip_count = per_page * (current_page - 1) loop do lists_count = lists.length return {} if lists_count.zero? shortest_list_count = lists.map(&:last).min mover = (shortest_list_count - curr_item_index) items_we_are_considering_count = lists_count * mover if items_we_are_considering_count >= items_to_skip_count curr_item_index += items_to_skip_count / lists_count curr_list_index = items_to_skip_count % lists_count break else curr_item_index = shortest_list_count lists.delete_if { |x| x.last == shortest_list_count } items_to_skip_count -= items_we_are_considering_count end end page_items = [] largest_list_count = lists.map(&:last).max while page_items.length < per_page && curr_item_index < largest_list_count curr_list = lists[curr_list_index] if curr_item_index < curr_list.last page_items << [curr_list.first, curr_item_index] end curr_list_index += 1 if curr_list_index == lists.length curr_list_index = 0 curr_item_index += 1 end end hashed = Hash.new { |h, k| h[k] = [] } page_items.each do |el| hashed[el.first] << el.last end hashed.each do |key, value| hashed[key] = (value.first..value.last) end hashed end |