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.



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 236

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.



234
235
236
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 234

def capacity
  @capacity
end

#positionsObject (readonly)

Returns the value of attribute positions.



234
235
236
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 234

def positions
  @positions
end

#usedObject (readonly)

Returns the value of attribute used.



234
235
236
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 234

def used
  @used
end

Instance Method Details

#all_valuesObject

Return a list of key-value pairs



257
258
259
260
261
262
263
264
265
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 257

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



289
290
291
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 289

def close
  @f.close
end

#read_value(key) ⇒ Object



267
268
269
270
271
272
273
274
275
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 267

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



293
294
295
296
297
298
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 293

def with_file_lock
  @f.flock(File::LOCK_EX)
  yield
ensure
  @f.flock(File::LOCK_UN)
end

#write_value(key, value) ⇒ Object



277
278
279
280
281
282
283
284
285
286
287
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 277

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