Class: FixWidthTable
- Inherits:
-
Object
- Object
- FixWidthTable
- Defined in:
- lib/rbbt/fix_width_table.rb
Instance Attribute Summary collapse
-
#file ⇒ Object
Returns the value of attribute file.
-
#filename ⇒ Object
Returns the value of attribute filename.
-
#mask ⇒ Object
Returns the value of attribute mask.
-
#range ⇒ Object
Returns the value of attribute range.
-
#record_size ⇒ Object
Returns the value of attribute record_size.
-
#size ⇒ Object
Returns the value of attribute size.
-
#value_size ⇒ Object
Returns the value of attribute value_size.
-
#write ⇒ Object
Returns the value of attribute write.
Class Method Summary collapse
Instance Method Summary collapse
- #[](pos) ⇒ Object
- #add(pos, value) ⇒ Object
-
#add_point(data) ⇒ Object
{{{ Adding data.
- #add_range(data) ⇒ Object
- #add_range_point(pos, value) ⇒ Object
- #chunked_values_at(keys, max = 5000) ⇒ Object
- #close ⇒ Object
-
#closest(pos) ⇒ Object
{{{ Searching.
- #dump ⇒ Object
- #format(pos, value) ⇒ Object
- #get_point(pos) ⇒ Object
- #get_range(pos) ⇒ Object
-
#initialize(filename, value_size = nil, range = nil, update = false, in_memory = true) ⇒ FixWidthTable
constructor
A new instance of FixWidthTable.
- #last_pos ⇒ Object
- #overlap(index) ⇒ Object
- #persistence_path ⇒ Object
- #persistence_path=(value) ⇒ Object
- #pos(index) ⇒ Object
- #pos_end(index) ⇒ Object
- #read(force = false) ⇒ Object
- #value(index) ⇒ Object
- #values_at(*list) ⇒ Object
- #write? ⇒ Boolean
Constructor Details
#initialize(filename, value_size = nil, range = nil, update = false, in_memory = true) ⇒ FixWidthTable
Returns a new instance of FixWidthTable.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/rbbt/fix_width_table.rb', line 4 def initialize(filename, value_size = nil, range = nil, update = false, in_memory = true) @filename = filename if update or %w(memory stringio).include?(filename.to_s.downcase) or not File.exists?(filename) Log.debug "FixWidthTable create: #{ filename }" @value_size = value_size @range = range @record_size = @value_size + (@range ? 16 : 8) @write = true if %w(memory stringio).include? filename.to_s.downcase @filename = :memory @file = StringIO.new else FileUtils.rm @filename if File.exists? @filename FileUtils.mkdir_p File.dirname(@filename) unless File.exists? @filename @file = File.open(@filename, 'wb') end @file.write [value_size].pack("L") @file.write [@range ? 1 : 0 ].pack("C") @size = 0 else Log.debug "FixWidthTable up-to-date: #{ filename }" if in_memory @file = StringIO.new(Open.read(@filename, :mode => 'r:ASCII-8BIT'), 'r') else @file = File.open(@filename, 'r:ASCII-8BIT') end @value_size = @file.read(4).unpack("L").first @range = @file.read(1).unpack("C").first == 1 @record_size = @value_size + (@range ? 16 : 8) @write = false @size = (File.size(@filename) - 5) / (@record_size) end @mask = "a#{@value_size}" end |
Instance Attribute Details
#file ⇒ Object
Returns the value of attribute file.
3 4 5 |
# File 'lib/rbbt/fix_width_table.rb', line 3 def file @file end |
#filename ⇒ Object
Returns the value of attribute filename.
3 4 5 |
# File 'lib/rbbt/fix_width_table.rb', line 3 def filename @filename end |
#mask ⇒ Object
Returns the value of attribute mask.
3 4 5 |
# File 'lib/rbbt/fix_width_table.rb', line 3 def mask @mask end |
#range ⇒ Object
Returns the value of attribute range.
3 4 5 |
# File 'lib/rbbt/fix_width_table.rb', line 3 def range @range end |
#record_size ⇒ Object
Returns the value of attribute record_size.
3 4 5 |
# File 'lib/rbbt/fix_width_table.rb', line 3 def record_size @record_size end |
#size ⇒ Object
Returns the value of attribute size.
3 4 5 |
# File 'lib/rbbt/fix_width_table.rb', line 3 def size @size end |
#value_size ⇒ Object
Returns the value of attribute value_size.
3 4 5 |
# File 'lib/rbbt/fix_width_table.rb', line 3 def value_size @value_size end |
#write ⇒ Object
Returns the value of attribute write.
3 4 5 |
# File 'lib/rbbt/fix_width_table.rb', line 3 def write @write end |
Class Method Details
.get(filename, value_size = nil, range = nil, update = false) ⇒ Object
57 58 59 60 61 62 63 64 65 |
# File 'lib/rbbt/fix_width_table.rb', line 57 def self.get(filename, value_size = nil, range = nil, update = false) return self.new(filename, value_size, range, update) if filename == :memory case when (!File.exists?(filename) or update or not Persist::CONNECTIONS.include?(filename)) Persist::CONNECTIONS[filename] = self.new(filename, value_size, range, update) end Persist::CONNECTIONS[filename] end |
Instance Method Details
#[](pos) ⇒ Object
256 257 258 259 260 261 262 263 |
# File 'lib/rbbt/fix_width_table.rb', line 256 def [](pos) return [] if size == 0 if range get_range(pos) else get_point(pos) end end |
#add(pos, value) ⇒ Object
76 77 78 79 80 81 |
# File 'lib/rbbt/fix_width_table.rb', line 76 def add(pos, value) format = format(pos, value) @file.write format @size += 1 end |
#add_point(data) ⇒ Object
{{{ Adding data
134 135 136 137 138 |
# File 'lib/rbbt/fix_width_table.rb', line 134 def add_point(data) data.sort_by{|value, pos| pos }.each do |value, pos| add pos, value end end |
#add_range(data) ⇒ Object
150 151 152 153 154 155 |
# File 'lib/rbbt/fix_width_table.rb', line 150 def add_range(data) @latest = [] data.sort_by{|value, pos| pos[0] }.each do |value, pos| add_range_point(pos, value) end end |
#add_range_point(pos, value) ⇒ Object
140 141 142 143 144 145 146 147 148 |
# File 'lib/rbbt/fix_width_table.rb', line 140 def add_range_point(pos, value) @latest ||= [] while @latest.any? and @latest[0] < pos[0] @latest.shift end overlap = @latest.length add pos + [overlap], value @latest << pos[1] end |
#chunked_values_at(keys, max = 5000) ⇒ Object
272 273 274 275 276 277 278 |
# File 'lib/rbbt/fix_width_table.rb', line 272 def chunked_values_at(keys, max = 5000) Misc.ordered_divide(keys, max).inject([]) do |acc,c| new = self.values_at(*c) new.annotate acc if new.respond_to? :annotate and acc.empty? acc.concat(new) end end |
#close ⇒ Object
121 122 123 124 |
# File 'lib/rbbt/fix_width_table.rb', line 121 def close @write = false @file.close end |
#closest(pos) ⇒ Object
{{{ Searching
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/rbbt/fix_width_table.rb', line 159 def closest(pos) upper = size - 1 lower = 0 return -1 if upper < lower while(upper >= lower) do idx = lower + (upper - lower) / 2 pos_idx = pos(idx) case pos <=> pos_idx when 0 break when -1 upper = idx - 1 when 1 lower = idx + 1 end end if pos_idx > pos idx = idx - 1 end idx.to_i end |
#dump ⇒ Object
126 127 128 129 130 |
# File 'lib/rbbt/fix_width_table.rb', line 126 def dump read @file.rewind @file.read end |
#format(pos, value) ⇒ Object
67 68 69 70 71 72 73 74 |
# File 'lib/rbbt/fix_width_table.rb', line 67 def format(pos, value) padding = value_size - value.length if range (pos + [padding, value + ("\0" * padding)]).pack("llll#{mask}") else [pos, padding, value + ("\0" * padding)].pack("ll#{mask}") end end |
#get_point(pos) ⇒ Object
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/rbbt/fix_width_table.rb', line 222 def get_point(pos) if Range === pos r_start = pos.begin r_end = pos.end else r_start = pos.to_i r_end = pos.to_i end idx = closest(r_start) return [] if idx >= size return [] if idx <0 and r_start == r_end idx = 0 if idx < 0 idx += 1 unless pos(idx) >= r_start return [] if idx >= size values = [] l_start = pos(idx) l_end = pos_end(idx) while l_start <= r_end values << value(idx) idx += 1 break if idx >= size l_start = pos(idx) l_end = pos_end(idx) end values end |
#get_range(pos) ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/rbbt/fix_width_table.rb', line 186 def get_range(pos) case pos when Range r_start = pos.begin r_end = pos.end when Array r_start, r_end = pos else r_start, r_end = pos, pos end idx = closest(r_start) return [] if idx >= size return [] if idx <0 and r_start == r_end idx = 0 if idx < 0 overlap = overlap(idx) idx -= overlap unless overlap.nil? values = [] l_start = pos(idx) l_end = pos_end(idx) while l_start <= r_end values << value(idx) if l_end >= r_start idx += 1 break if idx >= size l_start = pos(idx) l_end = pos_end(idx) end values end |
#last_pos ⇒ Object
83 84 85 |
# File 'lib/rbbt/fix_width_table.rb', line 83 def last_pos pos(size - 1) end |
#overlap(index) ⇒ Object
99 100 101 102 103 |
# File 'lib/rbbt/fix_width_table.rb', line 99 def overlap(index) return nil if index < 0 or index >= size @file.seek(13 + (record_size) * index, IO::SEEK_SET) @file.read(4).unpack("l").first end |
#persistence_path ⇒ Object
49 50 51 |
# File 'lib/rbbt/fix_width_table.rb', line 49 def persistence_path @filename end |
#persistence_path=(value) ⇒ Object
53 54 55 |
# File 'lib/rbbt/fix_width_table.rb', line 53 def persistence_path=(value) @filename=value end |
#pos(index) ⇒ Object
87 88 89 90 91 |
# File 'lib/rbbt/fix_width_table.rb', line 87 def pos(index) return nil if index < 0 or index >= size @file.seek(5 + (record_size) * index, IO::SEEK_SET) @file.read(4).unpack("l").first end |
#pos_end(index) ⇒ Object
93 94 95 96 97 |
# File 'lib/rbbt/fix_width_table.rb', line 93 def pos_end(index) return nil if index < 0 or index >= size @file.seek(9 + (record_size) * index, IO::SEEK_SET) @file.read(4).unpack("l").first end |
#read(force = false) ⇒ Object
114 115 116 117 118 119 |
# File 'lib/rbbt/fix_width_table.rb', line 114 def read(force = false) return if @filename == :memory @write = false @file.close unless @file.closed? @file = File.open(filename, 'r:ASCII-8BIT') end |
#value(index) ⇒ Object
105 106 107 108 109 110 111 112 |
# File 'lib/rbbt/fix_width_table.rb', line 105 def value(index) return nil if index < 0 or index >= size @file.seek((range ? 17 : 9 ) + (record_size) * index, IO::SEEK_SET) padding = @file.read(4).unpack("l").first+1 txt = @file.read(value_size) str = txt.unpack(mask).first padding > 1 ? str[0..-padding] : str end |
#values_at(*list) ⇒ Object
266 267 268 269 270 |
# File 'lib/rbbt/fix_width_table.rb', line 266 def values_at(*list) list.collect{|pos| self[pos] } end |
#write? ⇒ Boolean
45 46 47 |
# File 'lib/rbbt/fix_width_table.rb', line 45 def write? @write end |