herringbone 0.5.0 → 0.6.1

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.
data/lib/herringbone.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "stringio"
4
- require "pathname"
5
4
  require_relative "herringbone/version"
6
5
 
7
6
  # Pure-Ruby reader and writer for Apache Parquet files
@@ -38,33 +37,76 @@ module Herringbone
38
37
  class SchemaMismatch < EncodeError; end
39
38
 
40
39
  # The file (or the writer configuration) uses a Parquet feature Herringbone does not implement,
41
- # such as encryption or a codec whose library is unavailable
40
+ # such as a codec whose library is unavailable
42
41
  class UnsupportedError < Error; end
42
+
43
+ # An encrypted file or column cannot be read: its key was not given, the key or AAD prefix is
44
+ # wrong, or the encrypted bytes were changed
45
+ class DecryptionError < Error; end
43
46
  end
44
47
 
45
- require_relative "herringbone/io_buffer_support"
46
- require_relative "herringbone/codecs/snappy"
47
- require_relative "herringbone/codecs/lz4"
48
- require_relative "herringbone/codecs/lzo"
49
- require_relative "herringbone/thrift"
50
- require_relative "herringbone/format"
51
- require_relative "herringbone/encodings/rle"
52
- require_relative "herringbone/encodings/plain"
53
- require_relative "herringbone/encodings/delta"
54
- require_relative "herringbone/compression"
55
- require_relative "herringbone/types"
56
- require_relative "herringbone/schema"
57
- require_relative "herringbone/active_record"
58
- require_relative "herringbone/reader"
59
- require_relative "herringbone/byte_values"
60
- require_relative "herringbone/writer"
61
- require_relative "herringbone/inferring_writer"
62
- require_relative "herringbone/simple_writer"
63
- require_relative "herringbone/xxhash"
64
- require_relative "herringbone/bloom_filter"
65
- require_relative "herringbone/inspector"
66
- require_relative "herringbone/visualizer"
67
- require_relative "herringbone/redaction"
48
+ module Herringbone
49
+ # Everything else loads on first use, so a process that only reads plain files never loads the
50
+ # writer, the inspector or OpenSSL. Herringbone.eager_load! loads it all (Ractors on Ruby < 3.4
51
+ # need that: they cannot autoload).
52
+
53
+ # Directory holding the files that are autoloaded
54
+ LIB = File.expand_path("herringbone", __dir__)
55
+ private_constant :LIB
56
+
57
+ autoload :BloomFilter, "#{LIB}/bloom_filter"
58
+ autoload :ByteValues, "#{LIB}/byte_values"
59
+ autoload :Compression, "#{LIB}/compression"
60
+ autoload :DecryptionConfiguration, "#{LIB}/encryption_configuration"
61
+ autoload :Encryption, "#{LIB}/encryption"
62
+ autoload :EncryptionConfiguration, "#{LIB}/encryption_configuration"
63
+ autoload :Format, "#{LIB}/format"
64
+ autoload :InferringWriter, "#{LIB}/inferring_writer"
65
+ autoload :Inspector, "#{LIB}/inspector"
66
+ autoload :IOBufferSupport, "#{LIB}/io_buffer_support"
67
+ autoload :Key, "#{LIB}/key"
68
+ autoload :MissingCodecError, "#{LIB}/compression"
69
+ autoload :Reader, "#{LIB}/reader"
70
+ autoload :Redaction, "#{LIB}/redaction"
71
+ autoload :Schema, "#{LIB}/schema"
72
+ autoload :SimpleWriter, "#{LIB}/simple_writer"
73
+ autoload :Thrift, "#{LIB}/thrift"
74
+ autoload :Types, "#{LIB}/types"
75
+ autoload :Visualizer, "#{LIB}/visualizer"
76
+ autoload :Writer, "#{LIB}/writer"
77
+ autoload :XXHash, "#{LIB}/xxhash"
78
+
79
+ module Codecs
80
+ autoload :LZ4, "#{LIB}/codecs/lz4"
81
+ autoload :LZO, "#{LIB}/codecs/lzo"
82
+ autoload :Snappy, "#{LIB}/codecs/snappy"
83
+ end
84
+
85
+ module Encodings
86
+ autoload :ByteStreamSplit, "#{LIB}/encodings/delta"
87
+ autoload :Delta, "#{LIB}/encodings/delta"
88
+ autoload :Plain, "#{LIB}/encodings/plain"
89
+ autoload :RLE, "#{LIB}/encodings/rle"
90
+ end
91
+
92
+ # Loads every part of Herringbone now instead of on first use. Ractors cannot autoload before
93
+ # Ruby 3.4, so call this before starting Ractors that use Herringbone there; it also moves the
94
+ # loading out of the first request in a forking server.
95
+ #
96
+ # @return [void]
97
+ def self.eager_load!
98
+ seen = {}
99
+ walk = lambda do |mod|
100
+ next if seen[mod]
101
+ seen[mod] = true
102
+ mod.constants(false).each do |name|
103
+ value = mod.const_get(name, false)
104
+ walk.call(value) if value.is_a?(Module) && value.name&.start_with?("Herringbone::")
105
+ end
106
+ end
107
+ walk.call(self)
108
+ end
109
+ end
68
110
 
