Class: Lutaml::Model::Store
- Inherits:
-
Object
- Object
- Lutaml::Model::Store
- Defined in:
- lib/lutaml/model/store.rb
Constant Summary collapse
- COMPACTION_THRESHOLD =
Compact dead WeakRef shells once a class bucket grows past this size.
1000- COMPACTION_INTERVAL =
Once the threshold is exceeded, only compact every Nth subsequent register call. Amortises the O(N) reject! over N inserts so register stays O(1) per call rather than O(N) per call (O(N^2) cumulatively for the class).
1000
Class Method Summary collapse
- .clear ⇒ Object
- .instance ⇒ Object
- .register(object) ⇒ Object
- .reset! ⇒ Object
- .resolve(model_class, reference_key, reference_value) ⇒ Object
- .store ⇒ Object
Instance Method Summary collapse
- #clear ⇒ Object
- #compaction_count ⇒ Object
- #index_entry_count(model_key) ⇒ Object
-
#initialize ⇒ Store
constructor
A new instance of Store.
- #inserts_since_compaction ⇒ Object
- #refs_for(model_key) ⇒ Object
- #register(object) ⇒ Object
- #resolve(model_class, reference_key, reference_value) ⇒ Object
- #store ⇒ Object
Constructor Details
#initialize ⇒ Store
Returns a new instance of Store.
43 44 45 46 47 48 49 50 |
# File 'lib/lutaml/model/store.rb', line 43 def initialize @store = ::Hash.new { |hash, key| hash[key] = [] } # Nested index: { model_key => { reference_key => { value => WeakRef(object) } } } # Grouped by model_key so register only iterates this class's own indices. @index = {} @inserts_since_compaction = ::Hash.new(0) @compaction_count = 0 end |
Class Method Details
.clear ⇒ Object
34 35 36 |
# File 'lib/lutaml/model/store.rb', line 34 def clear instance.clear end |
.instance ⇒ Object
18 19 20 |
# File 'lib/lutaml/model/store.rb', line 18 def instance @instance ||= new end |
.register(object) ⇒ Object
26 27 28 |
# File 'lib/lutaml/model/store.rb', line 26 def register(object) instance.register(object) end |
.reset! ⇒ Object
22 23 24 |
# File 'lib/lutaml/model/store.rb', line 22 def reset! @instance = new end |
.resolve(model_class, reference_key, reference_value) ⇒ Object
30 31 32 |
# File 'lib/lutaml/model/store.rb', line 30 def resolve(model_class, reference_key, reference_value) instance.resolve(model_class, reference_key, reference_value) end |
.store ⇒ Object
38 39 40 |
# File 'lib/lutaml/model/store.rb', line 38 def store instance.store end |
Instance Method Details
#clear ⇒ Object
80 81 82 83 84 85 |
# File 'lib/lutaml/model/store.rb', line 80 def clear @store = ::Hash.new { |hash, key| hash[key] = [] } @index = {} @inserts_since_compaction = ::Hash.new(0) @compaction_count = 0 end |
#compaction_count ⇒ Object
105 106 107 |
# File 'lib/lutaml/model/store.rb', line 105 def compaction_count @compaction_count end |
#index_entry_count(model_key) ⇒ Object
109 110 111 |
# File 'lib/lutaml/model/store.rb', line 109 def index_entry_count(model_key) @index[model_key]&.sum { |_reference_key, entries| entries.size } || 0 end |
#inserts_since_compaction ⇒ Object
101 102 103 |
# File 'lib/lutaml/model/store.rb', line 101 def inserts_since_compaction @inserts_since_compaction end |
#refs_for(model_key) ⇒ Object
97 98 99 |
# File 'lib/lutaml/model/store.rb', line 97 def refs_for(model_key) @store[model_key] end |
#register(object) ⇒ Object
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/lutaml/model/store.rb', line 52 def register(object) model_key = object.class.to_s refs = @store[model_key] refs << WeakRef.new(object) @inserts_since_compaction[model_key] += 1 compact_if_needed(refs, model_key) update_existing_indices(object, model_key) end |
#resolve(model_class, reference_key, reference_value) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/lutaml/model/store.rb', line 63 def resolve(model_class, reference_key, reference_value) model_key = model_class.to_s model_indices = @index[model_key] unless model_indices&.key?(reference_key) model_indices = ensure_model_index(model_key) build_index(model_indices, model_key, reference_key) end entry = model_indices[reference_key][reference_value] return nil unless entry obj = dereference(entry) model_indices[reference_key].delete(reference_value) unless obj obj end |
#store ⇒ Object
87 88 89 90 91 92 93 94 95 |
# File 'lib/lutaml/model/store.rb', line 87 def store @store.transform_values do |refs| refs.each_with_object([]) do |ref, alive| alive << ref.__getobj__ if ref.weakref_alive? rescue WeakRef::RefError nil end end end |