Class: Ibex::Tables::Compact
- Inherits:
-
Object
- Object
- Ibex::Tables::Compact
- Defined in:
- lib/ibex/tables/compact.rb,
sig/ibex/tables/compact.rbs
Overview
Sparse table represented by per-row offsets and ownership checks.
Direct Known Subclasses
Constant Summary collapse
- DENSE_CELL_LIMIT =
1_000_000
Instance Attribute Summary collapse
- #checks ⇒ Array[Integer?] readonly
- #dense_values ⇒ Array[Object?]? readonly
- #dense_width ⇒ Integer? readonly
- #offsets ⇒ Array[Integer] readonly
- #row_count ⇒ Integer readonly
- #values ⇒ Array[Object?] readonly
Class Method Summary collapse
- .build(rows, dense: true) ⇒ Compact
- .packed(offsets, values, checks, row_count:, dense_width: nil) ⇒ Compact
Instance Method Summary collapse
- #dense_layout(dense_width) ⇒ Array[Object?]?
-
#initialize(offsets:, values:, checks:, row_count:, dense_width: nil) ⇒ Compact
constructor
A new instance of Compact.
-
#lookup(row, column) ⇒ Object?
Keep predicate dispatch out of this lookup because every parser action and goto crosses it.
- #row(row) ⇒ Hash[Integer, Object?]
Constructor Details
#initialize(offsets:, values:, checks:, row_count:, dense_width: nil) ⇒ Compact
Returns a new instance of Compact.
130 131 132 133 134 135 136 137 138 |
# File 'lib/ibex/tables/compact.rb', line 130 def initialize(offsets:, values:, checks:, row_count:, dense_width: nil) @offsets = offsets.freeze @values = values.freeze @checks = checks.freeze @row_count = row_count @dense_width = dense_width @dense_values = dense_layout(dense_width) freeze end |
Instance Attribute Details
#checks ⇒ Array[Integer?] (readonly)
73 74 75 |
# File 'lib/ibex/tables/compact.rb', line 73 def checks @checks end |
#dense_values ⇒ Array[Object?]? (readonly)
75 76 77 |
# File 'lib/ibex/tables/compact.rb', line 75 def dense_values @dense_values end |
#dense_width ⇒ Integer? (readonly)
76 77 78 |
# File 'lib/ibex/tables/compact.rb', line 76 def dense_width @dense_width end |
#offsets ⇒ Array[Integer] (readonly)
71 72 73 |
# File 'lib/ibex/tables/compact.rb', line 71 def offsets @offsets end |
#row_count ⇒ Integer (readonly)
74 75 76 |
# File 'lib/ibex/tables/compact.rb', line 74 def row_count @row_count end |
#values ⇒ Array[Object?] (readonly)
72 73 74 |
# File 'lib/ibex/tables/compact.rb', line 72 def values @values end |
Class Method Details
.build(rows, dense: true) ⇒ Compact
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/ibex/tables/compact.rb', line 80 def build(rows, dense: true) offsets = Array.new(rows.length, 0) values = [] #: Array[Object?] checks = [] #: Array[Integer?] next_offsets = {} #: Hash[Array[Integer], Integer] rows.each_index.sort_by { |row| [-rows[row].length, row] }.each do |row| offset = find_offset(rows[row].keys, checks, next_offsets) offsets[row] = offset rows[row].each do |column, value| index = offset + column values[index] = value checks[index] = row end end dense_width = rows.flat_map(&:keys).max.to_i + 1 if dense dense_width = nil if dense_width && (rows.length * dense_width) > DENSE_CELL_LIMIT new( offsets: offsets, values: values, checks: checks, row_count: rows.length, dense_width: dense_width ) end |
.packed(offsets, values, checks, row_count:, dense_width: nil) ⇒ Compact
104 105 106 107 108 109 110 111 112 |
# File 'lib/ibex/tables/compact.rb', line 104 def packed(offsets, values, checks, row_count:, dense_width: nil) new( offsets: PackedIntegers.decode_required(offsets), values: PackedIntegers.decode(values), checks: PackedIntegers.decode(checks), row_count: row_count, dense_width: dense_width ) end |
Instance Method Details
#dense_layout(dense_width) ⇒ Array[Object?]?
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/ibex/tables/compact.rb', line 170 def dense_layout(dense_width) return nil unless dense_width raise ArgumentError, "compact dense width must be positive" unless dense_width.positive? return nil if (@row_count * dense_width) > DENSE_CELL_LIMIT dense = Array.new(@row_count * dense_width) #: Array[Object?] @checks.each_index do |index| row = @checks[index] next unless row column = index - @offsets.fetch(row) raise ArgumentError, "compact column exceeds the dense row width" unless column.between?(0, dense_width - 1) dense[(row * dense_width) + column] = @values[index] end dense.freeze end |
#lookup(row, column) ⇒ Object?
Keep predicate dispatch out of this lookup because every parser action and goto crosses it. rubocop:disable Style/NumericPredicate
144 145 146 147 148 149 150 151 |
# File 'lib/ibex/tables/compact.rb', line 144 def lookup(row, column) return nil if row < 0 || row >= @row_count || column < 0 index = @offsets[row] + column return nil if index < 0 || index >= @checks.length @checks[index] == row ? @values[index] : nil end |
#row(row) ⇒ Hash[Integer, Object?]
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/ibex/tables/compact.rb', line 155 def row(row) return {} unless row.between?(0, @row_count - 1) result = {} #: Hash[Integer, Object?] @checks.each_index do |index| next unless @checks[index] == row result[index - @offsets[row]] = @values[index] end result end |