Class: Prometheus::Client::DataStores::DirectFileStore::FileMappedDict
- Inherits:
-
Object
- Object
- Prometheus::Client::DataStores::DirectFileStore::FileMappedDict
- Defined in:
- lib/prometheus/client/data_stores/direct_file_store.rb
Overview
A dict of doubles, backed by an file we access directly as a byte array.
The file starts with a 4 byte int, indicating how much of it is used. Then 4 bytes of padding. There’s then a number of entries, consisting of a 4 byte int which is the size of the next field, a utf-8 encoded string key, padding to an 8 byte alignment, and then a 8 byte float which is the value, and then a 8 byte float which is the unix timestamp when the value was set.
Constant Summary collapse
- INITIAL_FILE_SIZE =
1024*1024
Instance Attribute Summary collapse
-
#capacity ⇒ Object
readonly
Returns the value of attribute capacity.
-
#positions ⇒ Object
readonly
Returns the value of attribute positions.
-
#used ⇒ Object
readonly
Returns the value of attribute used.
Instance Method Summary collapse
-
#all_values ⇒ Object
Return a list of key-value pairs.
- #close ⇒ Object
- #increment_value(key, by) ⇒ Object
-
#initialize(filename, readonly = false) ⇒ FileMappedDict
constructor
A new instance of FileMappedDict.
- #read_value(key) ⇒ Object
- #with_file_lock ⇒ Object
- #write_value(key, value) ⇒ Object
Constructor Details
#initialize(filename, readonly = false) ⇒ FileMappedDict
Returns a new instance of FileMappedDict.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 235 def initialize(filename, readonly = false) @positions = {} @used = 0 open_file(filename, readonly) @used = @f.read(4).unpack('l')[0] if @capacity > 0 if @used > 0 # File already has data. Read the existing values with_file_lock { populate_positions } else # File is empty. Init the `used` counter, if we're in write mode if !readonly @used = 8 @f.seek(0) @f.write([@used].pack('l')) end end end |
Instance Attribute Details
#capacity ⇒ Object (readonly)
Returns the value of attribute capacity.
233 234 235 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 233 def capacity @capacity end |
#positions ⇒ Object (readonly)
Returns the value of attribute positions.
233 234 235 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 233 def positions @positions end |
#used ⇒ Object (readonly)
Returns the value of attribute used.
233 234 235 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 233 def used @used end |
Instance Method Details
#all_values ⇒ Object
Return a list of key-value pairs
256 257 258 259 260 261 262 263 264 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 256 def all_values with_file_lock do @positions.map do |key, pos| @f.seek(pos) value, = @f.read(16).unpack('dd') [key, value, ] end end end |
#close ⇒ Object
303 304 305 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 303 def close @f.close end |
#increment_value(key, by) ⇒ Object
288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 288 def increment_value(key, by) if !@positions.has_key?(key) init_value(key) end pos = @positions[key] @f.seek(pos) value = @f.read(8).unpack('d')[0] now = Process.clock_gettime(Process::CLOCK_MONOTONIC) @f.seek(-8, :CUR) @f.write([value + by, now].pack('dd')) @f.flush end |
#read_value(key) ⇒ Object
266 267 268 269 270 271 272 273 274 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 266 def read_value(key) if !@positions.has_key?(key) init_value(key) end pos = @positions[key] @f.seek(pos) @f.read(8).unpack('d')[0] end |
#with_file_lock ⇒ Object
307 308 309 310 311 312 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 307 def with_file_lock @f.flock(File::LOCK_EX) yield ensure @f.flock(File::LOCK_UN) end |
#write_value(key, value) ⇒ Object
276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 276 def write_value(key, value) if !@positions.has_key?(key) init_value(key) end now = Process.clock_gettime(Process::CLOCK_MONOTONIC) pos = @positions[key] @f.seek(pos) @f.write([value, now].pack('dd')) @f.flush end |