Skip to content

Commit

Permalink
Merge pull request #697 from rom-rb/reintroduce-memory-optimisations
Browse files Browse the repository at this point in the history
Reintroduce memory optimizations
  • Loading branch information
flash-gordon authored Jan 8, 2025
2 parents a750972 + 4c85e01 commit e3667fe
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 48 deletions.
2 changes: 1 addition & 1 deletion core/lib/rom/cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def inspect

# @api private
def initialize
@objects = Concurrent::Map.new
@objects = ::Concurrent::Map.new
@namespaced = {}
end

Expand Down
10 changes: 10 additions & 0 deletions core/lib/rom/container.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ def self.new(gateways, relations, mappers, commands)
end
end

# @api private
attr_reader :cache

# @api private
def initialize
super

@cache = Cache.new
end

# Return registered gateways
#
# @return [Hash<Symbol=>Gateway>]
Expand Down
17 changes: 2 additions & 15 deletions core/lib/rom/plugins/relation/registry_reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,9 @@ class RegistryReader < ::Module
EMPTY_REGISTRY = RelationRegistry.build(EMPTY_HASH).freeze

# @api private
attr_reader :relations

# @api private
def initialize(relations:)
def initialize(readers:)
super()
@relations = relations
define_readers!
include readers
end

# @api private
Expand All @@ -30,15 +26,6 @@ def included(klass)

klass.option :__registry__, default: -> { EMPTY_REGISTRY }
end

private

# @api private
def define_readers!
relations.each do |name|
define_method(name) { __registry__[name] }
end
end
end
end
end
Expand Down
13 changes: 12 additions & 1 deletion core/lib/rom/setup/finalize/finalize_relations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ class Finalize
class FinalizeRelations
attr_reader :notifications

class RegistryReaders < ::Module
def initialize(relations)
super()

relations.each do |name|
define_method(name) { __registry__[name] }
end
end
end

# Build relation registry of specified descendant classes
#
# This is used by the setup
Expand All @@ -32,6 +42,7 @@ def initialize(gateways, relation_classes, notifications:, mappers: nil, plugins
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def run!
relation_registry = RelationRegistry.new do |registry, relations|
registry_readers = RegistryReaders.new(relation_names)
@relation_classes.each do |klass|
unless klass.adapter
raise MissingAdapterIdentifierError,
Expand All @@ -45,7 +56,7 @@ def run!
"Relation with name #{key.inspect} registered more than once"
end

klass.use(:registry_reader, relations: relation_names)
klass.use(:registry_reader, readers: registry_readers)

notifications.trigger(
'configuration.relations.class.ready',
Expand Down
3 changes: 2 additions & 1 deletion repository/lib/rom/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ class Repository

# @!method self.relation_reader
# Get or set relation reader module
# @return [RelationReader]
# @return [Module]
defines :relation_reader
relation_reader RelationReader

struct_namespace ROM::Struct

Expand Down
8 changes: 5 additions & 3 deletions repository/lib/rom/repository/class_interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ def [](name)
def new(container = nil, **options)
container ||= options.fetch(:container)

unless relation_reader
relation_reader(RelationReader.new(self, container.relations.elements.keys))
include(relation_reader)
unless self < relation_reader
include relation_reader.new(
relations: container.relations.elements.keys,
cache: container.cache
)
end

super(**options, container: container)
Expand Down
77 changes: 52 additions & 25 deletions repository/lib/rom/repository/relation_reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,72 @@ module ROM
class Repository
# @api private
class RelationReader < ::Module
# @api private
attr_reader :klass

# @api private
attr_reader :relations

module InstanceMethods
private

# @api private
def set_relation(name) # rubocop:disable Naming/AccessorMethodName
def prepare_relation(name, **)
container
.relations[name]
.with(auto_struct: auto_struct)
.struct_namespace(struct_namespace)
.with(
auto_struct: auto_struct,
struct_namespace: struct_namespace
)
end

# @api private
def relation_reader(cache, ...)
cache_key = relation_cache_key(...)
cache.fetch_or_store(*cache_key) { prepare_relation(...) }
end

# @api private
def relation_cache_key(name, **)
[name, auto_struct, struct_namespace]
end
end

# @api private
def initialize(klass, relations)
super()
@klass = klass
@relations = relations
define_readers!
class Readers < ::Module
# @api private
attr_reader :cache

def initialize(relations)
super()

include InstanceMethods

define_readers(relations)
end

# @api private
def define_readers(relations)
cache = Cache.new
relations.each do |name|
define_readers_for_relation(cache, name)
end
end

# @api private
def define_readers_for_relation(cache, name)
define_method(name) do |**kwargs|
relation_reader(cache, name, **kwargs)
end
end
end

# @api private
def included(klass)
super
klass.include(InstanceMethods)
end
def initialize(relations:, cache:)
super()

private
add_readers(relations, cache)
end

# @api private
def define_readers!
relations.each do |name|
define_method(name) do
@relations[name] ||= set_relation(name)
end
end
def add_readers(relations, cache)
include cache.fetch_or_store(:relation_readers) {
Readers.new(relations)
}
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion repository/lib/rom/repository/root.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def self.inherited(klass)
# @see Repository#initialize
def initialize(*, **)
super
@root = set_relation(self.class.root)
@root = prepare_relation(self.class.root)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion repository/spec/integration/plugin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def self.apply(target, **)
target.prepend(self)
end

def set_relation(*)
def prepare_relation(*)
super.where { `1 = 0` }
end
end
Expand Down

0 comments on commit e3667fe

Please sign in to comment.