Class: Wp2txt::MultistreamReader
- Inherits:
-
Object
- Object
- Wp2txt::MultistreamReader
- Defined in:
- lib/wp2txt/multistream.rb
Overview
Reads articles from multistream bz2 files
Instance Attribute Summary collapse
-
#index ⇒ Object
readonly
Returns the value of attribute index.
-
#multistream_path ⇒ Object
readonly
Returns the value of attribute multistream_path.
Instance Method Summary collapse
-
#each_article_in_first_streams(stream_count, &block) ⇒ Object
Iterate through first N streams.
-
#each_article_in_stream(offset, &block) ⇒ Object
Iterate through all articles in a stream.
-
#each_article_parallel(entries, num_processes: 4) {|Hash| ... } ⇒ Object
Iterate through articles in parallel, yielding each page Groups articles by stream and processes streams in parallel.
-
#extract_article(title) ⇒ Object
Extract a single article by title.
-
#extract_articles(titles) ⇒ Object
Extract multiple articles (sequential).
-
#extract_articles_parallel(titles, num_processes: 4, &progress_callback) ⇒ Hash
Extract multiple articles in parallel (by stream).
-
#initialize(multistream_path, index_or_path, use_cache: true, cache_dir: nil) ⇒ MultistreamReader
constructor
Initialize reader with multistream file and index.
Constructor Details
#initialize(multistream_path, index_or_path, use_cache: true, cache_dir: nil) ⇒ MultistreamReader
Initialize reader with multistream file and index
233 234 235 236 237 238 239 240 241 242 |
# File 'lib/wp2txt/multistream.rb', line 233 def initialize(multistream_path, index_or_path, use_cache: true, cache_dir: nil) @multistream_path = multistream_path # Accept either an existing index or a path to create one if index_or_path.is_a?(MultistreamIndex) @index = index_or_path else @index = MultistreamIndex.new(index_or_path, use_cache: use_cache, cache_dir: cache_dir) end end |
Instance Attribute Details
#index ⇒ Object (readonly)
Returns the value of attribute index.
226 227 228 |
# File 'lib/wp2txt/multistream.rb', line 226 def index @index end |
#multistream_path ⇒ Object (readonly)
Returns the value of attribute multistream_path.
226 227 228 |
# File 'lib/wp2txt/multistream.rb', line 226 def multistream_path @multistream_path end |
Instance Method Details
#each_article_in_first_streams(stream_count, &block) ⇒ Object
Iterate through first N streams
340 341 342 343 344 |
# File 'lib/wp2txt/multistream.rb', line 340 def each_article_in_first_streams(stream_count, &block) @index.stream_offsets.first(stream_count).each do |offset| each_article_in_stream(offset, &block) end end |
#each_article_in_stream(offset, &block) ⇒ Object
Iterate through all articles in a stream
334 335 336 337 |
# File 'lib/wp2txt/multistream.rb', line 334 def each_article_in_stream(offset, &block) stream_content = read_stream_at(offset) extract_all_pages_from_xml(stream_content, &block) end |
#each_article_parallel(entries, num_processes: 4) {|Hash| ... } ⇒ Object
Iterate through articles in parallel, yielding each page Groups articles by stream and processes streams in parallel
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/wp2txt/multistream.rb', line 309 def each_article_parallel(entries, num_processes: 4) return enum_for(:each_article_parallel, entries, num_processes: num_processes) unless block_given? # Group by stream offset grouped = entries.group_by { |e| e[:offset] } # Process streams in parallel, collecting all pages all_pages = Parallel.flat_map(grouped.keys, in_processes: num_processes) do |offset| entries_in_stream = grouped[offset] stream_content = read_stream_at(offset) pages = [] entries_in_stream.each do |entry| page = extract_page_from_xml(stream_content, entry[:title]) pages << page if page end pages end # Yield each page (sequential, as yielding must happen in main process) all_pages.each { |page| yield page } end |
#extract_article(title) ⇒ Object
Extract a single article by title
245 246 247 248 249 250 251 |
# File 'lib/wp2txt/multistream.rb', line 245 def extract_article(title) entry = @index.find_by_title(title) return nil unless entry stream_content = read_stream_at(entry[:offset]) extract_page_from_xml(stream_content, title) end |
#extract_articles(titles) ⇒ Object
Extract multiple articles (sequential)
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/wp2txt/multistream.rb', line 254 def extract_articles(titles) # Group by stream offset for efficiency grouped = titles.group_by { |t| @index.stream_offset_for(t) } results = {} grouped.each do |offset, titles_in_stream| next unless offset stream_content = read_stream_at(offset) titles_in_stream.each do |title| page = extract_page_from_xml(stream_content, title) results[title] = page if page end end results end |
#extract_articles_parallel(titles, num_processes: 4, &progress_callback) ⇒ Hash
Extract multiple articles in parallel (by stream)
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 |
# File 'lib/wp2txt/multistream.rb', line 276 def extract_articles_parallel(titles, num_processes: 4, &progress_callback) # Group titles by stream offset grouped = titles.group_by { |t| @index.stream_offset_for(t) } grouped.delete(nil) # Remove titles not found in index # Process streams in parallel stream_results = Parallel.map(grouped.keys, in_processes: num_processes) do |offset| titles_in_stream = grouped[offset] stream_content = read_stream_at(offset) stream_pages = {} titles_in_stream.each do |title| page = extract_page_from_xml(stream_content, title) stream_pages[title] = page if page end stream_pages end # Merge results from all streams results = {} stream_results.each do |stream_pages| results.merge!(stream_pages) end results end |