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

Returns a new instance of SchemaOrderer.



239
240
241
242
243
244
245
# File 'lib/apiobjects.rb', line 239

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.



237
238
239
# File 'lib/apiobjects.rb', line 237

def order
  @order
end

#ordererObject

Returns the value of attribute orderer.



237
238
239
# File 'lib/apiobjects.rb', line 237

def orderer
  @orderer
end

#schemasObject

Returns the value of attribute schemas.



237
238
239
# File 'lib/apiobjects.rb', line 237

def schemas
  @schemas
end

Instance Method Details

#required_firstObject



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
300
301
302
303
304
305
# File 'lib/apiobjects.rb', line 267

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



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/apiobjects.rb', line 247

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