Class: Woods::Storage::MetadataStore::InMemory

Inherits:
Object
  • Object
show all
Includes:
Interface
Defined in:
lib/woods/storage/metadata_store.rb

Overview

Pure-Ruby metadata store backed by a hash. No external dependencies, no persistence — vectors and metadata both live in the building process and die with it. Suitable for hosts that don’t bundle the ‘sqlite3` gem (e.g., MySQL- or Postgres-only Rails apps), and for short-lived processes that rebuild the index per run.

Examples:

store = InMemory.new
store.store("User", { type: "model", namespace: "Admin" })
store.find("User")  # => { "type" => "model", "namespace" => "Admin" }

Instance Method Summary collapse

Constructor Details

#initializeInMemory

Returns a new instance of InMemory.



110
111
112
# File 'lib/woods/storage/metadata_store.rb', line 110

def initialize
  @data = {}
end

Instance Method Details

#bulk_load(entries) ⇒ void

This method returns an undefined value.

Hydrate the store from a pre-serialized dump.

Dual of #each_entry — Snapshotter feeds the deserialized dump contents through this method to restore the store in a new process.

Parameters:

  • entries (Enumerable<Array(String, Hash)>)

    Pairs of [id, metadata]



187
188
189
# File 'lib/woods/storage/metadata_store.rb', line 187

def bulk_load(entries)
  entries.each { |id, meta| @data[id] = meta }
end

#clear!Object

Drop every stored entry. Used by the MCP reload tool to pick up a fresh embed run without restarting the process. Safe on an empty store.



193
194
195
# File 'lib/woods/storage/metadata_store.rb', line 193

def clear!
  @data = {}
end

#countObject



162
163
164
# File 'lib/woods/storage/metadata_store.rb', line 162

def count
  @data.size
end

#delete(id) ⇒ Object



157
158
159
# File 'lib/woods/storage/metadata_store.rb', line 157

def delete(id)
  @data.delete(id)
end

#each_entry {|id, metadata| ... } ⇒ Enumerator

Iterate over every stored entry, yielding (id, metadata) pairs.

Persistence seam for Snapshotter::Metadata. Yields the raw internal hash (including updated_at) so the Snapshotter can reconstruct state faithfully on load.

Yields:

  • (id, metadata)

    id is a String; metadata is a Hash with string keys

Returns:

  • (Enumerator)

    when no block given



174
175
176
177
178
# File 'lib/woods/storage/metadata_store.rb', line 174

def each_entry(&block)
  return enum_for(:each_entry) unless block

  @data.each(&block)
end

#find(id) ⇒ Object



120
121
122
123
124
125
# File 'lib/woods/storage/metadata_store.rb', line 120

def find(id)
  record = @data[id]
  return nil unless record

  record.except('updated_at')
end

#find_batch(ids) ⇒ Object



128
129
130
131
132
133
# File 'lib/woods/storage/metadata_store.rb', line 128

def find_batch(ids)
  ids.each_with_object({}) do |id, result|
    data = find(id)
    result[id] = data if data
  end
end

#find_by_type(type) ⇒ Object



136
137
138
139
140
141
142
143
# File 'lib/woods/storage/metadata_store.rb', line 136

def find_by_type(type)
  target = type.to_s
  @data.each_with_object([]) do |(id, record), out|
    next unless record['type'].to_s == target

    out << record.except('updated_at').merge('id' => id)
  end
end

#search(query, fields: nil) ⇒ Object



146
147
148
149
150
151
152
153
154
# File 'lib/woods/storage/metadata_store.rb', line 146

def search(query, fields: nil)
  needle = query.to_s
  @data.each_with_object([]) do |(id, record), out|
    haystacks = fields ? fields.map { |f| record[f.to_s] } : [JSON.generate(record)]
    next unless haystacks.compact.any? { |h| h.to_s.include?(needle) }

    out << record.except('updated_at').merge('id' => id)
  end
end

#store(id, metadata) ⇒ Object



115
116
117
# File 'lib/woods/storage/metadata_store.rb', line 115

def store(id, )
  @data[id] = stringify_keys().merge('updated_at' => Time.now.iso8601)
end