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 a 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.

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.



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 209

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 do
      read_all_values.each do |key, _, pos|
        @positions[key] = pos
      end
    end
  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.



207
208
209
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 207

def capacity
  @capacity
end

#positionsObject (readonly)

Returns the value of attribute positions.



207
208
209
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 207

def positions
  @positions
end

#usedObject (readonly)

Returns the value of attribute used.



207
208
209
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 207

def used
  @used
end

Instance Method Details

#all_valuesObject

Yield (key, value, pos). No locking is performed.



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

def all_values
  with_file_lock do
    read_all_values.map { |k, v, p| [k, v] }
  end
end

#closeObject



261
262
263
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 261

def close
  @f.close
end

#read_value(key) ⇒ Object



240
241
242
243
244
245
246
247
248
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 240

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



265
266
267
268
269
270
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 265

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

#write_value(key, value) ⇒ Object



250
251
252
253
254
255
256
257
258
259
# File 'lib/prometheus/client/data_stores/direct_file_store.rb', line 250

def write_value(key, value)
  if !@positions.has_key?(key)
    init_value(key)
  end

  pos = @positions[key]
  @f.seek(pos)
  @f.write([value].pack('d'))
  @f.flush
end