Class: SchemaOrderer

Inherits:
Object
  • Object
show all
Defined in:
lib/apiobjects.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, schema_specs) ⇒ SchemaOrderer



233
234
235
236
237
238
239
# File 'lib/apiobjects.rb', line 233

def initialize(path, schema_specs)
  @schemas = {}
  schema_specs.each do |name, schema|
    r = "#{path}#{name}"
    @schemas[r] = SchemaInfo.new(r, name, schema)
  end
end

Instance Attribute Details

#orderObject

Returns the value of attribute order.



231
232
233
# File 'lib/apiobjects.rb', line 231

def order
  @order
end

#ordererObject

Returns the value of attribute orderer.



231
232
233
# File 'lib/apiobjects.rb', line 231

def orderer
  @orderer
end

#schemasObject

Returns the value of attribute schemas.



231
232
233
# File 'lib/apiobjects.rb', line 231

def schemas
  @schemas
end

Instance Method Details

#required_firstObject



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/apiobjects.rb', line 261

def required_first
  chosen = []
  until chosen.size == @schemas.size
    used = Set.new(chosen.map { |si| si.ref })
    avail = @schemas.values.select { |si| !used.member?(si.ref) }
    best = nil
    avail.each do |si|
      prereq = chosen.count { |x| x.direct_refs.fetch(si.ref, false) }
      fulfilled = chosen.count { |x| si.direct_refs.fetch(x.ref, false) }
      postreq = si.direct_refs.size - (prereq + fulfilled)
      better = false
      if best.nil?
        better = true
      else
        # Minimize preceding types requiring this.
        if prereq < best.first
          better = true
        elsif prereq == best.first
          # Minimize remaining unfulfilled requires.
          if postreq < best[1]
            better = true
          elsif postreq == best[1]
            # Check mutual direct requirements.
            best_req_si = best.last.direct_refs.fetch(si.ref, false)
            si_req_best = si.direct_refs.fetch(best.last.ref, false)
            if best_req_si
              better = true unless si_req_best
            end
            # Order by name if no other difference.
            better = si.ref < best.last.ref unless better
          end
        end
      end
      best = [ prereq, postreq, si ] if better
    end
    chosen.push(best.last)
  end
  chosen
end

#sort!(orderer = 'required_first') ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/apiobjects.rb', line 241

def sort!(orderer = 'required_first')
  case orderer
  when 'required_first' then @order = required_first
  when '<=>' then @order = @schemas.values.sort { |a, b| a <=> b }
  else
    @order = @schemas.values.sort do |a, b|
      va = var_or_method_value(a, orderer)
      vb = var_or_method_value(b, orderer)
      va <=> vb
    end
  end
  @orderer = orderer
  seen = Set.new
  @order.each do |si|
    si.set_post_refs(seen)
    seen.add(si.ref)
  end
  @order
end