Class: Prometheus::Client::DataStores::DirectFileStore::FileMappedDict

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

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

#capacityObject (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

#positionsObject (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

#usedObject (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_valuesObject

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, timestamp = @f.read(16).unpack('dd')
      [key, value, timestamp]
    end
  end
end

#closeObject



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_lockObject



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