purplelight 0.1.18 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/PERFORMANCE_NOTES.md +4 -2
- data/README.md +3 -2
- data/benchmark/baseline.json +405 -391
- data/benchmark/microbench.rb +1 -0
- data/lib/purplelight/queue.rb +6 -1
- data/lib/purplelight/snapshot.rb +25 -4
- data/lib/purplelight/version.rb +1 -1
- data/lib/purplelight/writer_parquet.rb +4 -3
- metadata +1 -1
data/benchmark/microbench.rb
CHANGED
|
@@ -47,6 +47,7 @@ PARQUET_READ_DOCS = Array.new(10_000) do |index|
|
|
|
47
47
|
'score' => index * 0.25,
|
|
48
48
|
'nullable_score' => (nullable ? nil : index * 0.5),
|
|
49
49
|
'category' => "category-#{index % 8}",
|
|
50
|
+
'symbol' => :"symbol-#{index % 8}",
|
|
50
51
|
'unique_text' => format('row-%<index>08d-value-%<encoded>08x',
|
|
51
52
|
index:, encoded: index * 2_654_435_761),
|
|
52
53
|
'utf8_text' => "日本語-#{index % 32}",
|
data/lib/purplelight/queue.rb
CHANGED
data/lib/purplelight/snapshot.rb
CHANGED
|
@@ -131,6 +131,12 @@ module Purplelight
|
|
|
131
131
|
|
|
132
132
|
# Reader queue
|
|
133
133
|
queue = ByteQueue.new(max_bytes: @queue_size_bytes)
|
|
134
|
+
failure_mutex = Mutex.new
|
|
135
|
+
worker_failure = nil
|
|
136
|
+
record_failure = lambda do |error|
|
|
137
|
+
failure_mutex.synchronize { worker_failure ||= error }
|
|
138
|
+
queue.close(discard: true)
|
|
139
|
+
end
|
|
134
140
|
|
|
135
141
|
# Writer
|
|
136
142
|
writer_count = @format == :jsonl ? [@writer_threads.to_i, 1].max : 1
|
|
@@ -163,9 +169,15 @@ module Purplelight
|
|
|
163
169
|
readers = partition_filters.each_with_index.map do |pf, idx|
|
|
164
170
|
Thread.new do
|
|
165
171
|
local_telemetry = @telemetry_enabled ? Telemetry.new(enabled: true) : Telemetry::NULL
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
172
|
+
begin
|
|
173
|
+
read_partition(idx: idx, filter_spec: pf, queue: queue, batch_size: @batch_size,
|
|
174
|
+
manifest: manifest, telemetry: local_telemetry)
|
|
175
|
+
rescue StandardError => e
|
|
176
|
+
record_failure.call(e)
|
|
177
|
+
ensure
|
|
178
|
+
# Merge per-thread telemetry
|
|
179
|
+
@telemetry.merge!(local_telemetry) if @telemetry_enabled
|
|
180
|
+
end
|
|
169
181
|
end
|
|
170
182
|
end
|
|
171
183
|
|
|
@@ -182,8 +194,14 @@ module Purplelight
|
|
|
182
194
|
|
|
183
195
|
worker_writer.write_many(batch)
|
|
184
196
|
end
|
|
197
|
+
rescue StandardError => e
|
|
198
|
+
record_failure.call(e)
|
|
185
199
|
ensure
|
|
186
|
-
|
|
200
|
+
begin
|
|
201
|
+
worker_writer.close
|
|
202
|
+
rescue StandardError => e
|
|
203
|
+
record_failure.call(e)
|
|
204
|
+
end
|
|
187
205
|
end
|
|
188
206
|
end
|
|
189
207
|
|
|
@@ -212,6 +230,9 @@ module Purplelight
|
|
|
212
230
|
else
|
|
213
231
|
@running = false
|
|
214
232
|
end
|
|
233
|
+
worker_error = failure_mutex.synchronize { worker_failure }
|
|
234
|
+
raise worker_error if worker_error
|
|
235
|
+
|
|
215
236
|
if @telemetry_enabled
|
|
216
237
|
total = @telemetry.timers.values.sum
|
|
217
238
|
breakdown = @telemetry.timers
|
data/lib/purplelight/version.rb
CHANGED
|
@@ -118,7 +118,7 @@ module Purplelight
|
|
|
118
118
|
return build_string_array(values)
|
|
119
119
|
end
|
|
120
120
|
return build_string_array(values) if data_type.is_a?(Arrow::StringDataType) ||
|
|
121
|
-
first.is_a?(String) || first.is_a?(Hash)
|
|
121
|
+
first.is_a?(String) || first.is_a?(Symbol) || first.is_a?(Hash)
|
|
122
122
|
if (data_type.is_a?(Arrow::ListDataType) || first.is_a?(Array)) &&
|
|
123
123
|
values.all? { |value| value.nil? || value.is_a?(Array) } &&
|
|
124
124
|
(data_type || values.any? { |value| value && !value.empty? })
|
|
@@ -317,13 +317,14 @@ module Purplelight
|
|
|
317
317
|
|
|
318
318
|
def low_cardinality_strings?(values)
|
|
319
319
|
first = values.find { |value| !value.nil? }
|
|
320
|
-
|
|
320
|
+
string_like = first.is_a?(String) || first.is_a?(Symbol)
|
|
321
|
+
return false unless string_like
|
|
321
322
|
|
|
322
323
|
distinct = {}
|
|
323
324
|
count = 0
|
|
324
325
|
values.each do |value|
|
|
325
326
|
next if value.nil?
|
|
326
|
-
return false unless value.is_a?(String)
|
|
327
|
+
return false unless value.is_a?(String) || value.is_a?(Symbol)
|
|
327
328
|
|
|
328
329
|
count += 1
|
|
329
330
|
distinct[value] = true
|