module Redlics::Key

Key namespace

Public Instance Methods

bucketize?(context, options = {}) click to toggle source

Check if Redlics can bucketize.

@param context [Hash] the hash of a context defined in Redlics::CONTEXTS @param options [Hash] configuration options @return [Boolean] true if can bucketize, false if not

# File lib/redlics/key.rb, line 102
def bucketize?(context, options = {})
  context[:long] == :counter && Redlics.config.bucket && !options[:id].nil?
end
decode(string) click to toggle source

Decode a number with a mapping table.

@param string [String] the string to encode @return [Integer] the decoded string as integer

# File lib/redlics/key.rb, line 77
def decode(string)
  decoded = ''
  string = string.to_s
  token = 0
  while token <= string.size - 1
    number = decode_map[string[token]].to_s
    decoded += number.size == 1 ? "0#{number}" : number
    token += 1
  end
  decoded.to_i
end
encode(number) click to toggle source

Encode a number with a mapping table.

@param number [Integer] the number to encode @return [String] the encoded number as string

# File lib/redlics/key.rb, line 61
def encode(number)
  encoded = ''
  number = number.to_s
  number = (number.size % 2) != 0 ? "0#{number}" : number
  token = 0
  while token <= number.size - 1
    encoded += encode_map[number[token..token+1].to_i.to_s].to_s
    token += 2
  end
  encoded
end
exists?(key) click to toggle source

Check if a key exists in Redis.

@param string [String] the key name to check @return [Boolean] true id key exists, false if not

# File lib/redlics/key.rb, line 93
def exists?(key)
  Redlics.redis { |r| r.exists(key) }
end
name(context, event, granularity, past, options = {}) click to toggle source

Construct the key name with given parameters.

@param context [Hash] the hash of a context defined in Redlics::CONTEXTS @param event [String] event name with eventual Redis namespace separator @param granularity [Symbol] existing granularity @param past [Time] a time object @param options [Hash] configuration options @return [String] unbucketized key name @return [Array] bucketized key name

# File lib/redlics/key.rb, line 17
def name(context, event, granularity, past, options = {})
  past ||= Time.now
  event ||= 'nil'
  granularity = Granularity.validate(context, granularity).first
  event = encode_event(event) if Redlics.config.encode[:events]
  key = "#{context[:short]}#{Redlics.config.separator}#{event}#{Redlics.config.separator}#{time_format(granularity, past)}"
  key = with_namespace(key) if options[:namespaced]
  return bucketize(key, options[:id]) if bucketize?(context, options)
  return unbucketize(key, options[:id]) if context[:long] == :counter && !options[:id].nil?
  key
end
timeframed(context, event, time_object, options = {}) click to toggle source

Construct an array with all keys of a time frame in a given granularity.

