module SplitIoClient module Cache module Repositories module Metrics class MemoryRepository OPERATIONS = %w(sdk.get_treatment sdk.get_treatments sdk.get_treatment_with_config sdk.get_treatments_with_config) def initialize(_ = nil, config) @counts = [] @latencies = [] @gauges = [] @config = config end def add_count(counter, delta) counter_hash = @counts.find { |c| c[:name] == counter } if counter_hash.nil? counter_delta = SumAndCount.new counter_delta.add_delta(delta) @counts << { name: counter, delta: counter_delta } else counter_hash[:delta].add_delta(delta) end end def add_latency(operation, time_in_ms, binary_search) if (OPERATIONS.include?(operation)) index = binary_search.add_latency_millis(time_in_ms, true) increase_latency_bucket(operation, index) else concatenate_latency(operation, time_in_ms) end end def add_gauge(gauge, value) gauge_hash = @gauges.find { |g| g[:name] == gauge } if gauge_hash.nil? gauge_value = ValueAndCount.new gauge_value.set_value(value) @gauges << { name: gauge, value: gauge_value } else gauge_hash[:value].set_value(value) end end def counts @counts.each_with_object({}) do |count, memo| memo[count[:name]] = count[:delta].sum end end def latencies @latencies.each_with_object({}) do |latency, memo| memo[latency[:operation]] = latency[:latencies] end end def gauges # TODO end def fix_latencies # NOOP end def clear_counts @counts = [] end def clear_latencies @latencies = [] end def clear_gauges @gauges = [] end def clear clear_counts clear_latencies clear_gauges end # # small class to act as DTO for counts # class SumAndCount attr_reader :count attr_reader :sum def initialize @count = 0 @sum = 0 end def add_delta(delta) @count += 1 @sum += delta end def clear @count = 0 @sum = 0 end end # # small class to act as DTO for gauges # class ValueAndCount attr_reader :count attr_reader :value def initialize @count = 0 @value = 0 end def set_value(value) @count += 1 @value = value end def clear @count = 0 @value = 0 end end private def increase_latency_bucket(operation, index) operation_latencies = find_operation_latencies(operation) if (operation_latencies.nil?) latencies_array = Array.new(BinarySearchLatencyTracker::BUCKETS.length, 0) latencies_array[index] = 1 @latencies << { operation: operation, latencies: latencies_array } else operation_latencies[:latencies][index] += 1 end end def concatenate_latency(operation, time_in_ms) operation_latencies = find_operation_latencies(operation) if (operation_latencies.nil?) @latencies << { operation: operation, latencies: [time_in_ms] } else operation_latencies[:latencies].push(time_in_ms) end end def find_operation_latencies(operation) @latencies.find { |l| l[:operation] == operation unless l.nil? } end end end end end end