CWDG论坛-专业魔兽插件's Archiver

cosin0002 发表于 2007-8-19 10:00

Cache code for performance

Cache是什么?我想来看这个贴的应该都明白,我就不Copy & Paste了。
下面给出的代码可以帮助你管理Cache(当然是 wow addon lua 环境下)。

[quote]
代码中所有的 local 函数是内部实现,cache = {} 是对外接口
cache.create [color=Green]-- 创建Cache[/color]
cache.release [color=Green]-- 销毁Cache[/color]
cache.clear [color=Green]-- 清空Cache内容[/color]
cache.resize [color=Green]-- 调整Cache的大小[/color]
cache.get [color=Green]-- 从Cache获得数据[/color]
cache.set [color=Green]-- 设置Cache数据[/color]


[color=Green]-- Cache大小的预定义常量[/color]
CACHE_SIZE_ALL = -1 [color=Green]-- Cache 所有数据[/color]
CACHE_SIZE_NONE = 0 [color=Green]-- 所有数据均不Cache[/color]
CACHE_SIZE_DEF = 20 [color=Green]-- 缺省的 Cache 大小[/color]

[color=Green]-- 当Cache丢弃的数据达同时到以下的两个标准时,将进行重新索引,以节省空间[/color]
[color=Green]-- 1 当Cache丢弃的数据与有效数据之间的比例大于该Cache定义的[color=Blue]数据丢弃率(Drop Rate)[/color][/color]
[color=Green]-- 2 当Cache丢弃的数据量大于该Cache定义的[color=Blue]最少丢弃量(Drop Count Min)[/color][/color]
[color=Green]-- 与重新索引相关的缺省常量[/color]
CACHE_REINDEX_DROPRATE_DEF = 0.5 [color=Green]-- Cache丢弃的数据与有效数据比例[/color]
CACHE_REINDEX_DROPCOUNT_MIN = 50 [color=Green]-- Cache丢弃的数据量[/color]
[/quote]

[language=lua]CACHE_SIZE_ALL = -1
CACHE_SIZE_NONE = 0
CACHE_SIZE_DEF = 20

CACHE_REINDEX_DROPRATE_DEF = 0.5
CACHE_REINDEX_DROPCOUNT_MIN = 50

local map = {}

local function cache_free(ob)
        ob.dropCount = 0
        ob.startIndex = 1
        ob.map = {}
        ob.arr = {}
end