@param context [Hash] the hash of a context defined in Redlics::CONTEXTS @param event [String] event name with eventual Redis namespace separator @param time_object [Symbol] time object predefined in Redlics::TimeFrame.init_with_symbol @param time_object [Hash] time object with keys ‘from` and `to` @param time_object [Range] time object as range @param time_object [Time] time object @param options [Hash] configuration options @return [Array] array with all keys of a time frame in a given granularity

# File lib/redlics/key.rb, line 39
def timeframed(context, event, time_object, options = {})
  options = { namespaced: true }.merge(options)
  timeframe = TimeFrame.new(context, time_object, options)
  timeframe.splat do |time|
    name(context, event, timeframe.granularity, time, options)
  end
end
unique_namespace() click to toggle source

Create a unique operation key in Redis. @return [String] the created unique operation key

# File lib/redlics/key.rb, line 108
def unique_namespace
  loop do
    ns = operation
    unless exists?(ns)
      Redlics.redis do |conn|
        conn.pipelined do |redis|
          redis.set(ns, 0)
          redis.expire(ns, Redlics.config.operation_expiration)
        end
      end
      break ns
    end
  end
end
with_namespace(key) click to toggle source

Prepend namespace to a key.

@param key [String] the key name @return [String] the key name with prepended namespace

# File lib/redlics/key.rb, line 51
def with_namespace(key)
  return key unless Redlics.config.namespace.length > 0
  return key if key.split(Redlics.config.separator).first == Redlics.config.namespace.to_s
  "#{Redlics.config.namespace}#{Redlics.config.separator}#{key}"
end

Private Instance Methods

bucketize(key, id) click to toggle source

Bucketize key name with id.

@param key [String] key name @param id [Integer] object id @return [Array] bucketized key name and value

# File lib/redlics/key.rb, line 153
def bucketize(key, id)
  bucket = id.to_i / Redlics.config.bucket_size.to_i
  value = id.to_i % Redlics.config.bucket_size.to_i
  if Redlics.config.encode[:ids]
    bucket = encode(bucket)
    value = encode(value)
  end
  ["#{key}#{Redlics.config.separator}#{bucket}", value]
end
decode_map() click to toggle source

Defined decode map. @return [Hash] the decode map with numbers as values

# File lib/redlics/key.rb, line 191
def decode_map
  @decode_map ||= replace_separator_decode({
    '1' =>  '0', '2' =>  '1', '3' =>  '2', '4' =>  '3', '5' =>  '4', '6' =>  '5', '7' =>  '6', '8' =>  '7', '9' =>  '8', '0' =>  '9',
    '-' => '10', '=' => '11', '!' => '12', '@' => '13', '#' => '14', '$' => '15', '%' => '16', '^' => '17', '&' => '18', '*' => '19',
    '(' => '20', ')' => '21', '_' => '22', '+' => '23', 'a' => '24', 'b' => '25', 'c' => '26', 'd' => '27', 'e' => '28', 'f' => '29',
    'g' => '30', 'h' => '31', 'i' => '32', 'j' => '33', 'k' => '34', 'l' => '35', 'm' => '36', 'n' => '37', 'o' => '38', 'p' => '39',
    'q' => '40', 'r' => '41', 's' => '42', 't' => '43', 'u' => '44', 'v' => '45', 'w' => '46', 'x' => '47', 'y' => '48', 'z' => '49',
    'A' => '50', 'B' => '51', 'C' => '52', 'D' => '53', 'E' => '54', 'F' => '55', 'G' => '56', 'H' => '57', 'I' => '58', 'J' => '59',
    'K' => '60', 'L' => '61', 'M' => '62', 'N' => '63', 'O' => '64', 'P' => '65', 'Q' => '66', 'R' => '67', 'S' => '68', 'T' => '69',
    'U' => '70', 'V' => '71', 'W' => '72', 'X' => '73', 'Y' => '74', 'Z' => '75', '[' => '76', ']' => '77', '\\' => '78', ';' => '79',
    ',' => '80', '.' => '81', '/' => '82', '{' => '83', '}' => '84', '|' => '85', '§' => '86', '<' => '87', '>' => '88', '?' => '89',
    '`' => '90', '~' => '91', 'ä' => '92', 'Ä' => '93', 'ü' => '94', 'Ü' => '95', 'ö' => '96', 'Ö' => '97', 'é' => '98', 'É' => '99' }).freeze
end
encode_event(event) click to toggle source

Encode ids in event names.

@param event [String] event name with eventual Redis namespace separator @return [String] event name with encoded ids

# File lib/redlics/key.rb, line 144
def encode_event(event)
  event.to_s.split(Redlics.config.separator).map { |v| v.match(/\A\d+\z/) ? encode(v) : v }.join(Redlics.config.separator)
end
encode_map() click to toggle source

Defined encode map. @return [Hash] the encode map with numbers as keys

# File lib/redlics/key.rb, line 175
def encode_map
  @encode_map ||= replace_separator_encode({
     '0' => '1',  '1' => '2',  '2' => '3',  '3' => '4',  '4' => '5',  '5' => '6',  '6' => '7',  '7' => '8',  '8' => '9',  '9' => '0',
    '10' => '-', '11' => '=', '12' => '!', '13' => '@', '14' => '#', '15' => '$', '16' => '%', '17' => '^', '18' => '&', '19' => '*',
    '20' => '(', '21' => ')', '22' => '_', '23' => '+', '24' => 'a', '25' => 'b', '26' => 'c', '27' => 'd', '28' => 'e', '29' => 'f',
    '30' => 'g', '31' => 'h', '32' => 'i', '33' => 'j', '34' => 'k', '35' => 'l', '36' => 'm', '37' => 'n', '38' => 'o', '39' => 'p',
    '40' => 'q', '41' => 'r', '42' => 's', '43' => 't', '44' => 'u', '45' => 'v', '46' => 'w', '47' => 'x', '48' => 'y', '49' => 'z',
    '50' => 'A', '51' => 'B', '52' => 'C', '53' => 'D', '54' => 'E', '55' => 'F', '56' => 'G', '57' => 'H', '58' => 'I', '59' => 'J',
    '60' => 'K', '61' => 'L', '62' => 'M', '63' => 'N', '64' => 'O', '65' => 'P', '66' => 'Q', '67' => 'R', '68' => 'S', '69' => 'T',
    '70' => 'U', '71' => 'V', '72' => 'W', '73' => 'X', '74' => 'Y', '75' => 'Z', '76' => '[', '77' => ']', '78' => '\\', '79' => ';',
    '80' => ',', '81' => '.', '82' => '/', '83' => '{', '84' => '}', '85' => '|', '86' => '§', '87' => '<', '88' => '>', '89' => '?',
    '90' => '`', '91' => '~', '92' => 'ä', '93' => 'Ä', '94' => 'ü', '95' => 'Ü', '96' => 'ö', '97' => 'Ö', '98' => 'é', '99' => 'É' }).freeze
end
operation() click to toggle source

Create a operation key. @return [String] the created operation key

# File lib/redlics/key.rb, line 127
def operation
  "#{Redlics::CONTEXTS[:operation][:short]}#{Redlics.config.separator}#{SecureRandom.uuid}"
end
replace_separator_decode(map) click to toggle source

Replace defined separator in configuration from the decode map.

@param map [Hash] decode map hash @return [Hash] decode map hash without defined separator in configuration.

# File lib/redlics/key.rb, line 221
def replace_separator_decode(map)
  unless Redlics.config.separator == ':'
    key = Redlics.config.separator.to_s.to_sym
    map[':'.to_sym] = map.delete(key) if map.key?(key)
  end
  map
end
replace_separator_encode(map) click to toggle source

Replace defined separator in configuration from the encode map.

@param map [Hash] encode map hash @return [Hash] encode map hash without defined separator in configuration.

# File lib/redlics/key.rb, line 209
def replace_separator_encode(map)
  unless Redlics.config.separator == ':'
    key = map.key(Redlics.config.separator)
    map[key] = ':' if key
  end
  map
end
time_format(granularity, past) click to toggle source

Get the time format pattern of a granularity.

@param granularity [Symbol] existing granularity @param past [Time] a time object @return [String] pattern of defined granularity

# File lib/redlics/key.rb, line 136
def time_format(granularity, past)
  past.strftime(Redlics.config.granularities[granularity][:pattern])
end
unbucketize(key, id) click to toggle source

Unbucketize key name with id. Encode the id if configured to encode.

@param key [String] key name @param id [Integer] object id @return [String] unbucketized key name with eventual encoded object id

# File lib/redlics/key.rb, line 168
def unbucketize(key, id)
  id = encode(id) if Redlics.config.encode[:ids]
  "#{key}#{Redlics.config.separator}#{id}"
end