69
111
  module Herringbone
70
112
  module_function
@@ -86,6 +128,7 @@ module Herringbone
86
128
  # @param schema [Schema, nil] schema to write with; derived from +records+ when nil
87
129
  # @param options [Hash{Symbol => Object}] passed to Writer.new
88
130
  # @option options [Symbol] :compression (:snappy) codec, see Herringbone.codecs
131
+ # @option options [Integer, nil] :compression_level (nil) level for :zstd, :gzip or :brotli
89
132
  # @option options [Integer] :row_group_bytes (16MB) approximate buffered size that triggers a row group
90
133
  # @option options [Integer, nil] :row_group_rows (nil) also flush a row group after this many rows
91
134
  # @option options [Integer] :page_bytes (1MB) approximate uncompressed data page size
@@ -147,6 +190,7 @@ module Herringbone
147
190
  # @param writer_options [Hash{Symbol => Object}] Writer options for re-encoded column chunks, and
148
191
  # +metadata:+ to replace the footer key/value metadata, see Redaction#apply
149
192
  # @option writer_options [Symbol] :compression (codec of each source chunk) codec for re-encoded chunks
193
+ # @option writer_options [Integer, nil] :compression_level (nil) level for that codec, see Writer
150
194
  # @option writer_options [Boolean, Array<String>, Hash{String => Boolean, Hash}] :bloom_filters (nil)
151
195
  # columns whose re-encoded chunks get a bloom filter, besides those whose source chunk had one
152
196
  # @option writer_options [Hash{String => String}] :metadata (the input's) footer key/value metadata
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: herringbone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-10-02 00:00:00.000000000 Z
10
+ date: 2026-10-04 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bigdecimal
@@ -35,6 +35,7 @@ extra_rdoc_files: []
35
35
  files:
36
36
  - CHANGELOG.md
37
37
  - LICENSE
38
+ - MANUAL.md
38
39
  - README.md
39
40
  - bin/herringbone
40
41
  - lib/herringbone.rb
@@ -48,11 +49,15 @@ files:
48
49
  - lib/herringbone/encodings/delta.rb
49
50
  - lib/herringbone/encodings/plain.rb
50
51
  - lib/herringbone/encodings/rle.rb
52
+ - lib/herringbone/encryption.rb
53
+ - lib/herringbone/encryption_configuration.rb
51
54
  - lib/herringbone/format.rb
52
55
  - lib/herringbone/inferring_writer.rb
53
56
  - lib/herringbone/inspector.rb
54
57
  - lib/herringbone/io_buffer_support.rb
58
+ - lib/herringbone/key.rb
55
59
  - lib/herringbone/reader.rb
60
+ - lib/herringbone/reader/bloom_filters.rb
56
61
  - lib/herringbone/reader/column_chunk_reader.rb
57
62
  - lib/herringbone/reader/column_cursor.rb
58
63
  - lib/herringbone/reader/numo.rb