module ActiveRecord::IdRegions::ClassMethods

Public Instance Methods

clear_region_cache() click to toggle source
# File lib/active_record/id_regions.rb, line 43
def clear_region_cache
  @@my_region_number = nil
end
compress_id(id) click to toggle source
# File lib/active_record/id_regions.rb, line 98
def compress_id(id)
  return nil if id.nil?
  region_number, short_id = split_id(id)
  (region_number == 0) ? short_id.to_s : "#{region_number}#{COMPRESSED_ID_SEPARATOR}#{short_id}"
end
compressed_id?(id) click to toggle source

ID compression

# File lib/active_record/id_regions.rb, line 94
def compressed_id?(id)
  id.to_s =~ /^#{CID_OR_ID_MATCHER}$/
end
group_ids_by_region(ids) click to toggle source
# File lib/active_record/id_regions.rb, line 123
def group_ids_by_region(ids)
  ids.group_by { |id| id_to_region(id) }
end
id_in_current_region?(id) click to toggle source
# File lib/active_record/id_regions.rb, line 76
def id_in_current_region?(id)
  id_to_region(id) == my_region_number
end
id_in_region(id, region_number) click to toggle source
# File lib/active_record/id_regions.rb, line 51
def id_in_region(id, region_number)
  region_number * rails_sequence_factor + id
end
id_to_region(id) click to toggle source
# File lib/active_record/id_regions.rb, line 47
def id_to_region(id)
  id.to_i / rails_sequence_factor
end
in_my_region() click to toggle source
# File lib/active_record/id_regions.rb, line 64
def in_my_region
  in_region(my_region_number)
end
in_region(region_number) click to toggle source
# File lib/active_record/id_regions.rb, line 68
def in_region(region_number)
  region_number.nil? ? all : where(:id => region_to_range(region_number))
end
my_region_number(force_reload = false) click to toggle source
# File lib/active_record/id_regions.rb, line 16
def my_region_number(force_reload = false)
  clear_region_cache if force_reload
  @@my_region_number ||= discover_my_region_number
end
partition_ids_by_remote_region(ids) click to toggle source

Partition the passed ids into local and remote sets

# File lib/active_record/id_regions.rb, line 119
def partition_ids_by_remote_region(ids)
  ids.partition { |id| self.id_in_current_region?(id) }
end
partition_objs_by_remote_region(objs) click to toggle source

Partition the passed AR objects into local and remote sets

# File lib/active_record/id_regions.rb, line 114
def partition_objs_by_remote_region(objs)
  objs.partition(&:in_current_region?)
end
rails_sequence_end(region_number = my_region_number) click to toggle source
# File lib/active_record/id_regions.rb, line 33
def rails_sequence_end(region_number = my_region_number)
  rails_sequence_start(region_number) + rails_sequence_factor - 1
end
rails_sequence_factor() click to toggle source
# File lib/active_record/id_regions.rb, line 21
def rails_sequence_factor
  @@rails_sequence_factor ||= DEFAULT_RAILS_SEQUENCE_FACTOR
end
rails_sequence_factor=(factor) click to toggle source
# File lib/active_record/id_regions.rb, line 25
def rails_sequence_factor=(factor)
  @@rails_sequence_factor = factor
end
rails_sequence_range(region_number = my_region_number) click to toggle source
# File lib/active_record/id_regions.rb, line 37
def rails_sequence_range(region_number = my_region_number)
  rails_sequence_start(region_number)..rails_sequence_end(region_number)
end
Also aliased as: region_to_range
rails_sequence_start(region_number = my_region_number) click to toggle source
# File lib/active_record/id_regions.rb, line 29
def rails_sequence_start(region_number = my_region_number)
  region_number * rails_sequence_factor
end
region_number_from_sequence() click to toggle source
# File lib/active_record/id_regions.rb, line 127
def region_number_from_sequence
  sequence_name = connection.select_value("SELECT relname FROM pg_class WHERE relkind = 'S' LIMIT 1")
  return if sequence_name.nil?
  id_to_region(connection.select_value("SELECT last_value FROM #{sequence_name}"))
end
region_to_array(region_number) click to toggle source
# File lib/active_record/id_regions.rb, line 59
def region_to_array(region_number)
  range = region_to_range(region_number)
  [range.first, range.last]
end
region_to_conditions(region_number, col = "id") click to toggle source
# File lib/active_record/id_regions.rb, line 55
def region_to_conditions(region_number, col = "id")
  ["#{col} >= ? AND #{col} <= ?", *region_to_array(region_number)]
end
region_to_range(region_number = my_region_number)
split_id(id) click to toggle source
# File lib/active_record/id_regions.rb, line 80
def split_id(id)
  return [my_region_number, nil] if id.nil?
  id = uncompress_id(id)

  region_number = id_to_region(id)
  short_id      = (region_number == 0) ? id : id % (region_number * rails_sequence_factor)

  return region_number, short_id
end
uncompress_id(compressed_id) click to toggle source
# File lib/active_record/id_regions.rb, line 104
def uncompress_id(compressed_id)
  return nil if compressed_id.nil?
  compressed_id.to_s =~ RE_COMPRESSED_ID ? ($1.to_i * rails_sequence_factor + $2.to_i) : compressed_id.to_i
end
with_region(region_number) { || ... } click to toggle source
# File lib/active_record/id_regions.rb, line 72
def with_region(region_number)
  where(:id => region_to_range(region_number)).scoping { yield }
end

Private Instance Methods

discover_my_region_number() click to toggle source
# File lib/active_record/id_regions.rb, line 135
def discover_my_region_number
  region_file = Rails.root.join("REGION") if defined?(Rails)
  region_num = File.read(region_file) if region_file && File.exist?(region_file)
  region_num ||= ENV.fetch("REGION", nil)
  region_num ||= region_number_from_sequence
  region_num.to_i
end