local function cache_reindex(ob, bForce)
        bForce = bForce or false
        local cSize = #ob.arr - ob.dropCount
        if bForce or (ob.dropCount >= ob.dropCountMin and #ob.arr >= ob.size * (1 + ob.dropRate)) then
                local arr = {}
                local key, data
                local j = 1
                for i = ob.startIndex, #ob.arr do
                        key = ob.arr[ i ]
                        if type(key) == "string" then
                                data = ob.map[key]
                                arr[j] = key
                                data.index = j
                                j = j + 1
                        end
                end
                ob.arr = arr
                ob.dropCount = 0
                ob.startIndex = 1
        end
end

local function cache_adjust (ob, key)
        local data = ob.map[key]
        local iLen = #ob.arr
        if data.index < iLen then
                ob.arr[data.index] = 0
                ob.arr[iLen + 1] = key
                data.index = iLen + 1
                ob.dropCount = ob.dropCount + 1
                cache_reindex(ob)
        end
end

local function cache_keepSize(ob)
        if ob.size == CACHE_SIZE_ALL then
                return
        end
        local iLen = #ob.arr
        local dc = ob.dropCount
        local cSize = iLen - dc
        local key
        while cSize > ob.size do
                for i = ob.startIndex, iLen do
                        ob.startIndex = ob.startIndex + 1
                        key = ob.arr[ i ]
                        if type(key) == "string" then
                                ob.map[key] = nil
                                ob.arr[ i ] = 0
                                ob.dropCount = ob.dropCount + 1
                                ob.cSize = ob.cSize - 1
                                break
                        end
                end
                if dc == ob.dropCount then
                        --[[ "Error : keep size of Cache ["..name.."] failed!" ]]
                        break
                end
        end
        if dc < ob.dropCount then
                cache_reindex(ob)
        end
end

local function cache_resize(ob, size)
        if ob.size == size then
                return true
        elseif size == CACHE_SIZE_ALL then
                ob.size = size
        elseif size == CACHE_SIZE_NONE then
                cache_free(ob)
                ob.size = size
        elseif size > 0 then
                if ob.size > size then
                        ob.size = size
                        cache_keepSize(ob)
                else
                        ob.size = size
                end
        else
                --[[ "Error : Cache ["..name.."] size must > 0!" ]]
        end
end

local function cache_getValue(ob, key)
        local data = ob.map[key]
        if data == nil then
                return nil
        end
        cache_adjust(ob, key)
        return data.value
end

local function cache_setValue(ob, key, value)
        local data = ob.map[key]
        if data == nil then
                data = {value = value, index = #ob.arr + 1}
                ob.map[key] = data
                ob.arr[data.index] = key
                cache_keepSize(ob)
        else
                data.value = value
                cache_adjust(ob, key)
        end
        return true
end

cache = {}

cache.create = function(name, type, size, droprate, dropcountmin)
        local c = map[name]
        if c == nil then
                c = {
                        type = type or CACHE_TYPE_KEEP,
                        size = size or CACHE_SIZE_DEF,
                        dropRate = droprate or CACHE_REINDEX_DROPRATE_DEF,
                        dropCountMin = dropcountmin or CACHE_REINDEX_DROPCOUNT_MIN,
                        dropCount = 0,
                        startIndex = 1,
                        map = {},
                        arr = {},
                }
                map[name] = c
        else
                --[[ "Warning : Cache ["..name.."] already exist!" ]]
        end
        return c
end

cache.release = function(name)
        local c = map[name]
        if c ~= nil then
                cache.clear(c, true)
                map[name] = nil
                c = nil
        end
end

cache.clear = function(name, bForce)
        bForce = bForce or false
        local c = map[name]
        if c ~= nil then
                if bForce or c.type ~= CACHE_TYPE_KEEP then
                        cache_free(c)
                end
        end
end

cache.resize = function(name, size)
        local c = map[name]
        if c == nil then
                --[[ "Warning : Cache ["..name.."] does not exist!" ]]
                return nil
        end
        return cache_resize(c, size)
end

cache.get = function(name, key)
        local c = map[name]
        if c == nil then
                -- [[ "Warning : Cache ["..name.."] does not exist!" ]]
                return nil
        end
        if c.size == CACHE_SIZE_NONE then
                return nil
        end
        return cache_getValue(c, key)
end

cache.set = function(name, key, value)
        local c = map[name]
        if c == nil then
                --[[ "Warning : Cache ["..name.."] does not exist!" ]]
                return nil
        end
        if c.size == CACHE_SIZE_NONE then
                return false
        end
        return cache_setValue(c, key, value)
end[/language][/color][/color]

simonw 发表于 2007-8-25 19:46

来段简要说明啊

月色狼影 发表于 2007-8-26 22:53

fr你想表达什么意思?

cosin0002 发表于 2007-8-27 09:29

[quote]原帖由 [i]月色狼影[/i] 于 2007-8-26 22:53 发表 [url=http://bbs.cwowaddon.com/redirect.php?goto=findpost&pid=15351&ptid=1455][img]http://bbs.cwowaddon.com/images/common/back.gif[/img][/url]
fr你想表达什么意思? [/quote]
。。。这个。。。没啥意思呀
就是Cache的管理代码而已。。。

cosin0002 发表于 2007-8-27 09:42

[quote]原帖由 [i]simonw[/i] 于 2007-8-25 19:46 发表 [url=http://bbs.cwowaddon.com/redirect.php?goto=findpost&pid=15225&ptid=1455][img]http://bbs.cwowaddon.com/images/common/back.gif[/img][/url]
来段简要说明啊 [/quote]
说明补了。。。

PS:其实我觉得没啥好写,这个代码不复杂

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.