Class: Readorder::Results
- Inherits:
-
Object
- Object
- Readorder::Results
- Defined in:
- lib/readorder/results.rb
Overview
Results persists the results from a readorder run The results are persisted in an SQlite3 database which allows for ordering the results by whatever means are wanted.
Class Method Summary collapse
Instance Method Summary collapse
-
#add_datum(datum) ⇒ Object
:call-seq: results.add_datum( datum ).
- #close ⇒ Object
-
#each_error(&block) ⇒ Object
:call-seq: results.each_error { |e| … }.
-
#each_valid(&block) ⇒ Object
:call-seq: results.each_valid { |v| … }.
-
#each_valid_by_field(field, &block) ⇒ Object
:call-seq: results.each_valid_by_field( field ) { |v| … }.
-
#each_valid_by_first_physical_block_number(&block) ⇒ Object
:call-seq: results.each_valid_by_physical_block_number { |v| … }.
-
#each_valid_by_inode_number(&block) ⇒ Object
:call-seq: results.each_valid_by_inode_number { |v| … }.
-
#error_count ⇒ Object
:call-seq: results.error_count -> Integer.
- #flush ⇒ Object
-
#flush_error ⇒ Object
:call-seq: results.flush_error.
-
#flush_valid ⇒ Object
:call-seq: results.flush_valid.
-
#has_datum_for_filename?(filename) ⇒ Boolean
:call-seq: results.has_datum_for_filename?( filename ).
-
#initialize(filename, batch_size = 1) ⇒ Results
constructor
:call-seq: Results.new( filename, 10_000 ) -> results.
- #logger ⇒ Object
-
#valid_count ⇒ Object
:call-seq: results.valid_count -> Integer.
Constructor Details
#initialize(filename, batch_size = 1) ⇒ Results
:call-seq:
Results.new( filename, 10_000 ) -> results
Create a new Results object with a batch size. The batch size is how many items to queue up to run in a single transaction into the sqlite database.
By default the batch size is 1 which is not very performant.
36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/readorder/results.rb', line 36 def initialize( filename, batch_size = 1 ) @db = Amalgalite::Database.new( filename ) unless @db.schema.tables['readorder_valid'] then logger.info "Creating tables" @db.execute_batch( Results.create_table_sql ) end @db.reload_schema! @batch_size = batch_size @valid_queue = [] @error_queue = [] end |
Class Method Details
.create_table_sql ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/readorder/results.rb', line 8 def self.create_table_sql sql = <<-SQL CREATE TABLE readorder_valid ( original_order INTEGER PRIMARY KEY NOT NULL, size INTEGER NOT NULL, inode_number INTEGER NOT NULL UNIQUE, first_physical_block_number INTEGER UNIQUE, physical_block_count INTEGER, filename TEXT NOT NULL UNIQUE ); CREATE TABLE readorder_errors ( original_order INTEGER PRIMARY KEY NOT NULL, filename TEXT NOT NULL UNIQUE, error_reason TEXT NOT NULL ); SQL end |
Instance Method Details
#add_datum(datum) ⇒ Object
:call-seq:
results.add_datum( datum )
add a datum to the database, this will insert the datum into either valid or errors depending on the state of datum.valid?
80 81 82 83 84 85 86 87 |
# File 'lib/readorder/results.rb', line 80 def add_datum( datum ) if datum.valid? @valid_queue << datum else @error_queue << datum end flush if ((@valid_queue.size + @error_queue.size) >= @batch_size ) end |
#close ⇒ Object
49 50 51 52 |
# File 'lib/readorder/results.rb', line 49 def close flush @db.close end |
#each_error(&block) ⇒ Object
:call-seq:
results.each_error { |e| ... }
Return each error record without any predefined order
217 218 219 220 221 |
# File 'lib/readorder/results.rb', line 217 def each_error( &block ) @db.execute( "SELECT * FROM readorder_errors" ) do |row| yield row end end |
#each_valid(&block) ⇒ Object
:call-seq:
results.each_valid { |v| ... }
Return each valid record without any predefined order
139 140 141 142 143 |
# File 'lib/readorder/results.rb', line 139 def each_valid( &block ) @db.execute( "SELECT * FROM readorder_valid" ) do |row| yield row end end |
#each_valid_by_field(field, &block) ⇒ Object
:call-seq:
results.each_valid_by_field( field ) { |v| ... }
171 172 173 174 175 |
# File 'lib/readorder/results.rb', line 171 def each_valid_by_field( field, &block ) @db.execute( "SELECT * from readorder_valid ORDER BY #{field} ASC" ) do |row| yield row end end |
#each_valid_by_first_physical_block_number(&block) ⇒ Object
:call-seq:
results.each_valid_by_physical_block_number { |v| ... }
Return each valid record in physical block number order
151 152 153 154 155 |
# File 'lib/readorder/results.rb', line 151 def each_valid_by_first_physical_block_number( &block ) each_valid_by_field( 'first_physical_block_number' ) do |row| block.call( row ) end end |
#each_valid_by_inode_number(&block) ⇒ Object
:call-seq:
results.each_valid_by_inode_number { |v| ... }
161 162 163 164 165 |
# File 'lib/readorder/results.rb', line 161 def each_valid_by_inode_number( &block ) each_valid_by_field( 'inode_number' ) do |row| block.call( row ) end end |
#error_count ⇒ Object
:call-seq:
results.error_count -> Integer
return the number of errors
207 208 209 |
# File 'lib/readorder/results.rb', line 207 def error_count @db.first_value_from( "SELECT count(original_order) FROM readorder_errors" ) end |
#flush ⇒ Object
54 55 56 57 |
# File 'lib/readorder/results.rb', line 54 def flush flush_valid flush_error end |
#flush_error ⇒ Object
:call-seq:
results.flush_error
Flush all the error items to disk
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/readorder/results.rb', line 182 def flush_error if @error_queue.size > 0 then logger.info "Flushing #{@error_queue.size} error items to disk" sql = <<-insert INSERT INTO readorder_errors ( original_order, filename, error_reason ) VALUES( ?, ?, ? ); insert @db.transaction do |trans| trans.prepare( sql ) do |stmt| until @error_queue.empty? do datum = @error_queue.shift stmt.execute( datum.original_order, datum.filename, datum.error_reason ) end end end end end |
#flush_valid ⇒ Object
:call-seq:
results.flush_valid
Flush all the pending valid items to the sqlite database
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/readorder/results.rb', line 95 def flush_valid if @valid_queue.size > 0 then logger.info "Flushing #{@valid_queue.size} valid items to disk" sql = <<-insert INSERT INTO readorder_valid ( original_order, size, inode_number, first_physical_block_number, physical_block_count, filename ) VALUES( ?, ?, ?, ?, ?, ? ); insert @db.transaction do |trans| trans.prepare( sql ) do |stmt| until @valid_queue.empty? do datum = @valid_queue.shift stmt.execute( datum.original_order, datum.size, datum.inode_number, datum.first_physical_block_number, datum.physical_block_count, datum.filename) end end end end end |
#has_datum_for_filename?(filename) ⇒ Boolean
:call-seq:
results.has_datum_for_filename?( filename )
return true or false if the give filename is alread in the database
69 70 71 |
# File 'lib/readorder/results.rb', line 69 def has_datum_for_filename?( filename ) @db.first_value_from( "SELECT filename FROM readorder_valid WHERE filename = ?", filename ) end |
#logger ⇒ Object
59 60 61 |
# File 'lib/readorder/results.rb', line 59 def logger Logging::Logger[ self ] end |
#valid_count ⇒ Object
:call-seq:
results.valid_count -> Integer
return the number of valid result rows
128 129 130 |
# File 'lib/readorder/results.rb', line 128 def valid_count @db.first_value_from( "SELECT count(original_order) FROM readorder_valid" ) end |