Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reintroduce memory optimizations #697

Merged
merged 4 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading