Модуль:Cache

Материал из Dota 2 Вики
Перейти к: навигация, поиск

Документация для Модуль:Cache Перейти к коду ↴ [ править | очистить ]


This module provides a way of storing data between module invocations. Legal data types are strings, numbers and tables. The data gets stored as json in a variable named cargo_data. To see the stored raw json data, simply add {{#var:cargo_data}} at the end of the page.

This is useful for templates that tend to appear multiple times on the same page. Do not use this for modules that only appear a single time per page. It will lead to performance decreases.

Функции[править]

Базовые[править]

cache.auto[править]

cache.auto(func, args, prefix)

The cache.auto function is the simplest way of implementing caching. It wraps the function supplying the value and automatically decides whether to execute the function or use a cached version.


It's parameters are:

  1. The function for which caching should be applied.
  2. A table holding the functions arguments.
  3. An optional prefix for the key under which the output will be stored (useful if multiple functions have the same arguments).

In pseudo-code it would look something like this:

function cache.auto(func, args, prefix)
  if prefix_args[1]_args[2].isCached() then
    return get_cache(prefix_args[1]_args[2])
  else
    return set_cache(prefix_args[1]_args[2], func(args))
  end
end

Дополнительные[править]

Use these functions if you want to manually implement caching in your module.

cache.set[править]

cache.set(args, value, prefix)

Stores content. Logs the stored content and the variable name. Returns the content.

cache.get[править]

cache.get(args, prefix)

Retrieves content. Returns the content.

Использование[править]

local p = {}
local cache = require('Модуль:Cache')


function p.example(args)
  -- First usage of p._example(); Executes the function and stores the value.
  cache.auto(p._example, args, 'example_prefix')

  -- Second usage; Uses the cached version.
  cache.auto(p._example, args, 'example_prefix')
end

function p._example(args)
  return args[1]
end


return p

Тесты[править]

ДаД All tests passed.

Name Expected Actual
ДаД test_auto_boolean
ДаД test_auto_number
ДаД test_auto_string
ДаД test_auto_table
ДаД test_get_boolean
ДаД test_get_no_set
ДаД test_get_number
ДаД test_get_string
ДаД test_get_table
ДаД test_set_boolean
ДаД test_set_number
ДаД test_set_string
ДаД test_set_table

Зависимости

--------------------------------------------------------------------------------
-- Imports
--------------------------------------------------------------------------------

local libraryUtil = require( 'libraryUtil' )
local var = require( 'Модуль:Variables' ).var
local vardefine = require( 'Модуль:Variables' ).vardefine

--------------------------------------------------------------------------------
-- Strings
--------------------------------------------------------------------------------

local i18n = {
  error = {
    unsupported_type = 'Неподдерживаемый тип данных'
  },
  log = {
    caching = 'Не найдено кэшированной версии. Сбор данных.'
  }
}

--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------

local h = {}

--- Generate a variable unique key.
-- @param args (table): The template/module arguments.
-- @param prefix (string): A unique prefix for the cached template/module.
-- @return (string): A unique key.
function h.make_key( args, prefix )
  prefix = ( prefix or 'cache' )
  local key = { prefix }
  for _,arg in pairs( args ) do
    key[#key+1] = tostring( arg )
  end
  local key = table.concat( key, '_' )
  return mw.hash.hashValue( 'md5', key )
end

--- Convert a value into a string for caching.
-- @param value (string/number/bool/table/nil): The value to be converted
-- @return (string): The converted value.
-- @return (string): The original type.
function h.preprocess( value )
  local value_type = type( value )
  
  if value_type == 'number' or value_type == 'boolean' then
    value = tostring( value )
  elseif value_type == 'table' then
    -- Check the table for a metatable to detect mw.html and similar objects.
    local mt = getmetatable( value )
    if mt and mt.__tostring then
      value = tostring( value )
      value_type = 'string'
    else
      value = mw.text.jsonEncode( value )
    end
  elseif value_type ~= 'string' then
    error( i18n.error.unsupported_type )
  end

  return value, value_type
end

--- Convert a string value back to its original type.
-- @param value (string): The string value.
-- @param value_type (string): The original type.
-- @return (string/number/bool/table/nil): The value in its original type.
function h.process( value, value_type )
  if value_type == 'string' then
    return value
  elseif value_type == 'number' then
    return tonumber( value )
  elseif value_type == 'boolean' then
    return ( value == 'true' )
  elseif value_type == 'table' then
    return mw.text.jsonDecode( value )
  elseif not value_type then
    return
  else
    error( i18n.error.unsupported_type )
  end
end

--- Write a value to the cache.
-- @param key (string): The key under which the value will be stored.
-- @param value (string/number/bool/table/nil): The value to store.
-- @return (string/number/bool/table/nil): The value.
function h.write( key, value )
  local processed_value, value_type = h.preprocess( value )
  vardefine( key, processed_value )
  vardefine( key .. '__type', value_type )
  return value
end

--- Read a value from the cache.
-- @param key (string): The key from which to retrieve the value.
-- @return (string/number/bool/table/nil): The original value.
function h.read( key )
  local value = var( key )
  local value_type = var( key .. '__type' )

  return h.process( value, value_type )
end

--------------------------------------------------------------------------------
-- Functions
--------------------------------------------------------------------------------

local p = {}

function p.auto( func, args, prefix )
  libraryUtil.checkType( 'auto', 1, func, 'function' )
  libraryUtil.checkType( 'auto', 2, args, 'table' )
  libraryUtil.checkType( 'auto', 3, prefix, 'string', true )

  local key = h.make_key( args, prefix )
  local cached = h.read( key )
  if cached then
    return cached
  else
    mw.log( i18n.log.caching )
    return h.write( key, func( args ) )
  end
end

function p.set( args, value, prefix )
  libraryUtil.checkType( 'set', 1, args, 'table' )
  libraryUtil.checkTypeMulti( 'set', 2, value, { 'boolean', 'string', 'number', 'table' } )
  libraryUtil.checkType( 'set', 3, prefix, 'string', true )

  local key = h.make_key( args, prefix )

  return h.write( key, value )
end

function p.get( args, prefix )
  libraryUtil.checkType( 'get', 2, args, 'table' )
  libraryUtil.checkType( 'get', 3, prefix, 'string', true )

  local key = h.make_key( args, prefix )

  return h.read( key )
end

function p.key( args, prefix )
  return h.make_key( args, prefix )
end

--------------------------------------------------------------------------------
-- Return
--------------------------------------------------------------------------------

return p