module Granulate::ClassMethods

Constants

GRANULARITIES

Public Instance Methods

granulate(range) click to toggle source
# File lib/3scale_time_range/granulate.rb, line 9
def granulate(range)
  result = { rest: [] }
  GRANULARITIES.each do |granularity|
    result[(granularity.to_s + 's').to_sym] = []
  end
  time_range = TimeRange.new(range.begin, range.end, range.exclude_end?)
  extract(time_range, GRANULARITIES.first, result)
  result
end

Private Instance Methods

empty_range?(range) click to toggle source

TODO: Can be refactored to TimeRange#empty? Refactoring requires investigation into TimeRange use in System.

# File lib/3scale_time_range/granulate.rb, line 83
def empty_range?(range)
  (range.begin.to_i == range.end.to_i) && range.exclude_end?
end
extract(range, cycle, result) click to toggle source
# File lib/3scale_time_range/granulate.rb, line 21
def extract(range, cycle, result)
  if cycle.nil?
    result[:rest] << range unless empty_range?(range)
    return
  end

  cycle_start, cycle_end = extract_boundaries(range, cycle)
  if cycle_start && cycle_end
    result[(cycle.to_s + 's').to_sym] << TimeRange.new(cycle_start, cycle_end)

    if range.begin < cycle_start
      # Getting the last hour is enough because is the smallest resolution
      # that we support. If we supported minutes, we would need to get the
      # last minute non included.
      last_hour_not_treated = (cycle_start - 1.hour).end_of_hour
      extract(TimeRange.new(range.begin, last_hour_not_treated, false),
              next_cycle(cycle),
              result)
    end

    if range.end > cycle_end
      first_hour_not_treated = (cycle_end + 1.hour).beginning_of_hour
      extract(TimeRange.new(first_hour_not_treated, range.end, range.exclude_end?),
              next_cycle(cycle),
              result)
    end
  else
    extract(range, next_cycle(cycle), result)
  end
end
extract_boundaries(range, cycle) click to toggle source
# File lib/3scale_time_range/granulate.rb, line 58
def extract_boundaries(range, cycle)
  result = []
  range.each(cycle) do |date|
    if included_in_range?(range, date.send("beginning_of_#{cycle}")) &&
        included_in_range?(range, date.send("end_of_#{cycle}"))
      result << date
    end
  end
  if result.empty?
    return nil, nil
  else
    return result.first.send("beginning_of_#{cycle}"),
      result.last.send("end_of_#{cycle}")
  end
end
included_in_range?(range, value) click to toggle source

TODO: Can be refactored to TimeRange#include? Refactoring requires investigation into TimeRange use in System.

# File lib/3scale_time_range/granulate.rb, line 76
def included_in_range?(range, value)
  (range.begin <= value) &&
    (value < range.end || (value.to_i == range.end.to_i && !range.exclude_end?))
end
next_cycle(current_cycle) click to toggle source
# File lib/3scale_time_range/granulate.rb, line 52
def next_cycle(current_cycle)
  current_cycle_index = GRANULARITIES.find_index(current_cycle)
  raise "Unknown cycle: #{current_cycle.inspect}" unless current_cycle_index
  GRANULARITIES[current_cycle_index + 1]
end